For this assignment, you are to solve the “bufoverflow” labtainer exercise, and submit both a lab report and the labtainer zip file. There is no template provided for the report, but you should carefully and clearly document what you did, what you saw, and what you learned for each of the four tasks. This should be a proper lab report, including an introduction and conclusion – don’t just type up raw observations. As an example of the level of detail that is expected, see the sample report. The report should be typed, saved as a PDF, and submitted in Canvas.
While this is just a single labtainer exercise, be aware that it is very detail-oriented, and you must figure out the details and get them exactly right in order for this to work. Here is some additional information and hints/tips:
Make sure you read through the lab all the way before you start. In particular, the final sections provide important information that you’ll need in order to solve the tasks. These sections talk about memory layout of a process and call stack (which we will also discuss in class), and the section on “Storing a long integer in a buffer” has information on how to set a word in your exploit output to a specific 32-bit value.
Task 1 (Section 2.4) is the hardest part. While the lab write-up talks about compiling “stack.c” you should not have to do this for Task 1 as a pre-compiled setuid-root binary is provided in the labtainer. You can of course compile your own custom versions of stack.c in order to examine various aspects of the code, but that is optional.
Task 2 requires patience. If you solved task 1 correctly, then this attack will eventually succeed, although it might take thousands of attempts and a long running time. The lab write-up has a vague statement that you “can modify your exploit program to increase the probability of success” but doesn’t give any details. If you want to try this, have the program print out information on the vulnerable buffer address and try to figure out some information on the distribution of the random placements. In particular, you’ll notice that the “non-randomized target address” from Task 1 is on the far end of that distribution of addresses. A better choice might be something closer to the middle of that range!
Despite what the lab write-up says, you can use gdb with a setuid program - the system will disable the setuid bit, so the program will run as your regular (unprivileged) user, but you can debug, single step, and examine memory just fine without having to make a copy. Also note that setuid root programs running natively and with the setuid bit disabled in the debugger will have slightly different addresses for the stack. As long as you have enough flexibility in your jump address calculation, this shouldn’t matter.
The buffer sizes are different for each student, so the code will not exactly match the code and sizes in the lab instructions/write-up. Do not modify the sizes in your programs (use your values, not the ones in the write-up)! You’ll need to keep this in mind while reading the lab write-up so that you don’t get confused by the different sizes.
We will demonstrate and discuss several useful gdb commands in class, and will give some tricks for working with gdb to find the values that you need to perform this exploit. If you miss class, make sure you check the recording! If you want a very basic and very quick introduction to the basic gdb concept, there is a (completely optional) “gdblesson” labtainer exercise that you can do.