We are given following hints and source code:
Hints
- At this point in time, it might be easier to use someone elses shellcode
- If debugging the shellcode, use \xcc (int3) to stop the program executing and return to the debugger
- remove the int3s once your shellcode is done.
This program seems to do nothing special, let’s read what the man page tells us about gets():
“gets() reads a line from stdin into the buffer….”
But the more interesting part is section Bugs:
“Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use.“
This looks like we have to do a buffer overflow attack.
Before we start, we do a very small introduction to the most basic Intel x86 instruction set. If you want more details, have a look at the Intel 64 and IA-32 Architectures
Software Developer’s Manual
When we call a function, we will save the address of the instruction following after the current instruction on the stack and jump to the function we are calling. This guarantees, that we will jump back to the correct place, after the called function ends.
Starting /opt/protostar/bin/stack5 in gdb and disassembling the main function shows us following:
The instructions in the beginning are setting up our stack frame within our function – this is also known as function prologue. Our stack looks somehow like following, after the instruction pointer $eip reached <main+9>

We restart gdb and put a breakpoint at <main+0>
with break *0x080483c4
. Examining the stack with x/4wx $esp
show us the return address pushed on the stack frame of the caller function:
$eip: 0x80483c4 : push ebp
$esp: 0xbffffcbc: 0xb7eadc76 0x00000001 0xbffffd64 0xbffffd6c
We are going to overwrite 0xb7eadc76
placed at 0xbffffcbc
Adding a breakpoint at <main+16> with break *0x080483d4
and printing registers with info registers
shows us the value of register $eax, which indicates the start of the buffer
(gdb) info registers
eax 0xbffffc70
Doing some maths:
0xbffffcbc – 0xbffffc70 = 0x4C (=76 in decimal)
+ Another 4 bytes to overwrite the return address = 80 bytes
Entering 80 A’s and putting a breakpoint at <main+22> shows:
$eip: 0x80483da : ret
$esp: 0xbffffcbc: 0x41414141 0x00000000 0xbffffd64 0xbffffd6c
Looks good! We overwrote the return address (0x41 is character A) and the instruction ret will jump to the address on the top of the stack and increment the stack pointer (notice that stack starts at higher memory address)
Going back to the Hints in the beginning:
We need some shellcode that we can inject. Since we control the return address, we will overwrite the return address call our injected shellcode. We will write a small exploit for that and inject this shellcode.
However, writing this exploit
was only working in gdb with r < exploit, where exploit contains the resulting characters from exploit.py. Piping the exploit to the stdin of stack5 just returned immediately.
Here comes a trick: In combination with cat, we can force the shell to stay open
1 thought on “protostar – stack five”
Comments are closed.