University of Minnesota
Machine Architecture and Organization (sec 010)

CSCI 2021 lab 0x7

Buffer Overflow Attacks

This week's lab will focus on buffer overflow attacks. Essentially, you will be creating input for a function that causes the return address to be overwritten (as well as other internal variables).

This will also be the first lab in the online-only format. But if you're looking at these instructions, you're already finished the first step. Our first-choice recommendation is that you use Vole for the problems, though other CSE Labs machines should also work, and your own Linux machine should work too though some details may be different.

In place of talking to the TAs in person, use one of the Zoom teleconferences available from the Zoom section of the course Canvas page to talk with TAs. There should be several teleconferences available, one for each TA; you can choose randomly or move between them based on how busy they are.

Instead of a physical attendance sheet, you should register the fact that you participated in the lab by talking to one of the TAs at least once during the lab. This can happen either in the course of them answering a question, or near the end of the lab or after you've finished the activity you can show them the progress you've made. (You don't have to have made any specific level of progress for participating in the lab, but if the lab ends before you finish the assignment, you might ask the TA for advice the direction in which you can work on it more on your own.)

We didn't get a chance to talk in detail about buffer overflows in lecture, but they are covered in section 10.3 of the textbook, or in the last part of the lecture slides on "Machine-level advanced topics".

Completing The Lab

To get the files to use in lab, run the command:

cp /web/classes/Spring-2020/csci2021/labs/0x7/{Makefile,hex_echo.c} .

To compile hex_echo.c, we have provided a Makefile for you. Thus to compile, execute the command make in the terminal.

To see what hex_echo does run the executable hex_echo with the following value: 48656c6c6f20776f726c6421. Also, when looking at the C code you'll notice we added a function called overflow_target that is never actually called. It is your goal in this lab to get the overflow_target to run when calling hex_echo.

The first question in trying to complete this lab is to first figure out what you need to accomplish in order to get the overflow_target function to run. If you remember from the textbook or slides, functions can have vulnerabilities such as buffer overflows. This means that if your input is too large and you try to put it into a buffer that is too small, it starts to overwrite other parts of memory. In this case we will be trying to overwrite the part of memory that relates to the return address of hex_echo. The idea is that we can overwrite this value and instead of returning the normal value for the function, instead we overwrite it with the address to the overflow_target.

In order to do this we will use gdb and some new commands to investigate our function and see how it lays out in memory in order to acquire the information we need to overwrite the return address and have the overflow_target execute. (If you understand the principle of how buffer overflows work, it's also possible to create a working attack just by trying different locations for the overwrite blindly, but you'll learn more from figuring it out in detail.)

You can look back to previous labs or the lecture slides for reminders of useful GDB commands. Some particular commands that you may find useful in this lab will be:

info frame: shows information relate to the stack frame
p &variable: prints memory address of a variable in the code
p function_name: print the function (this will also give you an address)
dissass function_name: gives assembly of the given function
(Hint! You can also do arithmetic in print: i.e print 0x100-0x10)

From the command line, you can get the addresses of functions or globals variables inside the hex_echo program using the nm command, as in:
nm hex_echo | fgrep target

As a hint to get you going, the information you will need to find is the address of overflow_target and the size of your input. Think about what buffer you're overflowing, and where it is relative to other things in memory. And don't forget that x86-64 machines like Vole are little-endian..