/* * grade.c * * by Aaron Bloomfield, 2018. This is part of the aaronbloomfield/ics * github repository, and is released under the same license (CC * BY-SA) as that entire repo. * * This program is designed to be vulnerable to a shellcode-based * buffer overflow. Students must have it print a grade other than an * F to receive any credit. * * To run it, be sure to invoke `setarch x86_64 -v -LR bash` first */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> // used to indicate if we are printing the buffer address int print_buffer_address = 0; // we use this to pass the name back from the vulnerable() function to // main() char global_name[100]; // the vulnerable function void vulnerable() { char name[200]; if ( print_buffer_address ) { unsigned long addr = (unsigned long) name + 0x20; printf("%lx\n",addr); exit(0); } else { printf ("Please enter your name:\n"); fgets (name, 1000000, stdin); strncpy (global_name, name, 199); // look, ma, no buffer overflow possible here! } return; // not necessary, but useful to set a breakpoint at grade.c:38 } void main(int argc, char *argv[]) { if ( (argc == 2) && (!strcmp(argv[1],"--print-buffer-address")) ) print_buffer_address = 1; // we use this to help find the address of the stack in the next command int on_stack; // we set the stack to allow execution; it already allows reading // and writing mprotect((char *)((long)&on_stack & -0x1000), 1, PROT_READ | PROT_WRITE | PROT_EXEC); // we set the executable code (the .text section) to be writable; it // already allws reading and execution mprotect((char *)((long)&main & -0x1000), 1, PROT_READ | PROT_WRITE | PROT_EXEC); // call the vulnerable function vulnerable(); // remove trailing newline global_name[strlen(global_name)-1] = 0; // print the grade printf ("\n%s, your grade on this assignment is a F\n", global_name); }