Category: Web Exploitation
Difficulty: Medium
Points: 100
Description
The server refuses to serve the flag unless the request looks exactly like it came from a very specific, trusted client. Each time a condition fails, the server reveals the next requirement.
Overview
- The server checks 7 HTTP request headers in sequence.
- Each check must pass before the next one is revealed.
- All conditions must be satisfied simultaneously in the final request.
Solution
Step 1: Set the User-Agent
- The default Python
requestsUser-Agent is rejected immediately. - The server requires
User-Agent: PicoBrowser.
headers = {"User-Agent": "PicoBrowser"}
Step 2: Add a Referer
- The server then requires the request to appear to originate from the site itself.
- Setting
Refererto the site URL satisfies this.
headers["Referer"] = "http://mercury.picoctf.net:38322"
Step 3: Spoof the Date
- The server checks that the request carries a
Dateheader from 2018. - Python’s
datetimeformats the date in the RFC 1123 format the header requires.
headers["Date"] = datetime(2018, 1, 1).strftime("%a, %d %b %Y %H:%M:%S GMT")
Step 4: Set Do Not Track
- The server requires
DNT: 1, indicating the client has opted out of tracking. - DNT (Do Not Track) is a voluntary HTTP header; here the server requires it as an identity signal.
headers["DNT"] = "1"
Step 5: Spoof the IP Address
- The server checks
X-Forwarded-Forand requires a Swedish IP address. X-Forwarded-Foris a proxy header that conveys the originating client IP.- The server uses this to gate access by apparent geographic location.
headers["X-Forwarded-For"] = "192.44.242.19"
Step 6: Set the Language
- The final check requires
Accept-Language: sv(Swedish locale).
headers["Accept-Language"] = "sv"
Step 7: Send the Final Request
- All six header conditions are combined into one request.
- The response now contains the flag.
r = requests.get(url, headers=headers)
Flag
picoCTF{http_h34d3rs_v3ry_c0Ol_much_w0w_b22d773c}