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 acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.