Target APP:http://challenge01.root-me.org/cracking/ch3/ch3.bin[1][2]
Tools: gdb + radare2 +IDA Pro
Reference:https://en.wikipedia.org/wiki/Ptrace
http://man7.org/linux/man-pages/man2/ptrace.2.html
Usage:
ptrace is used by debuggers (such as gdb and dbx), by tracing tools like strace and ltrace, and by code coverage tools. ptrace is also used by specialized programs to patch running programs, to avoid unfixed bugs or to overcome security features. It can further be used as a sandbox
and as a run-time environment simulator (like emulating root access for non-root software.
Use IDA Pro To Disassemble Ptrace Function:
Load the application into IDA pro,search main function,press F5 to disassemble it,get the code below:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4; // [esp-Ch] [ebp-24h]
char v5; // [esp+2h] [ebp-16h]
const char *v6; // [esp+Ch] [ebp-Ch]
v6 = "ksuiealohgy";
if ( ptrace(0, 0, 1) >= 0 )
{
puts("############################################################");
puts("## Bienvennue dans ce challenge de cracking ##");
puts("############################################################\n");
printf("Password : ", v4);
fgets(&v5, 9, stdin);
JUMPOUT(__CS__, ¬ng + 1);
}
puts(&unk_80C2894);
return 1;
}
Double click ptrace,get the code blew.
unsigned int __cdecl ptrace(unsigned int a1, int a2, int a3)
{
unsigned int result; // eax
unsigned int v4; // [esp+Ch] [ebp-Ch]
result = dl_sysinfo(a2, a3);
if ( result > 0xFFFFF000 )
{
__writegsdword(0xFFFFFFE8, -result);
result = -1;
}
else if ( (result & 0x80000000) == 0 && a1 && a1 <= 3 )
{
__writegsdword(0xFFFFFFE8, 0);
result = v4;
}
return result;
}
According to assemble code below,the address which called ptrace function is:0x08048410
.text:080483F0 lea ecx, [esp+4]
.text:080483F4 and esp, 0FFFFFFF0h
.text:080483F7 push dword ptr [ecx-4]
.text:080483FA push ebp
.text:080483FB mov ebp, esp
.text:080483FD push ecx
.text:080483FE sub esp, 14h
.text:08048401 mov [ebp+var_C], offset aKsuiealohgy ; "ksuiealohgy"
.text:08048408 push 0
.text:0804840A push 1
.text:0804840C push 0
.text:0804840E push 0
.text:08048410 call ptrace
.text:08048415 add esp, 10h
.text:08048418 test eax, eax
.text:0804841A jns short loc_8048436
.text:0804841C sub esp, 0Ch
.text:0804841F push offset unk_80C2894
.text:08048424 call puts
.text:08048429 add esp, 10h
.text:0804842C mov eax, 1
.text:08048431 jmp loc_80484F9
Use Radare2 To Edit Elf File
We need use r2 to nop the ptrace called,and change the condition jump ‘jns’ to ‘jmp’
root@zyjsuper:~# r2 -ww ch3.bin //use edit mode
Warning: Cannot initialize dynamic strings
[0x080482f0]> aafl
|Usage: aa[0*?] # see also 'af' and 'afna'
| aa alias for 'af@@ sym.*;af@entry0;afva'
| aa* analyze all flags starting with sym. (af @@ sym.*)
| aaa[?] autoname functions after aa (see afna)
| aac [len] analyze function calls (af @@ `pi len~call[1]`)
| aad [len] analyze data references to code
| aae [len] ([addr]) analyze references with ESIL (optionally to address)
| aai[j] show info of all analysis parameters
| aar[?] [len] analyze len bytes of instructions for references
| aan autoname functions that either start with fcn.* or sym.func.*
| aas [len] analyze symbols (af @@= `isq~[0]`)
| aat [len] analyze all consecutive functions in section
| aaT [len] analyze code after trap-sleds
| aap find and analyze function preludes
| aav [sat] find values referencing a specific section or map
| aau [len] list mem areas (larger than len bytes) not covered by functions
[0x080482f0]> aaa
[ ] Analyze all flags starting with sym. and entry0 (aa)
//It maybe need a lot of time,you can type ctrl+c to cancel.
[x] Analyze all flags starting with sym. and entry0 (aa)
[0x080482f0]>
Use two commands below to nop the ptrace call and change the jump.
[0x080483f0]> wx 90 @ 0x08048410
[0x080483f0]> wx eb @ 0x0804841a
[0x080483f0]> pd 20
;-- main:
/ (fcn) sym.main 175
| sym.main ();
| ; var int local_16h @ ebp-0x16
| ; var int local_ch @ ebp-0xc
| ; var int local_4h @ ebp-0x4
| ; DATA XREF from 0x08048307 (entry0)
| 0x080483f0 8d4c2404 lea ecx, dword [esp + 4] ; 0x4
| 0x080483f4 83e4f0 and esp, 0xfffffff0
| 0x080483f7 ff71fc push dword [ecx - 4]
| 0x080483fa 55 push ebp
| 0x080483fb 89e5 mov ebp, esp
| 0x080483fd 51 push ecx
| 0x080483fe 83ec14 sub esp, 0x14
| 0x08048401 c745f488280c. mov dword [ebp - local_ch], str.ksuiealohgy
| 0x08048408 6a00 push 0
| 0x0804840a 6a01 push 1
| 0x0804840c 6a00 push 0
| 0x0804840e 6a00 push 0
| 0x08048410 e85b060100 call sym.ptrace
| 0x08048415 83c410 add esp, 0x10
| 0x08048418 85c0 test eax, eax
| ,=< 0x0804841a 791a jns 0x8048436
| | 0x0804841c 83ec0c sub esp, 0xc
| | 0x0804841f 6894280c08 push str.Debugger_detect___..._Exit ; str.Debugger_detect___..._Exit ; "Debugger detect.. ... Exit" @ 0x80c2894
| | 0x08048424 e8a70e0000 call sym.puts ; int puts(const char *s);
| | 0x08048429 83c410 add esp, 0x10
[0x080483f0]> wx 90 @ 0x08048410
[0x080483f0]> wx eb @ 0x0804841a
[0x080483f0]> pd 20
;-- main:
/ (fcn) sym.main 175
| sym.main ();
| ; var int local_16h @ ebp-0x16
| ; var int local_ch @ ebp-0xc
| ; var int local_4h @ ebp-0x4
| ; DATA XREF from 0x08048307 (entry0)
| 0x080483f0 8d4c2404 lea ecx, dword [esp + 4] ; 0x4
| 0x080483f4 83e4f0 and esp, 0xfffffff0
| 0x080483f7 ff71fc push dword [ecx - 4]
| 0x080483fa 55 push ebp
| 0x080483fb 89e5 mov ebp, esp
| 0x080483fd 51 push ecx
| 0x080483fe 83ec14 sub esp, 0x14
| 0x08048401 c745f488280c. mov dword [ebp - local_ch], str.ksuiealohgy
| 0x08048408 6a00 push 0
| 0x0804840a 6a01 push 1
| 0x0804840c 6a00 push 0
| 0x0804840e 6a00 push 0
| 0x08048410 90 nop
| 0x08048411 5b pop ebx
| 0x08048412 06 push es
| 0x08048413 0100 add dword [eax], eax
| 0x08048415 83c410 add esp, 0x10
| 0x08048418 85c0 test eax, eax
| ,=< 0x0804841a eb1a jmp 0x8048436
| | 0x0804841c 83ec0c sub esp, 0xc
[0x080483f0]> quit
// type 'y' to save the edit.
Use gdb to do tracking a debug,to find the real password.
In order to find the right password,we need to create suitable breakpoints for debugging,please follow the below.
root@zyjsuper:~# chmod +x ch3.bin
root@zyjsuper:~# gdb ch3.bin
(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
.......
0x08048486 <+150>: call 0x8048f90 <fgets>
0x0804848b <+155>: add esp,0x10
0x0804848e <+158>: lea eax,ds:0x8048497
0x08048494 <+164>: inc eax
0x08048495 <+165>: jmp eax
0x08048497 <+167>: mov eax,0x8bea558a
0x0804849c <+172>: inc ebp
--Type <RET> for more, q to quit, c to continue without paging--
0x0804849d <+173>: hlt
0x0804849e <+174>: add eax,0x4
0x080484a1 <+177>: mov al,BYTE PTR [eax]
0x080484a3 <+179>: cmp dl,al
0x080484a5 <+181>: jne 0x80484e4 <main+244>
0x080484a7 <+183>: mov dl,BYTE PTR [ebp-0x15]
0x080484aa <+186>: mov eax,DWORD PTR [ebp-0xc]
0x080484ad <+189>: add eax,0x5
0x080484b0 <+192>: mov al,BYTE PTR [eax]
0x080484b2 <+194>: cmp dl,al
0x080484b4 <+196>: jne 0x80484e4 <main+244>
0x080484b6 <+198>: mov dl,BYTE PTR [ebp-0x14]
0x080484b9 <+201>: mov eax,DWORD PTR [ebp-0xc]
0x080484bc <+204>: inc eax
0x080484bd <+205>: mov al,BYTE PTR [eax]
0x080484bf <+207>: cmp dl,al
0x080484c1 <+209>: jne 0x80484e4 <main+244>
0x080484c3 <+211>: mov dl,BYTE PTR [ebp-0x13]
0x080484c6 <+214>: mov eax,DWORD PTR [ebp-0xc]
0x080484c9 <+217>: add eax,0xa
0x080484cc <+220>: mov al,BYTE PTR [eax]
0x080484ce <+222>: cmp dl,al
0x080484d0 <+224>: jne 0x80484e4 <main+244>
0x080484d2 <+226>: sub esp,0xc
0x080484d5 <+229>: push 0x80c297a
0x080484da <+234>: call 0x80492d0 <puts>
0x080484df <+239>: add esp,0x10
0x080484e2 <+242>: jmp 0x80484f4 <main+260>
--Type <RET> for more, q to quit, c to continue without paging--
0x080484e4 <+244>: sub esp,0xc
0x080484e7 <+247>: push 0x80c298e
0x080484ec <+252>: call 0x80492d0 <puts>
0x080484f1 <+257>: add esp,0x10
0x080484f4 <+260>: mov eax,0x0
0x080484f9 <+265>: mov ecx,DWORD PTR [ebp-0x4]
0x080484fc <+268>: leave
0x080484fd <+269>: lea esp,[ecx-0x4]
0x08048500 <+272>: ret
End of assembler dump.
(gdb) b *0x080484a3
Breakpoint 2 at 0x80484a3
(gdb) b *0x080484b2
Breakpoint 3 at 0x80484b2
(gdb) b *0x080484ce
Breakpoint 4 at 0x80484ce
(gdb) b *0x080484bf
Breakpoint 5 at 0x80484bf
(gdb) i b
Num Type Disp Enb Address What
2 breakpoint keep y 0x080484a3 <main+179>
3 breakpoint keep y 0x080484b2 <main+194>
4 breakpoint keep y 0x080484ce <main+222>
5 breakpoint keep y 0x080484bf <main+207>
(gdb) r
Starting program: /root/ch3.bin
############################################################
## Bienvennue dans ce challenge de cracking ##
############################################################
Password : zyjsuper
Breakpoint 2, 0x080484a3 in main () //The programm break at the point we created.
(gdb) p $al
$1 = 101 //The ascii's value for the first character in the right password,it's 'e'.
(gdb) p $dl
$2 = 122
(gdb) set $al=$dl //If varible al and bl is the same value,the address will not be jump.
(gdb) c
Continuing.
Breakpoint 3, 0x080484b2 in main ()
(gdb) p $al
$3 = 97 //The ascii's value for the second character in the right password,it's 'a'.
(gdb) p $dl
$4 = 121
(gdb) set $al=$dl
(gdb) c
Continuing.
Breakpoint 5, 0x080484bf in main ()
(gdb) p $al
$5 = 115 //The ascii's value for the third character in the right password,it's 's'.
(gdb) p $dl
$6 = 106
(gdb) set $al=$dl
(gdb) c
Continuing.
Breakpoint 4, 0x080484ce in main ()
(gdb) p $al
$7 = 121 //The ascii's value for the forth character in the right password,it's 'y'.
(gdb) p $dl
$8 = 115
(gdb) set $al=$dl
(gdb) c
Continuing.
Good password !!!
So the validation password is:easy