Tuesday, May 6, 2014

Of Binary Bombs (part 1)

I was recently turned on to radare2 (http://www.radare.org/y/) and, in an attempt to use-it-to-learn-it, I am going to try and solve the sample binary bomb provided as an example lab for the CMU computer systems course. I'm aiming to make my next few posts an account of trying to solve that puzzle (and learn this new tool).

Caveat lector: I've basically no experience with binary tools and assembly language so this will be deliberate and likely full of amateur mistakes.


I expect to be able to analyze this as the program would be run so I'm staring at the main entry point and assuming that there is nothing tricky happening prior to that. Load up radare2 and enter visual mode (press 'V' at the command prompt) then press 'p' until the view is one that resembles assembly instructions. Once there search for the main entry point (at the command prompt: s main). That will bring you to a screen that looks similar to:


First thing to happen in this program is to check the arguments to main to determine whether to read from stdin or from a file. This progresses from the function prologue: saving the base pointer (ebp); copy the stack pointer (esp); and reserve 20 bytes for local use (sub esp, 0x14). The program then continues to look at the value of argc and acts accordingly eventually assigning the input stream (stdin or otherwise) to sym.infile.

Without error, control flow reaches address 0x08048a30 (in my version) which is a call to sym.initialize_bomb. Radare2 allows you to set marks much like you would in vim so if you are familiar with that, set a mark here with ma and hit enter at this address to follow to sym.initialize_bomb. Alternatively, at the command prompt, search for the function symbol with s sym.initialize_bomb. In either case you should see the following:


Here, the program simply sets up to handle SIGINT with the function sig_handler and returns. If you are using marks you can return to the previous address with 'a.

The program continues with a couple of generic prompts, proceeds to read a line of input (which does some internal bookkeeping), and jumps to phase 1 (sys.phase_1). Place a local mark (ma) and jump to the first phase code: we are now ready to start the actual process of solving Dr. Evil's nasty riddle.


Phase 1 is intended to be easy. The first line of input provided to the program is copied to eax, and then two arguments are set up: a global string (at address 0x080497c0) and eax. These arguments are sent to strings_not_equal which returns 0 if the two arguments are the same length and contain the same strings. The check test eax, eax (true when eax is 0) avoids exploding the bomb so we want eax (the first input string) to be the same as whatever is in 0x080497c0.

The radare2 command to print memory as a string is ps. Entering command mode (:) and typing ps @ 0x080497c0 yields: 'Public speaking is very easy.' (the period is significant). Entering that provides:


Next, I'll tackle phase 2.

No comments :

Post a Comment