0 of 11 captured, by you - progress is tracked per browser, so your neighbours' finds do not show here. Flag values are set by a secret this server holds, so they survive a restart but cannot be read out of the source.
| # | Challenge | Goal, slide and hints | State |
|---|---|---|---|
01 | Scout the base Reconnaissance | The village links to every page it wants you to see. Find one it does not. Slide 4 - Step 2, Reconnaissance Burp: Target > Site map, and ask the server what it would rather you skipped. Hint 1Web servers keep a file that politely asks crawlers to stay away from certain paths. Hint 2Fetch /robots.txt. A Disallow line is a signpost, not a lock. Hint 3GET /dev/war-notes.txt | open |
02 | Saying too much Information disclosure | The dashboard shows your name and village. The server sends more than that. Slide 11 and 13 - read the reply, including every field Burp: Proxy > HTTP history. Open the JSON reply the dashboard fetched and read every field. Hint 1Load the dashboard while Burp is recording, then look at what the page fetched in the background. Hint 2The page renders 2 fields. The API returns more. Hint 3GET /api/me with your session cookie, and read the whole JSON body. | open |
03 | Peeking at other people's data IDOR / broken object level authorization | Read a supply order that does not belong to you. Slide 12 and 14 - the worked example Burp: Send your own order request to Repeater, change the number, press Send. Hint 1Open your own supply order and watch the URL. There is a number in it. Hint 2Your order is 1042. Numbers near it belong to your neighbours. Hint 3GET /api/orders/1043 | open |
04 | The hidden value the site added Mass assignment / hidden parameter tampering | Edit a profile that is not yours. Slide 10 - name=Asha&user_id=1042 Burp: Catch the profile-update POST. Read the whole body, not just the field you typed into. Hint 1Save your profile once and look at the request body in HTTP history. Hint 2You typed 2 values. The browser sent 3. Who decided the third? Hint 3POST /profile/update with user_id changed to the chief's id, 1041. | open |
05 | Doing things above your rank Broken access control | Reach the chief's treasury as an ordinary villager. Slide 12 - resend an admin request with a normal user's cookie Burp: The front-end hides the link. The server may not check who is asking. Hint 1The dashboard's JavaScript knows about more endpoints than the menu shows. Read /static/app.js. Hint 2A hidden menu item is a client-side control. Ask the server directly. Hint 3GET /api/treasury with your plain villager cookie. Do not tamper with the cookie first. | open |
06 | Rewriting your own ID badge Privilege escalation via unsigned session token | Blow the war horn, which only the chief may do. Slide 9 (Decoder) and slide 10 (the badge) Burp: Decoder: paste your session cookie, decode it, change one word, encode it back. Hint 1Your raid_session cookie is not random. It is scrambled text. Slide 9 names the tab that fixes that. Hint 2Decode it as Base64. It is JSON, and one field describes your rank. Hint 3Set "role":"chief", re-encode as Base64, replace the cookie, then GET /chief/warhorn. | open |
07 | Logout that does not log out Session management | Use a session the server was told to destroy. Slide 12 - log out in the browser, press Send again Burp: Park an authenticated request in Repeater, log out in the browser, then Send. Hint 1Send any authenticated request (say GET /api/me) to Repeater before you log out. Hint 2Log out in Burp's browser. Confirm the browser is really logged out. Hint 3Now press Send in Repeater. If the old cookie still works, the server never invalidated it. | open |
08 | Trusting what you type SQL injection | Make the store-room search read a table it was never meant to touch. Slide 13 - a database error appears Burp: Type a single quote into the search box and read the reply. 500 means 'I tripped'. Hint 1Search the store room for a single quote: ' . Read the error text carefully. Hint 2The query selects 3 columns. UNION needs the same number. SQLite lists its own tables in sqlite_master. Hint 3/storeroom?q=' UNION SELECT 1,flag,1 FROM relics-- | open |
09 | Your text became their code Stored cross-site scripting | First make the marker render bold. Then use that foothold to read a cookie the server marked as readable by scripts, and hand it to /collect?c= Slide 13 - type test"'<b>hi</b> into a form field Burp: Post the marker to the war-room board, then look at the page, then at HTTP history. Hint 1Post <b>hi</b> to the war-room board. If 'hi' renders bold, your text became HTML. Hint 2The village sets a cookie called village_seal and forgot the HttpOnly flag, so JavaScript can read it. Hint 3Post: <script>fetch('/collect?c='+document.cookie)</script> then read that request's own reply in HTTP history. /collect/log lists what the sink caught. | open |
10 | I tripped, and told you why Information disclosure via verbose errors | Crash an endpoint, read what it spills, then use it. Slide 11 - 500 is worth a closer look Burp: Endpoints that expect a number rarely enjoy being handed a word. Hint 1The orders endpoint takes a number. Give it letters instead. Hint 2The debug page dumps local variables, and one of them is the app's configuration. Hint 3Take SECRET_KEY out of the dump and GET /seal/verify?key=<that value> | open |
11 | No limit on guessing Missing rate limiting / brute force | Guess the watch-tower code. It is 2 digits, so there are exactly 100 of them. Slide 13 - about 20 times with Intruder, only if the rules allow Burp: Intruder, Sniper, payload type Numbers 0-99 with 2-digit min integer digits. Or load wordlists/gate-codes.txt. Hint 1Find the watch-tower gate and submit a wrong code once. Note the reply length. Hint 2Send that request to Intruder and mark the code value as the payload position. Hint 3100 requests, no lockout, no captcha, no delay. Sort by response length to spot the odd one out. | open |