Assignment: UAF

Changelog:

Your Task

  1. Download the two versions of a vulnerable (uafA.exe and uafB.exe) and their source code (uafA.cc and uafB.cc)

    (For conveience, we also provide objdump output on uafA and uafB.)

  2. Start with the “uafA” version of the program, which is much simpler. Submit a file called uafA-attack.py3 such that running

    python3 uafA-attack.py3 > commands.txt
    ./uafA.exe < commands.txt
    

    (or submit a similar file named uafA-attack.py2 or uafA-attack.cc, etc., which we will run similarly to prior assignmnets, depending ont he type of file) will produce output that ends with

    I recommend YOUR-COMPUTING-ID get a grade of A for the UAF assignment.
    > Exiting.
    

    (We do not care about other output the program produces.)

    Your exploit must work on the executable version of the programs we supply, not any slightly different executable you produce.

  3. do the same thing for the “uafB.exe” version of the program.

About the programs / Hints

  1. Both of these programs prompt for commands and making help gives a list of commands:

    > help
    Available commands:
      setup-info
      set-info-0 STRING
      set-info-1 STRING
      set-info-2 STRING
      free-info
      setup-grader ASSIGNMENT
      grade STUDENT
      free-grader
      exit
    

    The grader commands can be used as follows:

    > setup-grader UAF
    (grader address 0x1234567)
    > grade mst3k
    I recommend mst3k get a grade of F for the UAF assignment.
    

    (The output will vary slightly between uafA and uafB)

    Your job is to supply input to setup the grader, so that you can run the commands “grade YOUR-COMPUTING-ID” then “exit”, and the last lines of output from the program will be:

    I recommend YOUR-COMPUTING-ID get a grade of A for the UAF assignment.
    > Exiting.
    

    (The last line is a normal prompt for the exit command followed by its output.)

  2. The programs implement the commands above using an InfoTracker class and a Grader class. The Grader class is an abstract superclass which is implemented by the GraderImpl subclass.

    The setup-info and setup-grader commands create new instances of these classes and store pointers to them in global variables. The free-info and free-grader commands delete these instances, but do not reset the pointers.

  3. The setup-info and setup-grader commands show the addresses of the InfoTracker and Grader objects they create to make it easier for you to determine whether they were allocated in the same address. (On a less cooperative program, one might use a debugger to determine this.)

  4. The programs have a use-after-free vulnerability which provides an attacker substantial control. One example of how this can be triggered to cause a crash is as follows:

    > setup-info
    (info address XXX)
    > free-info
    > setup-grader UAF
    (grader address XXX)
    > set-info-0 XXX
    info[0]: "XXX
    > grade foo
    

    This will result in a segmentation fault. What happens is that the struct used by the info tracker has been freed but there’s still a pointer to it that the set-info-NUMBER command tries to use.

    In the code, you will see that the pointer to the info object is stored in a global variable called info_tracker and the pointer to the grader object is stored in a global variable called grader. (The output info[0]: "XXX is showing that the value of info slot 0 is XXX after being set. Yes, the program inadvertantly does not include a closing " in the output.)

    Since the object for grading was allocated to the same place, set-info-NUMBER can overwrite information used by the grade function. This happens to include the virtual table pointer. The grade command tries to use this virtual table pointer to find a function to output the grade, and because it’s corrupted (by writing XXX there), it fails.

  5. You can use this use-after-free vulnerability to make the programs produce the desired output.

  6. In the case of uafA, you can change the information used by the normal grade-outputting function.

  7. In the case of uafB, you will probably need to take advantage of changing the VTable in use. Since the executable we supply does not make writable regions of memory executable, you should expect to look for existing code that would make sense to jump to.

  8. If you get a buffer overflow detected message from sprintf in print_escaped, this is because the code does not handle bytes whose values is negative (when treated as signed). You do not need to input such bytes to successfully complete an attack of uafA or uafB.

  9. To help read the objdump output, you can use the program c++filt to decode C++ method names. (For example: _Z13read_argumentiPc is read_argument(int, char*).) The objdump output we supply has already been processeed with this tool.