#55 Challenge - Buffer Overflow

Credits: Computer Systems: A Programmer's Perspective
Authors: Randal E. Bryant and David R. O'Hallaron
Samples of book: http://csapp.cs.cmu.edu/public/manuscript.html
Disclaimer: I have written permission from the author to post his labs on my site.

Solution: posted here

Your job is to carefully construct a string that when entered in as user input will cause the program to execute a function that it was not intented to execute.

You will need to look at the disassembly to see how you should construct your string. You will find the linux program: objdump useful.



unix> objdump -d bufbomb > bufbomb.disassembly


Further instructions are below. You can download the files you need for this challenge here: bufferOverflow.tar.gz The function getbuf is called within bufbomb by a function test having the following C code:



      void test()


      {


          int val;


          volatile int local = 0xdeadbeef;


          val = getbuf();


          /* Check for corrupted stack */


          if (local != 0xdeadbeef) {


              printf("Sabotaged!: the stack has been corrupted\n");


          }


          else if (val == cookie) {


              printf("Boom!: getbuf returned 0x%x\n", val);


              validate(3);


          }


          else {


              printf("Dud: getbuf returned 0x%x\n", val);


          }


      }


  


When getbuf executes its return statement (line 5 of getbuf), the program ordinarily resumes execution within function test (at line 8 of this function). Within the bufbomb, there is a function smoke having the following C code:



    void smoke()


    {


        entry_check(0); /* Make sure entered this function properly */


        printf("Smoke!: You called smoke()\n");


        validate(0);


        exit(0);


    }


  

Your task is to get bufbomb to execute the code for smoke when getbuf executes its return statement, rather than returning to test. You can do this by supplying an exploit string that overwrites the stored return pointer in the stack frame for getbuf with the address of the first instruction in smoke. Note that your exploit string may also corrupt other parts of the stack state, but this will not cause a problem, since smoke causes the program to exit directly.

The bufbomb program reads a string from standard input with a function getbuf having the following C code:



  int getbuf()


  {


      char buf[12];


      Gets(buf);


      return 1;


  }


The function Gets is similar to the standard library function gets. It reads a string from standard input (terminated by ‘\n’ or end-of-file) and stores it (along with a null terminator) at the specified destination. In this code, the destination is an array buf having sufficient space for 12 characters.

Neither Gets nor gets has any way to determine whether there is enough space at the destination to store the entire string. Instead, they simply copy the entire string, possibly overrunning the bounds of the storage allocated at the destination.

If the string typed by the user to getbuf is no more than 11 characters long, it is clear that getbuf will return 1, as shown by the following execution example:



  unix> bufbomb


  Type string:  howdy doody


  Dud: getbuf returned 0x1


If we type a longer string, typically an error occurs:



  unix> bufbomb


  Type string: This string is too long


  Ouch!: You caused a segmentation fault!


As the error message indicates, overrunning the buffer typically causes the program state to be corrupted, leading to a memory access error. Your task is to be more clever with the strings you feed bufbomb so that it does more interesting things. These are called exploit strings.

Your exploit strings will typically contain byte values that do not correspond to the ASCII values for printing characters. The program sendstring can help you generate these raw strings. It takes as input a hex-formatted string. In this format, each byte value is represented by two hex digits. For example, the string “012345” could be entered in hex format as “30 31 32 33 34 35” since the ASCII code for decimal digit 0 is 0x30 and so forth. Non-hex digit characters are ignored, including the blanks in the example shown.

If you place a hex-formatted exploit string in the file exploit.txt, you can apply the raw string to bufbomb in at least two different ways:

1. You can set up a series of pipes to pass the string through sendstring.



        unix> cat exploit.txt | sendstring | bufbomb -t bob


2. You can store the raw string in a file and use I/O redirection to supply it to bufbomb:



        unix> sendstring < exploit.txt > exploit-raw.txt


        unix> bufbomb -t bovik < exploit-raw.txt


This second approach can also be used when running bufbomb from within gdb:



  unix> gdb /home/user/bufbomb


  (gdb) run -t bob < exploit-raw.txt


One important point: your exploit string must not contain byte value 0x0A at any intermediate position, since this is the ASCII code for newline (‘\n’). When Gets encounters this byte, it will assume you intended to terminate the string. Sendstring will warn you if it encounters this byte value. That's about it.