This weekend, I participated in the curiously named Bugs Bunny CTF (www.bugsbunnyctf.me). Unfortunately, due to very poor record-keeping (and general incompetence in solving some more interesting challenges) on my part, I am only able to present a few limited writeups.
rev75 was presented as a 64-bit Linux binary file, which you can download here. At first glance, this is a stock standard reverse engineering challenge, with a simple string comparison leading to a flag. However, trying this reveals that the challenge goes further:
Going back into IDA Pro, we can notice a multitude of functions which seem to do something with base64-encoded blocks, as well as two functions (“encrypt” and “decrypt”):
Calling these functions in gdb doesn’t seem to do anything, so we go for our next best option – we extract the base64 blobs (in order they are presented in the binary) join them together and try to make sense of the output.
The output is presented as a valid PNG file: unfortunately, it doesn’t seem to render, and strings doesn’t show anything obvious. We then head for our trusty 010 editor PNG template:
010 editor quickly reveals that the last IDAT chunk stretches past the end of the file. Scrolling to the end of the file reveals an IEND chunk, and a quick ctrl-F doesn’t show any more IDAT chunks – my next step is to manually tweak the size of the last chunk. A little bit of math later, and we arrive at a size of 6039, which ends the IDAT where the IEND begins, revealing a broken image, which is good enough to scavenge the flag from:
The SimplePHP challenge was presented as a website, with accompanying source code, which you can download here.
This challenge introduced me to the PHP concept of a “variable variable”. That is:
$a = 1; $b = "a"; $$b = 2 $a == 2
My initial attempt was to set the $flag variable to something I controlled, then send a “flag” POST variable – this got me to the “200” response, but didn’t give me the flag. Thinking a bit further, I noted the _200 and _403 variables – what if I could use one of these to “store” the $flag variable, then trigger a controlled response?
The “pwn100” challenge was presented as a Linux binary, which you can download here.
After some initial analysis in IDA Pro and some trickery in gdb, we know that this is a simple stack-based overflow, with the vulnerable function in plain sight:
With a little trial and error, we’re able to control EIP. Unfortunately, we don’t know where our vulnerable buffer is on the target – but a little bit of inspection in gdb reveals that the location of our buffer is in eax:
A quick detour into Ropper (I’m sure PEDA also has an option for finding it), and we identify a clean control transfer to eax at 0x08048386. We set this as our return address, modify some standard /bin/sh shellcode to clean up the stack (so it can use the “push” instruction), and we’re in business:
You can download the completed exploit here.
I’d like to thank the organisers of Bugs Bunny CTF for an enjoyable event – a shame that the timing was such that fully half the challenges were added while I could not play, due to the thrice-accursed misfortune of having to wake up for a 9am meeting on Monday. At the time of writing, these challenges appear to still be online, so I will attempt to devote some time this week to completing more of these challenges.
See you all in SHA2017 CTF next weekend.