Challenge 7: Stack Buffer Overflows

Introduction


A buffer overflow occurs when a program or process tries to store more data in a buffer (or some temporary data storage area) than that buffer was intended to hold. This extra data, which has to go somewhere, overflows adjacent memory regions, corrupting or overwriting the valid data stored there. If the buffer is stored on the stack, as it is the case for local variables in C, control information such as function return addresses can be altered. This allows the attacker to redirect the execution flow to arbitrary memory addresses. By injecting machine code into the process memory (e.g., as part of the data used to overflow the buffer, or in environment variables), the attacker can redirect the execution flow to this code and execute arbitrary machine instructions with the privileges of the running process. Thus, it is imperative that the length of the input data is checked before copied into buffers of fixed lengths. Unfortunately, a number of popular C functions (e.g., strcpy, strcat, sprintf, gets, or fgets) do not perform such length checks, making many applications vulnerable to this kind of attack.

Detailed Description


Your task is to exploit stack buffer overflow vulnerabilities in two programs that have their set-guid (i.e. set group identification) bit enabled. The programs are installed under /usr/local/bin/prog[7-8]. The source for the two programs can be obtained here:

You have successfully exploited a vulnerability in one of our two challenge programs when you are able to call /bin/grade with the effective group-id of the group that owns the vulnerable program (for our challenge, these are groups bsp[7-8]).

Hints


Performing a successful buffer overflow can be tricky, because it is important to get all the little details right. This section lists a few things that you might consider.

  • If you haven't written a buffer overflow before, check out the standard tutorial article by Aleph One. Everyone interested in security should have read this paper anyway.
  • Remember that the shell drops the effective user-id (as well as the effective group-id) when it is different from the real user-id (or group-id, respectively). This is the reason why standard shell code often contains a setuid(0) call. Consider this when spawning a shell.
  • Make sure that your shell code works correctly. That is, write a little test program that jumps to your shell code and make sure that it does what you want it to do before proceeding.
  • Use the debugger (/usr/bin/gdb) to see what is going on. The debugger is your best friend. Getting all the address right can be difficult. Note that you cannot debug the vulnerable programs directly, so you might want to compile your version of the vulnerable program and try to exploit it first.
  • Think about using a nop-sled. It makes exploitation easier if you don't get the addresses completely right.
  • To show the dynamic relocation entries of a program (GOT entries), you can use objdump -R on the binary. Check the man pages of objdump for more details.

Deliverables


To submit your challenge solution to us, you need to follow these steps:

  1. Create a file called challenge7.txt.
  2. Put the two codes that you have received from /bin/grade for the two programs that you have exploited (i.e., prog[7-8]) into this file, writing each code on a single line in that file and making sure the order is correct (first the code for prog7, then the code for prog8).
  3. In the directory where your file challenge7.txt is located, call /usr/local/bin/submit7
  4. Read any error or success messages. Then, wait a couple of minutes and read your e-mails on bandit to view the results of the automatic grading program.

Administrative Information and Deadline


This is an individual project. The project is due on Wednesday, 01.06.2011, 23:59:59 PST.