All writeups. Or maybe just CrackMe0x01?

This is a walkthrough for the CrackMe0x02 that was part of the Rensselaer Polytechnic Institute’s Binary Exploitation course in Spring 2015. You can follow along by downloading the challenges here. (mirror 1, mirror 2)

As usual let’s start by running the binary.

Again, nothing new. Slightly modified welcome message and again, no re-prompts for incorrect passwords.

You’ll have to trust me on this but there’s nothing interesting that pops up with xxd, radare2 or strings. I would show you the radare2 output, but honestly I’m more comfortable with gdb. Here is a radare2 writeup if you’re into that :^)

As usual, let’s proceed with a dump of the assembly.

$ gdb ./crackme0x02
(gdb) disass main
Dump of assembler code for function main:
   0x080483e4 <+0>:	push   ebp
   0x080483e5 <+1>:	mov    ebp,esp
   0x080483e7 <+3>:	sub    esp,0x18
   0x080483ea <+6>:	and    esp,0xfffffff0
   0x080483ed <+9>:	mov    eax,0x0
   0x080483f2 <+14>:	add    eax,0xf
   0x080483f5 <+17>:	add    eax,0xf
   0x080483f8 <+20>:	shr    eax,0x4
   0x080483fb <+23>:	shl    eax,0x4
   0x080483fe <+26>:	sub    esp,eax
   0x08048400 <+28>:	mov    DWORD PTR [esp],0x8048548
   0x08048407 <+35>:	call   0x804831c <printf@plt>
   0x0804840c <+40>:	mov    DWORD PTR [esp],0x8048561
   0x08048413 <+47>:	call   0x804831c <printf@plt>
   0x08048418 <+52>:	lea    eax,[ebp-0x4]
   0x0804841b <+55>:	mov    DWORD PTR [esp+0x4],eax
   0x0804841f <+59>:	mov    DWORD PTR [esp],0x804856c
   0x08048426 <+66>:	call   0x804830c <scanf@plt>
   0x0804842b <+71>:	mov    DWORD PTR [ebp-0x8],0x5a
   0x08048432 <+78>:	mov    DWORD PTR [ebp-0xc],0x1ec
   0x08048439 <+85>:	mov    edx,DWORD PTR [ebp-0xc]
   0x0804843c <+88>:	lea    eax,[ebp-0x8]
   0x0804843f <+91>:	add    DWORD PTR [eax],edx
   0x08048441 <+93>:	mov    eax,DWORD PTR [ebp-0x8]
   0x08048444 <+96>:	imul   eax,DWORD PTR [ebp-0x8]
   0x08048448 <+100>:	mov    DWORD PTR [ebp-0xc],eax
   0x0804844b <+103>:	mov    eax,DWORD PTR [ebp-0x4]
   0x0804844e <+106>:	cmp    eax,DWORD PTR [ebp-0xc]
   0x08048451 <+109>:	jne    0x8048461 <main+125>
   0x08048453 <+111>:	mov    DWORD PTR [esp],0x804856f
   0x0804845a <+118>:	call   0x804831c <printf@plt>
   0x0804845f <+123>:	jmp    0x804846d <main+137>
   0x08048461 <+125>:	mov    DWORD PTR [esp],0x804857f
   0x08048468 <+132>:	call   0x804831c <printf@plt>
   0x0804846d <+137>:	mov    eax,0x0
   0x08048472 <+142>:	leave  
   0x08048473 <+143>:	ret    
End of assembler dump.

We can find our comparison at <main+106> – again it’s cmp so let’s assume they’re numbers. But what the hell is eax or DWORD PTR [ebp-0xc]? We know they’re registers – accumulator and base pointer (with an offset) and that they’ll change during execution of the code. So we’ll need to run the program up until the comparison. Let’s set a breakpoint.

(gdb) break *main+106
Breakpoint 1 at 0x804844e
(gdb) run
Starting program: /mnt/hdd1/Downloads/challenges/crackme0x02 
IOLI Crackme Level 0x02
Password: 12345

Breakpoint 1, 0x0804844e in main ()

Now let’s find the values of eax and DWORD PTR [ebp-0xc].

(gdb) print $eax
$1 = 12345
(gdb) x/x $ebp-0xc
0xffffd08c:	0x00052b24

So eax turns out to hold our input – 12345. That must mean DWORD PTR [ebp-0xc] contains the actual password. Once again, we don’t really want hexadecimal, so let’s convert the hexadecimal into decimal.

(gdb) print 0x00052b24
$2 = 338724

Yay!!!! Password ended up being 338724. What will CrackMe0x03 have in hold for us?