csrf xss cookie (pwn.college)
Summary
We chain CSRF -> reflected XSS -> cookie theft. The victim bot always visits http://hacker.localhost:1337/, so we host an attacker page at / that redirects the victim to /ephemeral?msg=... with a <script> payload. That payload runs on http://challenge.localhost, reads document.cookie (not HttpOnly), and exfiltrates the admin cookie back to our server. We then replay the cookie to view the admin post (the flag).
Start
The challenge ships two binaries:
./serverruns the Flask app athttp://challenge.localhost./victimlaunches the headless admin bot
Run the server:
cd /challenge
./server &Understand the goal from server code
Key facts from server:
Admin credentials are derived from the flag:
db.execute("""CREATE TABLE users AS SELECT "admin" AS username, ? as password""", [flag[-20:]])Successful login sets the cookie:
response.set_cookie('auth', username+"|"+password)Admin's flag post is already in the posts table:
If we can steal the admin cookie (auth=admin|<last_20_of_flag>), we can request / as admin and see the flag.
The reflected XSS sink
/ephemeral reflects a GET parameter directly into HTML:
That means:
is a reflected XSS sink. just like the previous challenge
Two-layer JavaScript plan
We need two scripts:
Outer JS on
http://hacker.localhost:1337/-> constructs the payload and navigates the victim to/ephemeral?msg=....Inner JS inside the reflected XSS -> runs in
challenge.localhost, stealsdocument.cookie, and sends it back.
Because </script> inside a <script> tag breaks parsing, we split the closing tag:
We also URL-encode the payload to avoid special characters (+, <, >, spaces) breaking the URL.
Final attacker page
This page redirects the victim to the XSS URL:
Save it as /tmp/index.html so it is served at http://hacker.localhost:1337/:
Host it:
Trigger the victim
Expected server logs:
The /leak 404 is fine; the request still appears in the log.
Extract the cookie and log in
From the http.server log, take the leaked cookie (URL-encoded):
Decode the cookie using CyberChef or any URL decoding website
Then reuse it:
You'll see the admin post (the flag).i'
Timeline view
Last updated
Was this helpful?