IOLI Crackme 0x05 solution

Hello,

This is another IOLI crackme challenge solution.

root@kali:~/IOLI-crackme/bin-linux# r2 crackme0x05

[0x080483d0]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
[x] Type matching analysis for all functions (afta)
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x080483d0]> afl
0x0804833c    1 23           sym._init
0x08048364    1 6            sym.imp.__libc_start_main
0x08048374    1 6            sym.imp.scanf
0x08048384    1 6            sym.imp.strlen
0x08048394    1 6            sym.imp.printf
0x080483a4    1 6            sym.imp.sscanf
0x080483b4    1 6            sym.imp.exit
0x080483d0    1 33           entry0
0x080483f4    3 33           fcn.080483f4
0x08048420    6 47           sym.__do_global_dtors_aux
0x08048450    4 50           sym.frame_dummy
0x08048484    3 68           sym.parell
0x080484c8    6 120          sym.check
0x08048540    1 92           sym.main
0x080485a0    4 99           sym.__libc_csu_init
0x08048610    1 5            sym.__libc_csu_fini
0x08048615    1 4            sym.__i686.get_pc_thunk.bx
0x08048620    4 35           sym.__do_global_ctors_aux
0x08048644    1 26           sym._fini
[0x080483d0]> pdf @ sym.main            
-- main:
┌ (fcn) sym.main 92
│   sym.main (int argc, char **argv, char **envp);
│           ; var int local_78h @ ebp-0x78
│           ; var int local_4h @ esp+0x4
│           ; DATA XREF from entry0 (0x80483e7)
│           0x08048540      55             push ebp                    ; push word, doubleword or quadword onto the stack
│           0x08048541      89e5           mov ebp, esp                ; moves data from src to dst
│           0x08048543      81ec88000000   sub esp, 0x88               ; substract src and dst, stores result on dst
│           0x08048549      83e4f0         and esp, 0xfffffff0         ; binary and operation between src and dst, stores result on dst
│           0x0804854c      b800000000     mov eax, 0                  ; moves data from src to dst
│           0x08048551      83c00f         add eax, 0xf                ; adds src and dst, stores result on dst
│           0x08048554      83c00f         add eax, 0xf                ; adds src and dst, stores result on dst
│           0x08048557      c1e804         shr eax, 4                  ; logic right shift (0 padding)
│           0x0804855a      c1e004         shl eax, 4                  ; logic left shift (0 padding)
│           0x0804855d      29c4           sub esp, eax                ; substract src and dst, stores result on dst
│           0x0804855f      c704248e8604.  mov dword [esp], str.IOLI_Crackme_Level_0x05 ; [0x804868e:4]=0x494c4f49 ; "IOLI Crackme Level 0x05\n" ; moves data from src to dst; const char *format
│           0x08048566      e829feffff     call sym.imp.printf         ; calls a subroutine, push eip into the stack (esp) ; int printf(const char *format)
│           0x0804856b      c70424a78604.  mov dword [esp], str.Password: ; [0x80486a7:4]=0x73736150 ; "Password: " ; moves data from src to dst; const char *format
│           0x08048572      e81dfeffff     call sym.imp.printf         ; calls a subroutine, push eip into the stack (esp) ; int printf(const char *format)
│           0x08048577      8d4588         lea eax, dword [local_78h]  ; load effective address
│           0x0804857a      89442404       mov dword [local_4h], eax   ; moves data from src to dst
│           0x0804857e      c70424b28604.  mov dword [esp], 0x80486b2  ; [0x80486b2:4]=0x7325 ; moves data from src to dst; const char *format
│           0x08048585      e8eafdffff     call sym.imp.scanf          ; calls a subroutine, push eip into the stack (esp) ; int scanf(const char *format)
│           0x0804858a      8d4588         lea eax, dword [local_78h]  ; load effective address
│           0x0804858d      890424         mov dword [esp], eax        ; moves data from src to dst
│           0x08048590      e833ffffff     call sym.check              ; calls a subroutine, push eip into the stack (esp)
│           0x08048595      b800000000     mov eax, 0                  ; moves data from src to dst
│           0x0804859a      c9             leave                       ; one byte alias for mov esp, ebp ; pop ebp
└           0x0804859b      c3             ret                         ; return from subroutine. 

pop 4 bytes from esp and jump there.

