In this set of questions we are going to create a buffer overflow exploit, including redirection to run some basic payload code.
Example adapted from https://www.soldierx.com/tutorials/Stack-Smashing-Modern-Linux-System
Create a trivial program vulnerable.c:
#include <string.h>
#include <stdio.h>
void go(char *data) {
char name[64];
printf("target: %p\n", name); // Print address of buffer.
strcpy(name, data);
}
int main(int argc, char **argv) {
go(argv[1]);
}
All this does is ask for a parameter on the command line and copy it to a variable "name".
It is again vulnerable code, which we can take advantage of via an overflow of the buffer.
To make life easier, the programe also prints the address of the buffer to help us.
In real life you might have to do a range of other things to work this out.
Compile the program with
gcc vulnerable.c -zexecstack -fno-stack-protector -g
Run the program several times with the same name as the input parameter:
./a.out rich
You should see the address of our name buffer change each time.
This is due to the default Linux stack memory randomisation. For our experimentation we can switch this off:
echo "0" > /proc/sys/kernel/randomize_va_space
This switches off the default ASLR protection in Linux. It is much harder to create a stable exploit with randomised
stack memory allocation... Run the program again to check the address of our name buffer is now stable.
Check the Program is Vulnerable
To check for a buffer overflow vunerability in the code, we can experimnet with sending large
buffers as input to the program. Try sending 40, 60, and 80 "A"s instead of rich as the parameter.
./a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
./a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
./a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
As expected the "name" buffer was overflowed and it seems like our Saved RIP, return instruction pointer
was too! Out exploit seems possible.
Identify Location of Saved RIP on Stack Frame
To create our buffer overflow exploit, we first need to locate the return
Instruction Pointer in our current Stack Frame, the Saved RIP of the calling function.
We could do this by experimenting with our "A"s, or using unique strings, but as we
have access to the code, we will use our previous method with the debugger and
analysis of the stack memory.
Run a.out with the gdb debugger, use "list" and find the line with the vulnerable "strcpy"
function on it, and set a breakpoint on that line. Now "run rich" (run the program
with argv[1] set to "rich"). Find the address of "name" (which is the buffer
we are going to overflow) and the adress of the "rip" saved instruction pointer for the
calling function, using your now familiar gdb commands. Using the previous method, calculate
the number of bytes between the "name" buffer and the return instruction pointer.
What is that offset in decimal?
Bytes to saved instruction pointer: