Writeup – Basic, ByteMe, Patch (AusCERT 2016)

For a few brief hours last night and throughout today, I participated in the AusCERT 2016  CTF as a guest of Team Money Shot.

BOOM MONEY SHOT

primarily for lulz

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):

wtb zalgo next time

wtb zalgo next time

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:

the smell of ctf trickery...

the smell of ctf trickery…

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:

dem pointz

dem pointz

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”):

glorious!

glorious!

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:

jmp near ptr fuckyou

jmp near ptr fuckyou

 

A bit of visual inspection in text mode quickly showed these jumps to be “fake”:

tricky tricky

tricky tricky

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:

fix fix

now with many% more nops

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:

py py

dem python sk1llz

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.

About Norman

Sometimes, I write code. Occasionally, it even works.
This entry was posted in Computers, Jesting and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s