All writeups. Or maybe just CrackMe0x05?

This is a walkthrough for the CrackMe0x06 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)

Let’s take a dump 😉

(gdb) disass main
Dump of assembler code for function main:
   0x08048607 <+0>:	push   %ebp
   0x08048608 <+1>:	mov    %esp,%ebp
   0x0804860a <+3>:	sub    $0x88,%esp
   0x08048610 <+9>:	and    $0xfffffff0,%esp
   0x08048613 <+12>:	mov    $0x0,%eax
   0x08048618 <+17>:	add    $0xf,%eax
   0x0804861b <+20>:	add    $0xf,%eax
   0x0804861e <+23>:	shr    $0x4,%eax
   0x08048621 <+26>:	shl    $0x4,%eax
   0x08048624 <+29>:	sub    %eax,%esp
   0x08048626 <+31>:	movl   $0x8048763,(%esp)
   0x0804862d <+38>:	call   0x80483b8 <printf@plt>
   0x08048632 <+43>:	movl   $0x804877c,(%esp)
   0x08048639 <+50>:	call   0x80483b8 <printf@plt>
   0x0804863e <+55>:	lea    -0x78(%ebp),%eax
   0x08048641 <+58>:	mov    %eax,0x4(%esp)
   0x08048645 <+62>:	movl   $0x8048787,(%esp)
   0x0804864c <+69>:	call   0x8048398 <scanf@plt>
   0x08048651 <+74>:	mov    0x10(%ebp),%eax
   0x08048654 <+77>:	mov    %eax,0x4(%esp)
   0x08048658 <+81>:	lea    -0x78(%ebp),%eax
   0x0804865b <+84>:	mov    %eax,(%esp)
   0x0804865e <+87>:	call   0x8048588 <check>
   0x08048663 <+92>:	mov    $0x0,%eax
   0x08048668 <+97>:	leave  
   0x08048669 <+98>:	ret    
End of assembler dump.

(gdb) disass check
Dump of assembler code for function check:
   0x08048588 <+0>:	push   %ebp
   0x08048589 <+1>:	mov    %esp,%ebp
   0x0804858b <+3>:	sub    $0x28,%esp
   0x0804858e <+6>:	movl   $0x0,-0x8(%ebp)
   0x08048595 <+13>:	movl   $0x0,-0xc(%ebp)
   0x0804859c <+20>:	mov    0x8(%ebp),%eax
   0x0804859f <+23>:	mov    %eax,(%esp)
   0x080485a2 <+26>:	call   0x80483a8 <strlen@plt>
   0x080485a7 <+31>:	cmp    %eax,-0xc(%ebp)
   0x080485aa <+34>:	jae    0x80485f9 <check+113>
   0x080485ac <+36>:	mov    -0xc(%ebp),%eax
   0x080485af <+39>:	add    0x8(%ebp),%eax
   0x080485b2 <+42>:	movzbl (%eax),%eax
   0x080485b5 <+45>:	mov    %al,-0xd(%ebp)
   0x080485b8 <+48>:	lea    -0x4(%ebp),%eax
   0x080485bb <+51>:	mov    %eax,0x8(%esp)
   0x080485bf <+55>:	movl   $0x804873d,0x4(%esp)
   0x080485c7 <+63>:	lea    -0xd(%ebp),%eax
   0x080485ca <+66>:	mov    %eax,(%esp)
   0x080485cd <+69>:	call   0x80483c8 <sscanf@plt>
   0x080485d2 <+74>:	mov    -0x4(%ebp),%edx
   0x080485d5 <+77>:	lea    -0x8(%ebp),%eax
   0x080485d8 <+80>:	add    %edx,(%eax)
   0x080485da <+82>:	cmpl   $0x10,-0x8(%ebp)
   0x080485de <+86>:	jne    0x80485f2 <check+106>
   0x080485e0 <+88>:	mov    0xc(%ebp),%eax
   0x080485e3 <+91>:	mov    %eax,0x4(%esp)
   0x080485e7 <+95>:	mov    0x8(%ebp),%eax
   0x080485ea <+98>:	mov    %eax,(%esp)
   0x080485ed <+101>:	call   0x804851a <parell>
   0x080485f2 <+106>:	lea    -0xc(%ebp),%eax
   0x080485f5 <+109>:	incl   (%eax)
   0x080485f7 <+111>:	jmp    0x804859c <check+20>
   0x080485f9 <+113>:	movl   $0x804874e,(%esp)
   0x08048600 <+120>:	call   0x80483b8 <printf@plt>
   0x08048605 <+125>:	leave  
   0x08048606 <+126>:	ret    
End of assembler dump.

