This weekend, I participated in the RCTF event. This was a well-paced, yet challenging CTF – I enjoyed this event, and did not encounter any hosting issues aside from a few moments when one of the web challenges went down.
I learned a few useful things from this CTF, and I will present some writeups below. In an attempt to keep these posts to a somewhat manageable length, I will split these writeups into two posts.
Cats was presented as a miscellaneous challenge: the object was to find 15 commands which were equivalent to “cat”, when “food” was provided as argv (and we controlled the contents of the file “food”). A dockerfile was provided, through which we could run this challenge locally, without a Google ReCAPTCHA slowing us down.
The “check” simply ensured that “cat food” and “$input food” provided the same output and return value, so the obvious choice was to look for equivalents to cat. Initially, I browsed my CTF box, looking for promising binaries. I came up with an initial list:
tail, more, head.
“less” didn’t seem to work in the target environment, so I set this aside. I then changed the file to contain the contents “food”, so “ls” would work, and changed the file to a single line, so commands like “tac” and “shuf” would work. This allowed me a few more options:
For the remainder of the challenge, I started up a Docker environment in AWS, and listed /usr/bin, manually looking for binaries which may have not been present on my CTF box. I ended up with the following list:
Successfully giving me the flag:
This challenge was presented as a Linux executable, which you can download here. The challenge was to run the executable for the flag.
Initial analysis showed that there were a number of strange-looking imports, and structures indicating the presence of a Windows executable. I attempted to extract this Windows executable, and glued a DOS Stub from another functioning Windows executable in, to no effect:
The structures seemed somehow mangled, and the executable would not execute.
At this point, I stumbled across a PNG in the file, which showed the Wine Notepad icon, so I ran the original executable in Wine for shits and giggles:
No shit, it’s the fucking flag. Welp.
This challenge was presented as a Python file, which ran remotely. You can download this here.
Inspecting the file, we note that the application acts as an oracle: that is, you can use it to sign a pre-constructed string (via the “Order” functionality), and then test if any string has a valid signature (via the “Pay” functionality). If we are able to correctly sign a querystring with “product=Flag” and “price=<less than our monies>”, we win.
We note the signature is constructed via the following function:
sha256(key + message)
This is affected by a hash length extension attack, where we’re able to construct a new, valid signature which appends an arbitrary string to the old signature.
In this case, it doesn’t matter what we append, as long as it ends with “&product=Flag&price=4”.
The only restriction is that in order to conduct this attack, we must know the length of “key”: but fortunately, the program limits this to range(8,32), and we are able to brute force.
You can download the Python script I used for this here.
I struggled for a while to get Python to exit properly (that is, for pwntools.recvuntil() to handle cases where the target string is received, and where a flag is printed and there is no target string), so I ended up using Wireshark to grab the flag:
In the next post, I will discuss the babyre and numbers game challenges.