1

I am trying to crack a crackme. I already catch the flag because I seen the string variable which represants flag. I would like to catch the flag on an other way, I want to set a breakpoint when there is a comparison of the string. I want to use radare2.

When I use the dc command to run the program which should stop to breakpoint I set up, I have the message TO DO continue. I don't know why. I expected a message in the form :

string 1 : TheStringIEnter string 2 : TheFlagOfTheChallenge

This is the commands I execute :

radare 2 -d ch1.bin
s sym.main
aaa
pdf
VV
:
:> db 0x08048705
:> dc
TODO continue
:> 

This is the output of pdf command :

[0x0804869d]> pdf
/ (fcn) main 155
|   main (int argc, char **argv, char **envp);
|           ; var int local_ch @ ebp-0xc
|           ; var int local_8h @ ebp-0x8
|           ; var int local_4h @ esp+0x4
|           ; DATA XREF from entry0 (0x8048507)
|           0x0804869d      8d4c2404       lea ecx, [local_4h]         ; 4
|           0x080486a1      83e4f0         and esp, 0xfffffff0
|           0x080486a4      ff71fc         push dword [ecx - 4]
|           0x080486a7      55             push ebp
|           0x080486a8      89e5           mov ebp, esp
|           0x080486aa      51             push ecx
|           0x080486ab      83ec24         sub esp, 0x24               ; '$'
|           0x080486ae      c745f8418804.  mov dword [local_8h], str.123456789 ; 0x8048841 ; "123456789"
|           0x080486b5      c704244c8804.  mov dword [esp], str.       ; [0x804884c:4]=0x23232323 ; "############################################################"
|           0x080486bc      e807feffff     call sym.imp.puts           ; int puts(const char *s)
|           0x080486c1      c704248c8804.  mov dword [esp], str.welcome_to_challenge ; [0x804888c:4]=0x20202323 ; "##        Welcome to this challenge        ##"
|           0x080486c8      e8fbfdffff     call sym.imp.puts           ; int puts(const char *s)
|           0x080486cd      c70424cc8804.  mov dword [esp], str.       ; [0x80488cc:4]=0x23232323 ; "############################################################\n"
|           0x080486d4      e8effdffff     call sym.imp.puts           ; int puts(const char *s)
|           0x080486d9      c704240c8904.  mov dword [esp], str.please_enter_pass: ; [0x804890c:4]=0x69756556 ; "Please enter the password : "
|           0x080486e0      e8b3fdffff     call sym.imp.printf         ; int printf(const char *format)
|           0x080486e5      8b45f4         mov eax, dword [local_ch]
|           0x080486e8      890424         mov dword [esp], eax
|           0x080486eb      e80effffff     call sym.getString
|           0x080486f0      8945f4         mov dword [local_ch], eax
|           0x080486f3      8b45f8         mov eax, dword [local_8h]
|           0x080486f6      89442404       mov dword [local_4h], eax
|           0x080486fa      8b45f4         mov eax, dword [local_ch]
|           0x080486fd      890424         mov dword [esp], eax
|           0x08048700      e8d3fdffff     call sym.imp.strcmp         ; int strcmp(const char *s1, const char *s2)
|           0x08048705      85c0           test eax, eax
|       ,=< 0x08048707      7515           jne 0x804871e
|       |   0x08048709      8b45f8         mov eax, dword [local_8h]
|       |   0x0804870c      89442404       mov dword [local_4h], eax
|       |   0x08048710      c70424308904.  mov dword [esp], str.good_job:__s ; [0x8048930:4]=0x6e656942 ; "Good job ! You just pass the challenge with the pass : %s!\n"
|       |   0x08048717      e87cfdffff     call sym.imp.printf         ; int printf(const char *format)
|      ,==< 0x0804871c      eb0c           jmp 0x804872a
|      ||   ; CODE XREF from main (0x8048707)
|      |`-> 0x0804871e      c70424708904.  mov dword [esp], str.bad__password. ; [0x8048970:4]=0x6d6d6f44 ; "Bad password."
|      |    0x08048725      e89efdffff     call sym.imp.puts           ; int puts(const char *s)
|      |    ; CODE XREF from main (0x804871c)
|      `--> 0x0804872a      b800000000     mov eax, 0
|           0x0804872f      83c424         add esp, 0x24               ; '$'
|           0x08048732      59             pop ecx
|           0x08048733      5d             pop ebp
|           0x08048734      8d61fc         lea esp, [ecx - 4]
\           0x08048737      c3             ret
[0x0804869d]> 
  • I think there are issues already open for this. Disable ESIL emulation and don't open in debug mode. Use doo in normal mode for dc to work – sudhackar Dec 25 '18 at 5:40
  • Ok, I executed the doo command and it works : radare2 ch1.bin aaa s sym.main pdf ood db 0x08048705 dc Now, radare2 show me this message : hit breakpoint at: 8048705. How can I print the two strings which are compared. – user26834 Dec 26 '18 at 14:22
  • Can you share the binary? – sudhackar Dec 27 '18 at 5:26
  • Sure, this is the link of the challenge : root-me.org/fr/Challenges/Cracking/ELF-0-protection – user26834 Dec 27 '18 at 9:53
1

Here's how you do it with debugging.

$ r2 ch1.bin
[0x080484f0]> 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.
[0x080484f0]> doo
Process with PID 18337 started...
File dbg:///tmp/ch1.bin  reopened in read-write mode
= attach 18337 18337
18337
[0xf7f6fc70]> pdf @ sym.main ~strcmp
│           0x08048700      e8d3fdffff     call sym.imp.strcmp         ; int strcmp(const char *s1, const char *s2)

