/* * breakme.c * * **** This has a *bad* bug ... * **** it's only for stack crash demo purposes. * * man gets: "never use gets ... use fgets() instead" * OK, I'll use fgets ... but with the wrong buffer size. :( * * Your mission : use a stack overflow attack to * get this to print "The magic word!!!" ... but without typing "magick", * and without running it in the debugger ... just with some "bad" input. * * The idea is to provide input which overflows the buffer in just * the right way so as to overwrite the return address to a different * one of your choice, making the running program do something other * than what it is supposed to do. * * This is a contrived example, but illustrates this type of exploit. * (Quick quiz: why is it interesting to do this without gdb?) * * You'll need to compile this without the stack canary : * * $ gcc -fno-stack-protector breakme.c -o breakme * * on shannon : * * $ ./breakme * What is the magic word? foo * That is not the magic word. * $ ./breakme * What is the magic word? magick * The magic word!!!. * $ ./breakme * What is the magic word? 123456789012345 * That is not the magic word. * $ ./breakme * What is the magic word? 123456789012345678901234567890 * That is not the magic word. * $ ./breakme * What is the magic word? 123456789012345678901234567890123456789012345678901234567890 * Segmentation fault * * Now ... what might the input be to crash the stack in a more clever way? * * Jim Mahoney | cs.marlboro.college | Nov 2018 | MIT License */ #include #include #include int is_magic(char* input){ /* return 1 if the input is the magic word. */ char magic_word[] = "magick\n"; return ! strcmp(magic_word, input); } void print_is_not_magic(){ printf("That is not the magic word.\n"); } void print_is_magic(){ printf("The magic word!!!.\n"); } char* read_word(){ /* read from stdin, return char* of input including trailing newline */ char buffer[16]; char* result; char* word; size_t n; result = fgets(buffer, 1024, stdin); n = strlen(buffer); // --- location of print_is_magic --- //printf(" --- debug -- print_is_magic = 0x%p \n", print_is_magic); // --- fgets behavior debugging --- // printf(" -- debug -- n is %lu\n", n); // printf(" -- debug -- buffer is '%s'\n", buffer); // printf(" -- debug -- result is '%s'\n", result); // int i; // for (i=0; i<(n+1); i++){ // printf(" -- debug -- buffer[%d] = 0x%02x = '%c' \n", // i, buffer[i], buffer[i]); // } // -------------------------------- word = malloc(n); strcpy(word, buffer); return word; } int main(){ char* word; printf("What is the magic word? "); word = read_word(); if (is_magic(word)){ print_is_magic(); } else { print_is_not_magic(); } return 0; }