For a few brief hours last night and throughout today, I participated in the AusCERT 2016 CTF as a guest of Team Money Shot.
Throughout this challenge, I tackled problems in the reversing, pwn and web categories: I’ll write about three reversing ones here (I wasn’t able to solve PongMe, a GBA ROM reversing challenge, in the time allocated. wtb sk1llz pl0x).
Basic
The “Basic” challenge was a Windows executable. A quick inspection in IDA showed this executable did a quick debug check, and then displayed a message box (without any user interaction):
A quick inspection of the program’s structure and it’s static strings revealed nothing of interest, except for a long hexadecimal string (“efe5…”).
From here, we quickly patch out the debug check, and breakpoint on MessageBoxW in WinDbg: we quickly realize that the MessageBox is displaying something we’ve seen already:
My first instinct was that this was some form of encoded flag (typically, xor, bit shift, add). A bit of manual checking reveals that the first two bytes xor cleanly to “fl” with a key of 137, so a quick Python script later, and the flag is ours:
ByteMe
This challenge was presented as a compiled Python “pyc” file. A quick Google led us to the “uncompyle2” utility, which quickly produced a clean Python source file.
At a glance, this seems simple enough: the “key” was produced via a rot13 followed by an xor against a known key, so we can simply xor against the known key (again) and perform another rot13 for the original plaintext.
Our first attempt, confusingly, led to failure:
def encodeXor(pwd): key = 'Insanity: doing the same thing over and over again and expecting different results.' * 2 result = [] i = 5 for x in pwd: result.append(ord(x) + i ^ ord(key[i]) % 255) i = i + 1 % len(key) return result def decodeXor(pwd): key = 'Insanity: doing the same thing over and over again and expecting different results.' * 2 result = [] i = 5 for x in pwd: result.append(x - i ^ ord(key[i]) % 255) i = i + 1 % len(key) return result
A bit of Google, and we realized that Python order of operations had confounded us here: we actually needed to swap the operations around a bit to reverse the xor correctly:
def decodeXor(pwd):
key = 'Insanity: doing the same thing over and over again and expecting different results.' * 2
result = ""
i = 5
for x in pwd:
result += chr((x ^ ord(key[i])) - i % 255)
i = i + 1 % len(key)
return result
Running the revised decode script against the original key soon us the flag (the long bit right after “eat my balls”):
Patch
The “patch” challenge was slightly more complicated: initially, this looked to be a normal ELF executable, but a quick inspection in main() in IDA revealed some oddities:
A bit of visual inspection in text mode quickly showed these jumps to be “fake”:
There weren’t too many of these, and I’m sure there’s a better way to do it with IDA Scripting (I really need to read the IDA Pro Book sometime), but in the interests of 2:30am I opened a hex editor and manually patched these out.
A quick try at running the patched binary reveals a few more invalid instructions hidden in the code, which a quick search-and-replace in the hex editor takes care of (IIRC: nopping out the 89 1D 01 00 00 00). This reveals a much nicer, graph-friendly executable:
From here, analysis shows a super simple executable structure:
- Some code at 0x080485D0 copies a static key into a stack variable
- A function call at 0x0804867F xor’s this key with “cakecakecakecakecak”
- A function call at 0x0804869A compares this against the user’s key.
Some quick Python trickery later, and the flag is ours:
Thanks to the conference organisers, and the Shearwater crew, for putting on a fantastic CTF – while I did not attend AusCERT itself (probably would’ve choked on all the vendor bong smoke from the sounds of things), I enjoyed the CTF event and had lots of fun (despite a few mishaps around things like ASLR being magically turned on :P).
As a special note – it’s extremely heartwarming to see the Sectalks Brisbane and Sectalks Melbourne teams also participating: in today’s Australian infosec industry, our day jobs are typically filled with everything except actual technical content (especially if you work in something like pentesting), so the more people we get interested in this, the better.