neven@dimitri-dev:~$
cd ../hacknite-2021

$cat e-shop-union.mdWebHacknite 2.0

e-Shop "Union"

The registration form is open to SQL injection, and a UNION lets a second query ride along, pulling the admin's row out of the database.

  • #sql-injection
  • #union
  • #password-hash

$man e-shop-union

What this one teaches:

  • What a SQL UNION does, and how injection uses it to return data from another table.
  • Matching a UNION to the number and type of columns the original query returns.
  • Cracking a leaked password hash to log in as the account you exposed.

$hint --one-at-a-time

Stuck? Open one hint, then go back and try again before reading the next.

Hint 1 of 2show

The title is the hint, as usual on this CTF. Which SQL keyword is it pointing at?

Hint 2 of 2show

Try the injection on the field you control at registration, and make your extra query return the admin's row.

Full solution below. Spoilers ahead.

Task description

A local shop built a site where customers track their purchase history. You register, and when you shop in person you give your username so your history updates.

The original was in Croatian; this is my translation.

The title is the hint

This CTF hid most of its hints in task titles, and here the word is UNION. In SQL, UNION joins the results of two queries into one list, as long as both return the same number of columns. Attackers use it in an injection to bolt a second query onto the first, so a page that was only meant to show your own data returns rows from another table instead.

So we looked for a field where our input reaches a query. The registration form worked. We registered with this as the username:

writeUp' UNION SELECT username, role, password FROM users WHERE role='admin'; -- '

The opening quote ends the value the site expected, then our UNION SELECT adds a second query that pulls the username, role and password of the admin account out of the users table. The three columns match what the original query returns, so the database accepts the combined result. The -- comments out the rest of the original line.

Logging in as admin

The injected row came back and gave us the admin’s password as a hash. As in SELECT error FROM info, we ran it through CrackStation, which turned it back into a password: zlocinikazna (“zlocin i kazna” is Crime and Punishment in Croatian).

We logged in as admin with that password, and to our pleasant surprise it worked, showing the flag. The fix is the same one that defeats every injection task here: a parameterised query, so the username you register with stays a username and can never carry its own UNION SELECT.

$cat flag.txt revealCTF2021[283295419225]

Written by Neven Marić. This writeup was written with the help of Claude Code (Anthropic).