[0x080483d0]> pdf @ sym.check`
┌ (fcn) sym.check 120
│   sym.check (char *s);
│           ; var char *local_dh @ ebp-0xd
│           ; var unsigned int local_ch @ ebp-0xc
│           ; var unsigned int local_8h @ ebp-0x8
│           ; var int local_4h @ ebp-0x4
│           ; arg char *s @ ebp+0x8
│           ; var char *format @ esp+0x4
│           ; var int local_8h_2 @ esp+0x8
│           ; CALL XREF from sym.main (0x8048590)
│           0x080484c8      55             push ebp                    ; push word, doubleword or quadword onto the stack
│           0x080484c9      89e5           mov ebp, esp                ; moves data from src to dst
│           0x080484cb      83ec28         sub esp, 0x28               ; '(' ; substract src and dst, stores result on dst
│           0x080484ce      c745f8000000.  mov dword [local_8h], 0     ; moves data from src to dst
│           0x080484d5      c745f4000000.  mov dword [local_ch], 0     ; moves data from src to dst
│           ; CODE XREF from sym.check (0x8048530)
│       ┌─> 0x080484dc      8b4508         mov eax, dword [s]          ; [0x8:4]=-1 ; 8 ; moves data from src to dst
│       ╎   0x080484df      890424         mov dword [esp], eax        ; moves data from src to dst; const char *s
│       ╎   0x080484e2      e89dfeffff     call sym.imp.strlen         ; calls a subroutine, push eip into the stack (esp) ; size_t strlen(const char *s)
│       ╎   0x080484e7      3945f4         cmp dword [local_ch], eax   ; compare two operands
│      ┌──< 0x080484ea      7346           jae 0x8048532               ; jump short if above or equal (cf=0)
│      │╎   0x080484ec      8b45f4         mov eax, dword [local_ch]   ; moves data from src to dst
│      │╎   0x080484ef      034508         add eax, dword [s]          ; adds src and dst, stores result on dst
│      │╎   0x080484f2      0fb600         movzx eax, byte [eax]       ; move dst register size padding with zeroes
│      │╎   0x080484f5      8845f3         mov byte [local_dh], al     ; moves data from src to dst
│      │╎   0x080484f8      8d45fc         lea eax, dword [local_4h]   ; load effective address
│      │╎   0x080484fb      89442408       mov dword [local_8h_2], eax ; moves data from src to dst;   ...
│      │╎   0x080484ff      c74424046886.  mov dword [format], 0x8048668 ; [0x8048668:4]=0x50006425 ; moves data from src to dst; const char *format
│      │╎   0x08048507      8d45f3         lea eax, dword [local_dh]   ; load effective address
│      │╎   0x0804850a      890424         mov dword [esp], eax        ; moves data from src to dst; const char *s
│      │╎   0x0804850d      e892feffff     call sym.imp.sscanf         ; calls a subroutine, push eip into the stack (esp) ; int sscanf(const char *s, const char *format,   ...)
│      │╎   0x08048512      8b55fc         mov edx, dword [local_4h]   ; moves data from src to dst
│      │╎   0x08048515      8d45f8         lea eax, dword [local_8h]   ; load effective address
│      │╎   0x08048518      0110           add dword [eax], edx        ; adds src and dst, stores result on dst
│      │╎   0x0804851a      837df810       cmp dword [local_8h], 0x10  ; compare two operands
│     ┌───< 0x0804851e      750b           jne 0x804852b               ; jump short if not equal/not zero (zf=0)
│     ││╎   0x08048520      8b4508         mov eax, dword [s]          ; [0x8:4]=-1 ; 8 ; moves data from src to dst
│     ││╎   0x08048523      890424         mov dword [esp], eax        ; moves data from src to dst
│     ││╎   0x08048526      e859ffffff     call sym.parell             ; calls a subroutine, push eip into the stack (esp)
│     ││╎   ; CODE XREF from sym.check (0x804851e)
│     └───> 0x0804852b      8d45f4         lea eax, dword [local_ch]   ; load effective address
│      │╎   0x0804852e      ff00           inc dword [eax]             ; increment by 1
│      │└─< 0x08048530      ebaa           jmp 0x80484dc               ; jump
│      │    ; CODE XREF from sym.check (0x80484ea)
│      └──> 0x08048532      c70424798604.  mov dword [esp], str.Password_Incorrect ; [0x8048679:4]=0x73736150 ; "Password Incorrect!\n" ; moves data from src to dst; const char *format
│           0x08048539      e856feffff     call sym.imp.printf         ; calls a subroutine, push eip into the stack (esp) ; int printf(const char *format)
│           0x0804853e      c9             leave                       ; one byte alias for mov esp, ebp ; pop ebp
└           0x0804853f      c3             ret                         ; return from subroutine. 

Pop 4 bytes from esp and jump there.

[0x080483d0]> ? 0x10
hex     0x10
octal   020
unit    16
segment 0000:0010
int32   16
string  "\x10"
binary  0b00010000f
value: 16.0
float:  0.000000f
double: 0.000000
trits   0t121

Apparently this levels so similar to the past one, so let’s try the same method with 16 as cmp operand.

root@kali:~/IOLI-crackme/bin-linux# ./crackme0x05

IOLI Crackme Level 0x05
Password: 88
Password OK!