BABY CTF — GDB FTW

Hi everyone, it’s been some time since I last posted but I was just playing IO WARGAME and decided to write some up some solutions in the hope it may help people just starting out.

Firstly, ssh in to the box (password: level1)

ssh level1@io.netgarage.org

Now enter the challenge directory

cd /levels

Now you are here, you’re free to try and run level01, if you do it will ask for a 3 digit passcode.

Enter the 3 digit passcode to enter:

Since I know this box has gdb, I am sure it’s easy to solve there so let’s try. Run gdb and supply the level01 script as the first argument.

sh-4.3$ gdb level01

One of the first things I do on entry level challenges is to use ‘disas main’ which will show us the main function, usually this is enough — in this case it is.

(gdb) disas main

You will then be shown the disassembly of the C code, since the C code was compiled we do not get the original C code but we do get assembly language and I will take that over machine code any day.

Dump of assembler code for function main:
0x08048080 <+0>: push $0x8049128
0x08048085 <+5>: call 0x804810f
0x0804808a <+10>: call 0x804809f
0x0804808f <+15>: cmp $0x10f,%eax
0x08048094 <+20>: je 0x80480dc
0x0804809a <+26>: call 0x8048103
End of assembler dump.

One thing that jumps out is the use of ‘cmp’, it means compare, which as I bet you’re now thinking means that’s where our program logic is for access control. In many large real-world apps there are many of these, many of which are benign comparison functions, however since it’s level01 I am sure this is it. Let’s see.

First we need to set a breakpoint there to check if it is our access control logic. With gdb simply copy the address and use ‘b*

(gdb) b* 0x0804808f
Breakpoint 1 at 0x804808f

Now if we run it will ask us for the three digit pass as before, except when entered it will hit our breakpoint.

(gdb) run
Starting program: /levels/level01
Enter the 3 digit passcode to enter: 123

Breakpoint 1, 0x0804808f in main ()

Note above, we gave 123 as our three digit pass. Once we hit enter we hit our breakpoint, perfect, now we want to know what is being compared here ‘cmp $0x10f,%eax’. A good place to start are the standard registers, so first let’s check out the eax register — we can do that with ‘info registers $REGISTER’, so for us to see eax we use the following command ‘info registers eax

(gdb) info registers eax
eax 0x7b 123

Great, so we have now confirmed that eax holds our user supplied input, so now we can deduce that ‘$0x10f’ is the value we need to use. 0x10f is simply hexadecimal, aka base16 so we can do the math on paper if we want, or in your head if you’re smart but we can also use the gdb command for print to show us the decimal value which we need to supply. The command is simply ‘p/d $HEX’, so we use ‘p/d 0x10f

(gdb) p/d 0x10f
$1 = 271

We see it’s 271 which is three digits, this could well be what we need. Let’s confirm. If we continue to run, we exit and don’t pass since we gave incorrect pass but if we run again and supply 271 it will work.

(gdb) c
Continuing.
[Inferior 1 (process 17165) exited normally]
(gdb)
The program is not being run.
(gdb) r
Starting program: /levels/level01
Enter the 3 digit passcode to enter: 271

Breakpoint 1, 0x0804808f in main ()
(gdb) c
Continuing.
Congrats you found it, now read the password for level2 from /home/level2/.pass
process 17171 is executing new program: /bin/bash

Great, that was it — let’s exit gdb and confirm one last time.

Simple process, but effective for low level CTFs and binary challenges — and in some cases some really bad real-world programming. Never check the low hanging fruit, I have made that mistake in the past —often the best option is the simplest.

Security Researcher / 365 Days of PWN