Маскарад (Masquerade)
Маскарад (Masquerade)
Platform: bug-makers | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-05-25 | Status: Solved Techniques: express_session_state_tracking, multi_part_flag_collection, session_cookie_reuse_with_different_user_agents
Summary
Task: Express.js app splits flag into 5 parts, each revealed by a new unique User-Agent within the same session. Solution: Reuse the connect.sid session cookie while changing the User-Agent header across 5 requests to collect all flag parts.
Маскарад (Masquerade) — bug-makers
Description
Очень хочется получить весть флаг целиком, но как бы я ни пытался, получаю только первую его часть, я даже пробовал открывать адрес через разные браузеры - результат один. Попробуй, может у тебя получится?
English summary: The author wants the full flag but only gets the first part. Even trying different browsers gives the same result — always just part #1. The challenge is to figure out how to get all parts.
Analysis
The target is an Express.js application at https://masquerade.t1.bug-makers.ru/.
Initial reconnaissance:
x-powered-by: Expressheader reveals the framework- Session cookie
connect.sidindicates express-session with server-side storage - Only two endpoints exist:
/(GET) and/health - Sending an empty User-Agent returns
"Oops! Incorrect headers!"
Key observation: The challenge description contains a critical hint — "I tried different browsers - same result." Each browser creates its own independent session (new connect.sid cookie), so the server treats each browser as a fresh visitor and always returns part #1.
The mechanism: The server maintains a list of seen User-Agent strings per session. Each new unique User-Agent presented within the same session advances the counter and reveals the next flag part. The flag is split into 5 parts.
Why different browsers fail: Different browsers send different User-Agents, but they also create separate sessions. The server sees each as a brand-new visitor with 0 unique agents seen, so it always returns part #1.
The solution: Change the User-Agent header while reusing the same session cookie (connect.sid).
Solution
Use curl to make 5 requests with different User-Agent strings while preserving the session cookie:
bash read-only • copy allowed#!/bin/bash # Solve script for Masquerade - collect all 5 flag parts URL="https://masquerade.t1.bug-makers.ru/" COOKIE_JAR="cookies.txt" # Request 1: establish session, get part #1 echo "=== Part 1 ===" curl -s -c "$COOKIE_JAR" "$URL" -A "Agent1" # Requests 2-5: reuse session cookie with different User-Agents for i in 2 3 4 5; do echo -e "\n=== Part $i ===" curl -s -b "$COOKIE_JAR" "$URL" -A "Agent$i" done
Output:
| Request | User-Agent | Response |
|---|---|---|
| 1 | Agent1 | You have flag part #1 BugCTF{ |
| 2 | Agent2 | You have flag part #2 h0w_m4n |
| 3 | Agent3 | You have flag part #3 y_4gen7s |
| 4 | Agent4 | You have flag part #4 _d0_y0u |
| 5 | Agent5 | You have flag part #5 _hav37} |
After all 5 parts are collected, any further request returns: You already have whole flag!
Concatenating all parts: BugCTF{ + h0w_m4n + y_4gen7s + _d0_y0u + _hav37} = BugCTF{REDACTED}
What didn't work
- Different browsers — each creates a new session, always returns part #1
- Various HTTP headers (Accept, Accept-Language, X-Forwarded-For, etc.) — no effect on flag parts
- Query parameters (part, id, mask, flag, page) — no effect
- HTTP method override — no effect
- Path enumeration with ffuf — only
/and/healthfound