In Level 3 of the Smash The Stack IO wargame, passing a large argument quickly causes a segmentation fault:
level3@io:/levels$ ./level03 $(python -c "print 'A' * 1000") Segmentation fault Analyzing the Source Code The source file level03.c is provided in /levels:
#include <stdio.h> #include <string.h> #include <unistd.h> void good() { puts("Win."); execl("/bin/sh", "sh", NULL); } void bad() { printf("I'm so sorry, you're at %p and you want to be at %p\n", bad, good); } int main(int argc, char **argv, char **envp) { void (*functionpointer)(void) = bad; char buffer[50]; if (argc != 2 || strlen(argv[1]) < 4) return 0; memcpy(buffer, argv[1], strlen(argv[1])); memset(buffer, 0, strlen(argv[1]) - 4); printf("This is exciting we're going to %p\n", functionpointer); functionpointer(); return 0; } Vulnerability Analysis Target Function: good() spawns a privileged shell via execl("/bin/sh", ...). Buffer and Function Pointer: main() allocates a 50-byte buffer (char buffer[50]) and initializes a function pointer pointing to bad(). Unbounded Copy: memcpy(buffer, argv[1], strlen(argv[1])) copies the entire input into buffer without checking against its 50-byte bound. Partial Clear: memset(buffer, 0, strlen(argv[1]) - 4) zeroes out buffer up to strlen(argv[1]) - 4. The last 4 bytes of our input remain untouched in memory. Execution: The program invokes functionpointer(). If we overflow buffer such that the trailing 4 bytes align precisely over functionpointer, we redirect execution to good(). Finding Addresses and Offset in GDB Disassemble and locate the address of good():
...