This is a sample writeup shipped as a template for the new CTF Writeups section. Swap it out (or delete it) once you’ve got real competitions to publish — it shows the front matter fields the layout expects and the general structure a writeup can follow.
Challenge summary
We’re given a web app with a login form and a “forgot password” flow. The goal is to recover the flag from the admin’s private notes page.
Recon
Poking at the login form, a standard ' OR 1=1 -- on the username field doesn’t do anything —
looks parameterized. The password-reset flow, though, echoes the submitted email back into a
confirmation message without escaping it, and that value later gets used in a lookup query on the
admin’s notes page.
POST /reset-password
email=test@example.com' UNION SELECT username, password FROM users --
Exploitation
Chaining the reset flow with a UNION-based injection into the lookup query lets us pull the admin row directly:
' UNION SELECT flag, NULL FROM secrets-- -
Dropping that into the reset endpoint and reading the confirmation page back gives us the flag directly.
Flag
HTB{s3c0nd_0rd3r_sqli_ftw}
Takeaways
Second-order injection is easy to miss because the vulnerable sink is nowhere near the input — always trace where user-controlled strings get reused downstream, not just where they’re first accepted.