Main navigation | Main content
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".
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..