(gdb) disass parell
Dump of assembler code for function parell:
   0x0804851a <+0>:	push   %ebp
   0x0804851b <+1>:	mov    %esp,%ebp
   0x0804851d <+3>:	sub    $0x18,%esp
   0x08048520 <+6>:	lea    -0x4(%ebp),%eax
   0x08048523 <+9>:	mov    %eax,0x8(%esp)
   0x08048527 <+13>:	movl   $0x804873d,0x4(%esp)
   0x0804852f <+21>:	mov    0x8(%ebp),%eax
   0x08048532 <+24>:	mov    %eax,(%esp)
   0x08048535 <+27>:	call   0x80483c8 <sscanf@plt>
   0x0804853a <+32>:	mov    0xc(%ebp),%eax
   0x0804853d <+35>:	mov    %eax,0x4(%esp)
   0x08048541 <+39>:	mov    -0x4(%ebp),%eax
   0x08048544 <+42>:	mov    %eax,(%esp)
   0x08048547 <+45>:	call   0x80484b4 <dummy>
   0x0804854c <+50>:	test   %eax,%eax
   0x0804854e <+52>:	je     0x8048586 <parell+108>
   0x08048550 <+54>:	movl   $0x0,-0x8(%ebp)
   0x08048557 <+61>:	cmpl   $0x9,-0x8(%ebp)
   0x0804855b <+65>:	jg     0x8048586 <parell+108>
   0x0804855d <+67>:	mov    -0x4(%ebp),%eax
   0x08048560 <+70>:	and    $0x1,%eax
   0x08048563 <+73>:	test   %eax,%eax
   0x08048565 <+75>:	jne    0x804857f <parell+101>
   0x08048567 <+77>:	movl   $0x8048740,(%esp)
   0x0804856e <+84>:	call   0x80483b8 <printf@plt>
   0x08048573 <+89>:	movl   $0x0,(%esp)
   0x0804857a <+96>:	call   0x80483e8 <exit@plt>
   0x0804857f <+101>:	lea    -0x8(%ebp),%eax
   0x08048582 <+104>:	incl   (%eax)
   0x08048584 <+106>:	jmp    0x8048557 <parell+61>
   0x08048586 <+108>:	leave  
   0x08048587 <+109>:	ret    
End of assembler dump.

(gdb) disass dummy
Dump of assembler code for function dummy:
   0x080484b4 <+0>:	push   %ebp
   0x080484b5 <+1>:	mov    %esp,%ebp
   0x080484b7 <+3>:	sub    $0x18,%esp
   0x080484ba <+6>:	movl   $0x0,-0x4(%ebp)
   0x080484c1 <+13>:	mov    -0x4(%ebp),%eax
   0x080484c4 <+16>:	lea    0x0(,%eax,4),%edx
   0x080484cb <+23>:	mov    0xc(%ebp),%eax
   0x080484ce <+26>:	cmpl   $0x0,(%edx,%eax,1)
   0x080484d2 <+30>:	je     0x804850e <dummy+90>
   0x080484d4 <+32>:	mov    -0x4(%ebp),%eax
   0x080484d7 <+35>:	lea    0x0(,%eax,4),%ecx
   0x080484de <+42>:	mov    0xc(%ebp),%edx
   0x080484e1 <+45>:	lea    -0x4(%ebp),%eax
   0x080484e4 <+48>:	incl   (%eax)
   0x080484e6 <+50>:	movl   $0x3,0x8(%esp)
   0x080484ee <+58>:	movl   $0x8048738,0x4(%esp)
   0x080484f6 <+66>:	mov    (%ecx,%edx,1),%eax
   0x080484f9 <+69>:	mov    %eax,(%esp)
   0x080484fc <+72>:	call   0x80483d8 <strncmp@plt>
   0x08048501 <+77>:	test   %eax,%eax
   0x08048503 <+79>:	jne    0x80484c1 <dummy+13>
   0x08048505 <+81>:	movl   $0x1,-0x8(%ebp)
   0x0804850c <+88>:	jmp    0x8048515 <dummy+97>
   0x0804850e <+90>:	movl   $0x0,-0x8(%ebp)
   0x08048515 <+97>:	mov    -0x8(%ebp),%eax
   0x08048518 <+100>:	leave  
   0x08048519 <+101>:	ret    
End of assembler dump.

Ew – another new function. On the bright side, <main> and <check> look the same. <parell> just seems to have an extra call to <dummy> – it also seems dummy returns a value as <parell+50> is handling it, with a conditional jump after.

The condition at <parell+52> is ‘je’ – if the previous line is equal. ‘test eax, eax’ is equivalent to ‘and eax, eax’ but stores the result in ZF (zero flag) instead of eax. That means in order for the jump to be executed, <dummy> must return a zero. But we don’t want the jump as that will skip over the “Password OK” line on <parell+84>. That must mean that our dummy should return a non-zero value.

Inspecting with radare2 shows us that of the jump at 0x080484d2 will cause the output of the <dummy> function to be 0 – that means we must mean that at 0x080484ce, dword [edx + eax] must not equal to zero. Radare2 shows jumps really nicely in visual mode, with the arrows on the left. Remember that if we are to debug <dummy> by inserting a breakpoint our password must add up to exactly 16 at one point (<check>) and have the last/next number be even (<parell>).

I’m a bit stuck here, but you can get the answers here. Time to go back to reading and learning more about assembly 🙂


Leave a Reply

Your email address will not be published. Required fields are marked *