Joel Eriksson
Vulnerability researcher, exploit developer and reverse-engineer. 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

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
Remote debugging using
[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

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