Set a breakpoint at the strcmp call and continue execution.

[0xf7f6fc70]> s 0x08048700
[0x08048700]> db 0x08048700
[0x08048700]> dc
############################################################
##        Bienvennue dans ce challenge de cracking        ##
############################################################

Veuillez entrer le mot de passe : test
hit breakpoint at: 8048700

Use pxr to dump esp with flags and information about addresses.

[0x08048700]> pxr@esp~:0..5
0xfff45270  0x09075570  pU.. @esp eax (test)
0xfff45274  0x08048841  A... (.rodata) (/tmp/ch1.bin) str.123456789 program R X 'xor dword [edx], esi' 'ch1.bin' (123456789)
0xfff45278  0xfff452a8  .R.. stack R W 0x0 -->  edi
0xfff4527c  0x08048769  i... (.text) (/tmp/ch1.bin) sym.__libc_csu_init program R X 'lea eax, [ebx - 0xe8]' 'ch1.bin'
0xfff45280  0x00000000  .... edi
[0x08048700]>

Stack top points to our input test passed as first param to strcmp. The next dword points to the second param at 0x08048841 string 123456789.

Since strcmp is a library function you can use ltrace to do the same.

$ ltrace ./ch1.bin
__libc_start_main(0x804869d, 1, 0xffbe8304, 0x8048750 <unfinished ...>
puts("################################"...############################################################
)                                               = 61
puts("##        Bienvennue dans ce cha"...##        Bienvennue dans ce challenge de cracking        ##
)                                               = 61
puts("################################"...############################################################

)                                               = 62
printf("Veuillez entrer le mot de passe "...)                                             = 34
malloc(2)                                                                                 = 0x9352570
getchar(2, 0, 0xffbe8258, 0xf7d792f6Veuillez entrer le mot de passe : test
)                                                     = 116
realloc(0x9352570, 2)                                                                     = 0x9352570
getchar(0x9352570, 2, 0xffbe8258, 0xf7d792f6)                                             = 101
realloc(0x9352570, 3)                                                                     = 0x9352570
getchar(0x9352570, 3, 0xffbe8258, 0xf7d792f6)                                             = 115
realloc(0x9352570, 4)                                                                     = 0x9352570
getchar(0x9352570, 4, 0xffbe8258, 0xf7d792f6)                                             = 116
realloc(0x9352570, 5)                                                                     = 0x9352570
getchar(0x9352570, 5, 0xffbe8258, 0xf7d792f6)                                             = 10
strcmp("test", "123456789")                                                               = 1
puts("Dommage, essaye encore une fois."...Dommage, essaye encore une fois.
)                                               = 33
+++ exited (status 0) +++

TBF you don't need to debug it at all and just static analysis would do.

[0x080484f0]> pdf @ sym.main~strcmp
│           0x08048700      e8d3fdffff     call sym.imp.strcmp         ; int strcmp(const char *s1, const char *s2)
[0x080484f0]> s 0x08048700
[0x08048700]> pd-10
│           0x080486d9      c704240c8904.  mov dword [esp], str.Veuillez_entrer_le_mot_de_passe_: ; [0x804890c:4]=0x69756556 ; "Veuillez entrer le mot de passe : " ; const char *format
│           0x080486e0      e8b3fdffff     call sym.imp.printf         ; int printf(const char *format)
│           0x080486e5      8b45f4         mov eax, dword [s1]
│           0x080486e8      890424         mov dword [esp], eax
│           0x080486eb      e80effffff     call sym.getString
│           0x080486f0      8945f4         mov dword [s1], eax
│           0x080486f3      8b45f8         mov eax, dword [local_8h]
│           0x080486f6      89442404       mov dword [s2], eax         ; const char *s2
│           0x080486fa      8b45f4         mov eax, dword [s1]
│           0x080486fd      890424         mov dword [esp], eax        ; const char *s1
[0x08048700]>

Now we know the arguments to strcmp : s1 and local_8h. s1 was populated with a call to sym.getString, so thats probably our input and hence local_8h is the string we need to find to match.

We'll see where it was used//modified (read/write) in the function. Use afv(R/W)

[0x08048700]> afv?
Usage: afv  [rbs]
| afvr[?]                       manipulate register based arguments
| afvb[?]                       manipulate bp based arguments/locals
| afvs[?]                       manipulate sp based arguments/locals
| afv*                          output r2 command to add args/locals to flagspace
| afvR [varname]                list addresses where vars are accessed (READ)
| afvW [varname]                list addresses where vars are accessed (WRITE)
| afva                          analyze function arguments/locals
| afvd name                     output r2 command for displaying the value of args/locals in the debugger
| afvn [new_name] ([old_name])  rename argument/local
| afvt [name] [new_type]        change type for given argument/local
| afv-([name])                  remove all or given var

Use this on local_8h

[0x08048700]> afvR local_8h
  local_8h  0x80486f3,0x8048709
[0x08048700]> afvW local_8h
  local_8h  0x80486ae

At 0x80486ae it was written to or initialized.

[0x08048700]> pd3 @ 0x80486ae 
│           0x080486ae      c745f8418804.  mov dword [local_8h], str.123456789 ; 0x8048841 ; "123456789"
│           0x080486b5      c704244c8804.  mov dword [esp], str.       ; [0x804884c:4]=0x23232323 ; "############################################################" ; const char *s
│           0x080486bc      e807feffff     call sym.imp.puts           ; int puts(const char *s)
[0x08048700]> 

Here r2 resolved the address 0x8048841 to a string 123456789

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy