【AIS3 Pre-Exam 2026 Writeup】Web - Mass-Rapid-Transit
http://chals1.ais3.org:10003/robots.txt
It returned:
User-agent: *
Disallow: /admin
So /admin was probably the interesting page. Direct access did not work.
curl -i http://chals1.ais3.org:10003/admin
The server redirected me back to /:
HTTP/1.1 302 Found
location: http://chals1.ais3.org:10003/
That told me the admin page existed, but normal visitors could not read it.
The protections here were web-side protections. CSRF was enabled, session cookies were needed, and /admin had an auth check. There was no ELF in this directory, so gdb and glibc/printf debugging were not useful for this target. I kept the work on HTTP behavior and page source.
Normal pages gave more surface:
/signup
/login
/profile
/lost_items
/map
/stations
/trains/<id>
The lost item pages were tempting. Some public records already contained XSS payloads from other players, like:
<img src="x" onerror="..." /> <svg onload="..."></svg>
On the detail page, the description was sanitized. Event handlers were removed, and payloads became harmless HTML such as:
<p><img src="x" /></p>
No script execution, no admin trigger. I did not continue with XSS.
After that I moved to authenticated features. First I registered a normal passenger account. Because Rails CSRF was enabled, I had to keep the cookie jar and reuse the token.
base='http://chals1.ais3.org:10003'
jar=$(mktemp)
html=$(mktemp)
curl -sS -c "$jar" "$base/signup" -o "$html"
tok=$(perl -0777 -ne 'print $1 if /name="authenticity_token" value="([^"]+)"/' "$html")

The profile update can use one extra parameter:

The server accepted it and redirected back to /profile:

