Due Date: May 3rd, 2007.
In this assignment, you will configure an attack program to compromise a buffer overflow vulnerability in a victim program. The victim program is instrumented to provide traces that will be helpful in determining how to leverage that vulnerability. Your task will be to modify the attack program, based on the victim traces, to overflow the buffer and start a shell program.
Note that this buffer overflow is 32-bit, x86-specific, so you must use such a machine. You can do this assignment in your Playpen (that is where I did mine), and that is where we will test it. You will need to test it there too.
In theory, this project could be done very quickly, so if you get stuck please seek help from us. There are some ad hoc materials online, but these may not help too much. This is not a recommendation to wait to the last minute, but to not slog on your own for too long.
Follow these instructions:
Get the project tarball from here. The project tarball contains: (1) a
victim program, cse497b-victim.c, which contains
a buffer overflow vulnerability and (2) an attack program,
cse497b-attack.c, which contains code to leverage
buffer overflow vulnerabilities in victims.
Unpack the tarfile on an x86 32-bit machine (Playpen). We will test on the Playpen, so it would probably be best to use you Playpen.
Two modifications to the attack program are necessary: (1) specify the stack offset between the vulnerable buffer and the return address of the victim (both are on the stack) and (2) the new return address for the running a shell on the victim. These are specified as variables in the attack program (see variables with "= fill in"). You just need to set those values in the attack program successfully to complete the assignment.
To determine the stack offset, build the victim program
(make victim). The victim program takes a sequence of
strings and concatenates them into a buffer (our target) that is
allocated on the stack. The victim also contains instrumentation to
print the buffer address (and others see below) and the stack of the
function with the vulnerable buffer buf (the function
is also called victim). From this information, you can
see where the buffer is allocated. The return address is also in
the stack trace, but you need to locate it. Assign the distance in
bytes between the start of the buffer and the start of the return
address in the variable rtn_addr_distance in
cse497b-attack.c. Hint:
The return address is an address inside the function that calls
the victim function (i.e., main calls
victim).
To determine the new return address (i.e., to run our attack
code), we need locate the code we want to run in the victim
(./victim foo bar). In this case, we are going to jump
to some code in the victim program. The function shell
in the victim opens a shell. Our exploit must call the
shell function which executes a shell.
To find the address of the shell function and
enable the attack program's exploit to jump to this address, we need
to:
Build an assembler version of the victim program,
victim.s, using make victim.s.
Find the assembler call shell in the victim
and add a new line to the assembler before this call to add a
label: JMP_ADDR:.
Also, change the tag for $shell in an
instruction in the victim function. This instruction follows a
printf. Change the tag from $shell to
$JMP_ADDR. This will print the address of the
JMP_ADDR label -- this is the return address we need
to invoke the shell function.
Build the assembler version of victim, using make
victim-label. This will be a different binary than victim.
Note that the attack code executes victim-label not
victim.
Run the ./victim-label foo bar and record the
value of shell printed by execution (i.e.,
&shell). There are 4 return address parameters in
the attack program (rtn1 to rtn4). Note
that the x86 is little-endian, so the highest address char goes in
rtn4 and the lowest in rtn1. For
example, for the address 0x80488ef, the values would assigned: (1)
rtn1 = 0xef;; (2) rtn2 = 0x88;; (3)
rtn3 = 0x4;; and (4) rtn4 = 0x8;. Note
that these are hex values.
Build the attack program (make attack), and
run it (./attack) to launch the attack against the
victim (actually victim-label). The result should be
that you open a new shell. You should be able to perform shell
commands (e.g., ls). You can exit the shell to
terminate the program. If you get a usable shell do not worry
about any subsequent segmentation fault after you exit. However,
an error will be cause a segmentation fault without opening a
shell.
When you have completed the buffer overflow code, email it to the course professor by 5:00pm on the 3rd. Make sure that you have tested it in your Playpen prior to submission. We will build and run your attack (which launches the victim) to verify it. Failure to build either program may result in a failing grade for this assignment.
All the information that you need should be available via these instructions and the project slides. Let the instructor or TA know of any other questions.
You are to complete this on your own. Any sharing of code or help during the coding of this project is expressly forbidden. Do not discuss this project with anyone.