Joel Eriksson
CEO/Founder of ClevCode. Vulnerability researcher, exploit developer and reverse-engineer. Previous CTO and co-founder of Bitsec, which was acquired by Nixu, and Cycura which was acquired by WELL Technologies. Have spoken at BlackHat, DefCon and the RSA conference. CTF player. Puzzle solver (Cicada 3301, Boxen)

PlaidCTF 2011 – 04 – Here, There Be Dragons – 300 pts

This is my writeup for the fourth challenge in the PlaidCTF 2011 competition. The information for the challenge was:

“After breaking into the AED network, we stumbled across a router with custom software loaded. Intrigued by this discovery, we sent in a team and extracted the software.
Reverse engineer this strange code, and report back.”

The first step is obviously to determine the format of the file, which I simply used the “file” command for.

je@isis:~/ctf/PlaidCTF-2011/04-Here_There_Be_Dragons$ file f20b029ce96f0278322c0629b1265e1abd0e72cd.bin
f20b029ce96f0278322c0629b1265e1abd0e72cd.bin: ELF 32-bit MSB executable, MIPS, MIPS32 version 1 (SYSV), statically linked, stripped

The file is a MIPS executable, and due to the following message within it it seems likely that it corresponds to a Cisco 3725 router image:

“Welcome to PPP IOS for C3725!”

Although this challenge certainly could be solved by pure static reversing, it will save a lot of time if we could actually run the code. Since I didn’t have a Cisco router laying around for the task, I used an emulator called Dynamips.

Dynamips has no builtin debugging facilities, but thanks to Sebastian Muñis and Alfredo Ortega of Groundwork Technologies there is a patch available that implements a GDB stub to allow for debugging with GDB, IDA Pro and other debuggers with support for the GDB remote protocol.

For the initial analysis of the binary I used IDA Pro, and could quickly pinpoint the code of interest. Using a combination of static reversing with IDA and debugging with GDB and Dynamips I could determine that the password is actually a numeric PIN, and once the correct PIN is entered, the password required to solve the challenge is decrypted and written to the terminal.

Note that we need a GDB with MIPS support to be able to use GDB for debugging. I used one compiler with mips-idt-elf as its target.

Debugging was extremely slow due to the fact that breakpoints did not seem to work. When a breakpoint was reached I got the following message in the emulator:

[[[ Virtual Breakpoint reached at PC=ADDR RA=ADDR]]]
...

It didn’t stop executing though.. So, I used GDB scripting to single-step to the instruction I wanted to break at instead:

while $pc != ADDR
 si
end

To not have to step through the entire boot process I let it execute until the password prompt before breaking out into the debugger with ^C.

Using this technique I simply let it execute until the address where the PIN entered is compared with the expected PIN and extracted the correct PIN from there. Then I could boot up the image again, enter the correct PIN and get the password.

After solving the challenge I came up with a much faster technique, by simply patching the code where I want to break at with an eternal loop. Example below:

je@isis:~/ctf/PlaidCTF-2011/04-Here_There_Be_Dragons$ mips-idt-elf-gdb -q f20b029ce96f0278322c0629b1265e1abd0e72cd.bin
(no debugging symbols found)
(gdb) target remote 127.0.0.1:1234
Remote debugging using 127.0.0.1:1234
[New Thread 1]
0xbfc00000 in ?? ()
(gdb) set *0x800085e0 = 0x1000ffff
(gdb) x/i 0x800085e0
0x800085e0:	beq	v1,v0,0x800085f0
0x800085e4:	nop
(gdb) set *0x800085e0 = 0x1000ffff
(gdb) x/i 0x800085e0
0x800085e0:	b	0x800085e0
0x800085e4:	nop
(gdb) c
Continuing.

I now switch to the console where I’m running the emulator, and enter 12345 as my PIN:

Launching IOS image at 0x80008000...
Welcome to PPP IOS for C3725!
Secret: 12345

The emulator will now hang on my eternal loop, so I switch back to the debugger and press ^C:

Program received signal SIGTRAP, Trace/breakpoint trap.
0x800085d4 in ?? ()
(gdb) p/d $v0
$1 = 134217728
(gdb) p/d $v1
$2 = 12345

The v1 register contains the PIN I entered (12345), and v0 the expected one (134217728 = 0x8000000). Now I only need to enter the correct PIN to get the password.

je@isis:~/ctf/PlaidCTF-2011/04-Here_There_Be_Dragons$ dynamips -P 3725 f20b029ce96f0278322c0629b1265e1abd0e72cd.bin
Cisco Router Simulation Platform (version 0.2.8-RC2-amd64)
Copyright (c) 2005-2007 Christophe Fillot.
Build date: Apr 23 2011 10:07:23

IOS image file: f20b029ce96f0278322c0629b1265e1abd0e72cd.bin

ILT: loaded table "mips64j" from cache.
ILT: loaded table "mips64e" from cache.
ILT: loaded table "ppc32j" from cache.
ILT: loaded table "ppc32e" from cache.
CPU0: carved JIT exec zone of 64 Mb into 2048 pages of 32 Kb.
NVRAM is empty, setting config register to 0x2142
C3725 instance 'default' (id 0):
  VM Status  : 0
  RAM size   : 128 Mb
  NVRAM size : 128 Kb
  IOS image  : f20b029ce96f0278322c0629b1265e1abd0e72cd.bin

Loading ELF file 'f20b029ce96f0278322c0629b1265e1abd0e72cd.bin'...
ELF entry point: 0x80008000

C3725 'default': starting simulation (CPU0 PC=0xffffffffbfc00000), JIT enabled.
ROMMON emulation microcode.

Launching IOS image at 0x80008000...
Welcome to PPP IOS for C3725!
Secret: 134217728
IsntCiscoGreat?