Project 1: Memory Safety
Due: 2026-03-01 at 23:59
Goal
The goal of this assignment is to gain hands-on experience with the effect of buffer overflows and other memory-safety bugs.
All work in this project must be done in the QEMU virtual machine available here; see below for information about this environment.
You are given a Python script generate_targets.py which, when run, will generate six vulnerable targets in a targets directory. The targets will be generated from an ID file that you must first fill out. See below for details.
These programs are to be compiled and installed, setuid root, in the /targets directory of your VM. After you run generate_targets.py, the created targets directory will contain a Makefile. You can build the target programs by running make in that directory. You can install the targets in the /targets directory by running make install.
Your goal is to write six exploit programs exploit1.py, …, exploit6.py, each of which will execute the corresponding target with input that exploits that target’s bug, giving a root shell on the VM.
I have provided skeletons for these exploits programs in the exploits directory. My own solutions, incidentally, are very short: fewer than 50 lines each. So while understanding and exploiting the bugs will not be easy, you will not need to write a lot of code.
Collaboration
You may work on this project in groups of up to 3, although I recommend groups of size 2.
You must not discuss solutions to the project with anyone other than your partners and course staff. You may use online resources for general reference, but not to search for solutions to specific questions posed in this project.
AI
Don’t use generative AI tools for any portion of the project, including identifying the vulnerabilities. Finding the vulnerabilities yourselves is a key part of this project.
The Environment
You (and I, for grading) will run your exploit programs within a QEMU virtual machine. This virtual machine emulates a 64-bit x86 processor and has the latest version of Debian installed.
You should first install QEMU. (Select the appropriate operating system, don’t build it from source.)
Next, download and decompress sandbox-4.0.tar.xz, if you have not already done so.
Inside the sandbox-4.0 directory, you’ll find a script start.sh. Running that script will boot the VM. Read the README.md in the directory for details. If you’re using Windows, you’re on your own in terms of running the VM. Presumably you can create a PowerShell script to run qemu-system-x86_64 with the appropriate options. (If you do do this, I’d love to see the script and add it to the sandbox for the next time this course is taught.)
You will need to configure Git inside the VM.
$ git config --global user.name "Your name here"
$ git config --global user.email "Your email here"
You’re now ready to clone the assignment repository.
The VM has a number of tools installed including the gcc compiler and gdb debugger. It has vim, emacs, and neovim installed. If you want to install additional tools such as other text editors, you may install them using sudo apt install ....
The password for user is user and the password for root is root. You should do your work as user.
The Assignment Repository
Go to the GitHub Classroom page and accept the assignment.
- If you are working by yourself, create a new team (you can name it whatever you like).
- If you are working with partners (which I recommend), one of you should create a new team and the other should join the team.
Warning: Do not join any team other than your partner’s. There’s no way to change teams for the assignment so just don’t do it! (If you do join the wrong team by mistake, let me know immediately.)
You should now be able to clone the assignment repository in your VM using the gh command line tool (or via git directly although that’s less convenient).
The Targets
Once you have cloned your assignment repository in the VM, you need to enter your name and your partners’ names in the ID file. If you’re working with partners, one of you should edit the ID file, commit it, and push it to GitHub. The other partner should git pull the change.
After you have done this, run
to generate the targets directory.
WARNING: Once you have generated the targets directory, any changes to your ID file at all will cause the generate_targets.py script to generate different targets and your exploits will likely not work when we’re grading.
The targets directory contains the source code for the targets along with a Makefile specifying how they are to be built. To compile the targets and install them setuid root in /targets, use the commands make and make install. You will need to enter the password user at the prompt when you run make install.
target5 is fairly complicated. It reads commands for manipulating strings from the file specified as its argument. Due to the way target5 is compiled, the glibc malloc/free/realloc functions are not used. Instead, the replacement functions in smalloc.c are called. You should be able to set breakpoints inside those functions in the debugger as normal.
Do not commit the targets directory. For grading, I will run the generate_targets.py script and run your exploits against those targets.
The Exploits
The exploits directory in the assignment contains skeleton source for the exploits which you are to write.
Your exploits should assume that the compiled target programs are installed in /targets—/targets/target1, …, /targets/target6.
The Assignment
You are to write exploits, one per target. Each exploit, when run in the virtual machine with its target installed setuid-root in /targets, should yield a root shell (/bin/sh).
In addition to the exploits, you should edit the writeup.md file and explain for each target that you exploit,
- what the vulnerability is;
- what technique you used to exploit the vulnerability; and
- how you used that technique to exploit the vulnerability.
Hints
- Read Aleph One’s “Smashing the Stack for Fun and Profit,” carefully! Also, read the “suggested reading” listed in the project
README.md. You will want to have a good understanding of what happens to the stack, program counter, and relevant registers before and after a function call. Read scut’s “Exploiting Format String Vulnerabilities.” It will be helpful to have a solid understanding of the basic buffer overflow exploits before reading the more advanced exploit papers. - The GDB debugger is your best friend in this assignment as you’ll want to understand what’s going on in the target program’s memory space. Specifically, note the
disassemble, stepi, and nexti commands. You may find the x command useful to examine memory (and the different ways you can print the contents such as /a or /i after x). The info register command is helpful for printing out the contents of registers. A useful way to run GDB is to use the -e and -s command line flags; for example, the command
gdb -e python3 -s /targets/target3
tells GDB to execute python3 and use the symbols from target3. Once GDB has started, you can use the GDB command run exploit3.py to run your exploit. This allows you to trace execution in the target in exactly the way it is executed by the exploit. By contrast, executing just gdb /targets/target3 will trace the target in the way it is executed by the shell, so the memory layout will be different. (Avoiding a segfault while using this requires careful timing in setting breakpoints. See the assignment README.md for the details.)
- One of the projects is very constrained in what arguments can be passed to it and you may have trouble running code on the heap (i.e., memory allocated by
malloc). Try placing the shellcode somewhere else. - Make sure that your exploits work within the provided virtual machine.
- Start early! Theoretical knowledge of exploits does not readily translate into the ability to write working exploits. The first target is relatively simple to exploit, but the difficulty ramps up from there.
Warnings
Aleph One gives code that calculates addresses on the target’s stack based on addresses on the exploit program’s stack. Since your exploits are written in Python, you don’t have access to this information. This is good since you shouldn’t rely on it anyway.
You must, therefore, hard-code target stack locations in your exploits. You should not use a function such as get_sp in the exploits you hand in.
Deliverables
- You will submit by committing your code and pushing to GitHub.
- Make sure you’ve explained how everything works in the
writeup.md file. Feel free to use Markdown formatting. - Finally, you must include the file
ID which contains the names of all partners (or just your own if you worked by yourself). Heed the warning about changing ID above!