Monday, September 23, 2013

CSAW CTF Quals 2013 - GameMan (exploitation 400)

Another CSAW CTF 2013 Quals exploitation task - this time for 400 points (there were two exp400 tasks, this one is the one added Saturday evening/night). It was solved by 26 teams (at the moment of writing these words; still 1h of CTF left), including ours, which is quite surprising since this task turned out to be really simple. On behalf of Dragon Sector it was worked on and solved by myself (gynvael) and mak.

The task description task was quite brief:

nc 1025 < hello_world.gbc

The extension - .gbc - tells about a GameBoy Cartridge, so we expected some funky Z80 hacking. But it turned out we were wrong.

When you actually execute the above command, this is the what you get:

Insert Cartridge... 
Loaded: CSAW CTF 2013
Hello World!

So it actually prints out Hello World. However, to our surprise, launching it in a GameBoy emulator didn't give the same results - it actually either did nothing or crashed inside the emulator.

We started to analyze the Z80 code, but we weren't getting anywhere - the code just didn't make any sense. So we decided to fall back to looking at the hex editor, trying to figure out if we maybe got the CPU wrong. Take a look at the following screen shot:

The part marked in black is the code at entry point, obviously responsible for writing out "Hello World".

Notice anything funny about it? The "h" letter before 4-char pieces of the string? The "B8 01 00 00 00" sequence? The "CD 80" sequence? Yes ladies and gentlemen - this isn't Z80, it's x86/Linux!

So what actually happens, is that the network daemon on is fetching a GBC cartridge, checking the checksums, and executing the x86 code that is placed at the entry point. And what we need to do is to put a different shellcode there (a reverse shell for example), fix the GBC checksums, and send it to the daemon.

The hardest part here were the checksums. Well OK, I'm actually exaggerating - it was the easiest part, since the emulator I was using (bgb - it's pretty awesome btw) would show me proper CRC values in the debugger:

So all you had to do was:

  1. Paste your shellcode at 0x150.
  2. Run bgb, note the correct checksums and put them in the gbc file at correct offsets.
  3. Execute: nc 1025 < myexp.gbc
The result? It worked pretty well :)

1 comment: