Overflowing the Return Address Example

This challenge requires you to enter a carefully crafted input file to the following program. The data should overwrite the return address with a binary value that will direct the program to execute the exploit() function.

/* The goal of this example is to provide the correct input so the program will overflow the stack and execute the function exploit( ). */
#include <iostream>
#include <fstream>
using namespace std;
ifstream inFile; // input data file
int i;

/* This is the function that generates the stack overflow */
void doit() {
char str[4]; // short input buffer

cout << "The address of str is " << hex << &str << endl;
i = 0;
while (!inFile.eof()) {
inFile.get(str[i]); // read from input file until EOF
i++;
}
cout << "The string you entered is:";
cout << str << endl;
}

/* The goal of the exploit is to execute this function. */
void exploit() {
cout << "\nExploit successful!\n\n";
}

/* Start of the program */
int main(int argc, char *argv[]) {
inFile.open(argv[1]); /* open the input file */
cout << "The address of function exploit is: " << hex << (void *)exploit << endl;
doit();
cout << "Normal end of the program\n";
return 0;
}

The source code for this program can be downloaded and a version in standard C is available.

Download the program and compile it with your favorite C or C++ compiler. The program reads input from a file whose name is given as the first command line value. Try running the program with a very short (4 characters or less) input file. To assist first time hackers, the program conveniently prints the memory addresses of useful locations. Use a debugger to look at the data on the program stack. Once you understand the format of the data and return address on the stack, create an input file that will overflow the str variable and change the return address in the doit function. You may wish to use a hex editor that will allow you to create a small file with specific binary values.

Hints:

· Intel CPUs are small endian machines. A four byte address is stored in reverse order with the least significant byte first at the lowest address.

· The stack on an Intel processor grows from high addresses to low addresses. When a value is pushed on the stack, it will be at a lower address than previous values on the stack.

· You may want to enter characters that have a useful binary ASCII code value.