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.

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:

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

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:

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

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

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.