Lab: Stack-Based Buffer Overflows
In this lab, you will be learning about buffer overflows in the stack, a common vulnerability in programs that allows you to run arbitrary code. This lab will require some programming in C, some knowledge of assembly, and a touch of debugging tools.
1. Background
Stack-based buffer overflows have been around for a long time and all indications are that they will continue to be a problem in the near future. Aleph One wrote the definitive paper on using this technique to exploit programs, Smashing The Stack For Fun And Profit. You should read this paper carefully. It will walk you through every aspect of overflowing the buffer, creating a shellcode, and ultimately exploiting a vulnerable program. It is very long and full of technical detail -- make sure to set aside plenty of time to work through it.
Several strategies have been created to counter these types of bugs in programs. Fedora Core 4 (the version of Linux installed on your machine) employs two different kernel-based stack protection mechanisms. One randomizes stack addresses to make it difficult to predict locations of shellcode. The other places random canary values on the stack to protect stored addresses. You need to disable both of these mechanisms or else it will be difficult to exploit overflows on your system.
To disable stack protection, run the script (as root or through sudo)
/root/bin/disable-stack-protection. To re-enable stack protections, run
/root/bin/enable-stack-protection.. Note that if your system is ever rebooted, the
stack protections will be re-enabled by default.
2. Instructions
-
On your Linux machine, you will find a directory
/usr/local/netsec/lab1which contains three files. The Makefile will compile the C programsuppercase.candlowercase.c. Examine both programs and discuss within your team what possible security issues exist with them. -
Now, focus on
uppercase.c. This program takes a string in onargv[1]and prints out the same string with all ASCII lowercase characters changed to uppercase. Think about what would happen if a user provided a string longer than 512 bytes. Now, try it out. Run the program with a first argument that is much longer than 512 bytes. -
Use
gdbto run the program again with the same, very long, first argument (hint:set args AAAAAAA...). When you run the program and it finishes, record the%eipaddress reported when it segfaults. Compare this value to your string's ASCII hexadecimal representation (hint: man ascii). Now, repeatedly shorten/lengthen your string and re-runuppercaseingdbto determine the length of the shortest string needed to control%eip. -
Set a breakpoint at
main()and runuppercaseagain with your shortest (but%eip-controlling)argv[1]. Once the breakpoint is reached, find the address ofuppercase'sargv[1](hint: print&argv[1]). -
Write a new program in C which exploits this stack-based buffer overflow to execute a shell. Your exploit should embed a shellcode in the
argv[1]buffer ofuppercaseand then overwrite the stack frame return address so that execution continues within that buffer whenmain()returns. Note: sincebufwill get modified beforemain()returns, you won't be able to jump into that buffer.
The shellcode you need to use is:
char scode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89" "\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c" "\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff" "\xff\xff/bin/sh";
-
Once you have a working exploit which executes a shell, make
uppercasea setuid root program by runningchmod u+s uppercaseas root. Now, run your exploit again as a non-root user. Once your shellcode runs, use theid(1)command to determine what user the shell is executed as. If everything works correctly, you'll have elevated privileges to root through this overflow. -
Now take a look at
lowercase.c. Notice what happens toargv[1]before it is copied intobuf. If you try to exploit this overflow by placing your shellcode inargv[1], why won't it work? Think about other locations your shellcode could be stored instead ofargv[1]. -
Write a new exploit for
lowercasewhich does not embed the shellcode inbuforargv[1]. Instead, just repeatedly fillargv[1]with the address where your shellcode resides. There's at least two places inlowercase's address space where you can stuff your shellcode.
Report
For this lab, your team must submit a report with the following information:
-
Submit all exploits with every line commented to demonstrate you understand how the exploits work.
-
Submit a diagram of the stack for
uppercasewhich includes the stack frames formain()andstrcpy()and all local variables formain(). Also, include the location ofmain()'s return address and how it gets overwritten by an overflownbuf. Finally, includeargv[1]in the diagram as well, relative to the stack frames. Exact offsets aren't that important here, but relative locations are. -
How would you modify
uppercase.candlowercase.cto make them safe from buffer overflow attacks? Submit an answer to this question in the form a code diff of each program in the unified format. See the man page fordiff(1). Verify that your changes fixed the problem by running your exploits on the patched programs. -
If
bufwere instead allocated viamalloc(3)in these vulnerable programs, would the same techniques for exploitation work? Why or why not? -
What is different about executing a setuid program versus a non-setuid program? What are the dangers of setuid programs? Why are setuid programs sometimes necessary?
-
Find an advisory for a remote overflow vulnerability published within the last year on the web which has an associated, published exploit. The exploit must be in the form of source code, and should be designed to execute code on the remote system (you do not need to test this). In what scenarios can the vulnerability you found be exploited? Include links and references to an advisory on the vulnerability, the exploit itself, and any related information you find.
Grading
Your grade for this lab will be composed of:
25% - The source code of the exploits with appropriate comments.
25% - The stack diagram.
20% - The fixes for the vulnerabilities in both programs.
30% - The rest of the questions.