2024-10-14
Huntress CTF 2024: warmup write-ups
A few of the challenges I solved at the Huntress CTF 2024. None of these are hard, but each has a clean trick worth remembering.
Matryoshka QR
The challenge hands you a QR code. Scan it and you don't get a flag — you get the
bytes of a PNG (the \x89PNG header gives it away), which is itself another QR
code. Save the bytes, open the image, scan the smaller code inside for the flag.


You can do the extraction by hand, but Python makes it tidy:
from PIL import Image
import io
inner_data = b"\x89PNG\r\n\x1a\n..." # the bytes decoded from the outer QR
inner_image = Image.open(io.BytesIO(inner_data))
inner_image.save('inner_qrcode.png')Cattle
The attached file is a wall of ms and os. Searched around and it turned out
to be COW, an esoteric language whose entire
instruction set is variations on "moo." An
online COW interpreter runs it and prints
the flag.

Whamazon
A little shop where the flag costs $10,000,000,000 and you start with $50. Easy to overthink.

The store multiplies quantity by unit price and subtracts that from your balance — but it never checks that the quantity is positive.

Buy a negative number of something and the subtraction becomes an addition. Your balance balloons.

Now the flag is affordable, and it's waiting in your inventory.

Finder's Fee
SSH in and user can't read finder's home directory.

But /bin links to /usr/bin, and there the find binary has its
SGID bit set
(rwxr-sr-x root finder) — so find runs with the finder group's permissions.

find will happily list a directory you couldn't otherwise read:

Its -exec flag then runs a command per result:
find /home/finder/ -name flag.txt -exec cat {} \;
Any SGID/SUID binary that can read files or spawn processes is a
privilege-escalation primitive — find is one of the friendliest.