CMU Bomb Lab Phase 1
Table of Contents
CMU Bomb Lab reverse engineering
This repo contains the explanation on how I solved the CMU bomb lab on reverse engineering. I mostly used gdb
to analye and reverse engineer the code and I documented my thought process and explanations.
"The CMU bomb lab is a famous reverse engineering challenge from CMU.
This category's challenges will track your progress through the 32-bit x86 CMU bomb lab.
Welcome to my fiendish little bomb. You have 6 phases with which to blow yourself up. Have a nice day!"
If you wanna solve the challenge go to reversing.ctfd.io
Phase 1
Note: We are using AT&T assembly syntax
We have to defuse the phase 1 of the bomb
Using gdb
disassemble main
We have the following output:
0x08048a52 <+162>: call 0x80491fc <read_line>
0x08048a57 <+167>: add $0xfffffff4,%esp
0x08048a5a <+170>: push %eax
0x08048a5b <+171>: call 0x8048b20 <phase_1>
0x08048a60 <+176>: call 0x804952c <phase_defused>
On instruction 162
we see a call to read line corresponding to the first input the program expects when executing ./bomb
. After this, a function phase_1
is called.
disassembling the function phase_1
on gdb
gives us the following:
0x08048b20 <+0>: push %ebp
0x08048b21 <+1>: mov %esp,%ebp
0x08048b23 <+3>: sub $0x8,%esp
0x08048b26 <+6>: mov 0x8(%ebp),%eax
0x08048b29 <+9>: add $0xfffffff8,%esp
0x08048b2c <+12>: push $0x80497c0
0x08048b31 <+17>: push %eax
0x08048b32 <+18>: call 0x8049030 <strings_not_equal>
0x08048b37 <+23>: add $0x10,%esp
0x08048b3a <+26>: test %eax,%eax
0x08048b3c <+28>: je 0x8048b43 <phase_1+35>
0x08048b3e <+30>: call 0x80494fc <explode_bomb>
0x08048b43 <+35>: mov %ebp,%esp
0x08048b45 <+37>: pop %ebp
0x08048b46 <+38>: ret
We have the prologue on the first two instructions, then a subtraction to the esp
pointer indicating that we are allocating space on the stack.
Let's put a breakpoint after the prologue and stack allocation:
b *(phase_1+12)
Now let's run our program!
run
We see that we our program started and now is waiting for standard input on the console:
Starting program: /home/user/Documents/reversing.ctfd.io/phase1/bomb
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
>
So let's put a random string on the prompt!
> Hello world, this is a string!!!!
We now have reached our breakpoint that we set earlier:
Starting program: /home/user/Documents/reversing.ctfd.io/phase1/bomb
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Hello world, this is a string!!!
Breakpoint 1, 0x08048b2c in phase_1 ()
You can see where in the program you are by doing
lay next
We see the following:
B+>0x8048b2c <phase_1+12> push $0x80497c0
0x8048b31 <phase_1+17> push %eax
0x8048b32 <phase_1+18> call 0x8049030 <strings_not_equal>
0x8048b37 <phase_1+23> add $0x10,%esp
0x8048b3a <phase_1+26> test %eax,%eax
0x8048b3c <phase_1+28> je 0x8048b43 <phase_1+35>
0x8048b3e <phase_1+30> call 0x80494fc <explode_bomb>
0x8048b43 <phase_1+35> mov %ebp,%esp
0x8048b45 <phase_1+37> pop %ebp
0x8048b46 <phase_1+38> ret
We are at the instruction 12
on the function phase_1
. We see that there's an incoming function call strings_not_equal
so let's set a breakpoint there to analize the arguments that this function is called with:
b *(phase_1+18)
And let's continue:
c
We are now on the instruction 18
on the function phase_1
:
B+ 0x8048b2c <phase_1+12> push $0x80497c0
0x8048b31 <phase_1+17> push %eax
B+>0x8048b32 <phase_1+18> call 0x8049030 <strings_not_equal>
0x8048b37 <phase_1+23> add $0x10,%esp
0x8048b3a <phase_1+26> test %eax,%eax
0x8048b3c <phase_1+28> je 0x8048b43 <phase_1+35>
0x8048b3e <phase_1+30> call 0x80494fc <explode_bomb>
0x8048b43 <phase_1+35> mov %ebp,%esp
0x8048b45 <phase_1+37> pop %ebp
0x8048b46 <phase_1+38> ret
So let's check the arguments! We see that the arguments are passed using the stack (there are two push
) instructions before our function is called:
B+ 0x8048b2c <phase_1+12> push $0x80497c0
0x8048b31 <phase_1+17> push %eax
Let's check those values (%eax
and 0x80497c0
) using gdb:
x/s $eax
> 0x804b680 <input_strings>: "hello"
x/s 0x80497c0
> 0x80497c0: "Public speaking is very easy."
Huh, we can see that the two arguments passed to the strings_not_equal
function are the string we input in the beggining and another string. These must be the first phase flag!!!
Solution: "Public speaking is very easy"