Exploiting Binaries 1
Binary exploitation is the process of subverting a compiled application such that it violates some trust boundary in a way that is advantageous to you, the attacker. In this module we are going to focus on memory corruption. By abusing vulnerabilities that corrupt memory in software we can often rewrite critical application state information in a way that allows us to elevate privileges inside the context of a particular application (like a remote desktop server) or perform arbitrary computation by hijacking control flow and running code of our choosing.
If you’re trying to find bugs in compiled C programs, it’s important to know what you’re looking for. Start with identifying where the data you send to the program is used. If your data is stored in a buffer, take note of the sizes of them. Programming in C without errors is very difficult and the CERT C Coding Standard catalogues many of the ways that errors can come about. Paying attention to commonly misused APIs can be a quick path to success.
Once a vulnerability is identified it should be used to compromise the integrity of the program, however, there are a variety of ways to achieve this goal. For programs such as web servers, obtaining the information from another user may be the end goal. In others, changing your permissions may be helpful, for example changing the permissions of a local user to the administrator.
Lecture
The first lecture, Memory Corruption 101, provides background and step-by-step explanation of exploiting an overflow on Windows. The second lecture, Memory Corruption 102, covers more advanced topics, including web browser exploitation. Both of these lectures use Windows-specific examples but the techniques and process are applicable across operating systems that use the x86 instruction set. Remember that the names of functions and sometimes the calling conventions will be different when you are working with UNIX/Linux binaries.
Tools
We recommend using GDB to debug the challenges in this module since all of them are compiled for 32-bit Linux, however, GDB is intended for debugging source code, not stripped binaries without symbols and debugging information. Projects such as GEF, peda, and voltron are attempts at making gdb more useful for debugging when source code is not available. We recommend making a .gdbinit
file in your home directory with at least the following commands:
set disassembly-flavor intel
set follow-fork-mode child
Workshop
In order to run these challenges, you’ll need to setup an Ubuntu 14.04 (32-bit) virtual machine. We recommend using VMware Player, since it’s free and well supported. When you have it running, open a terminal and install socat
with command sudo apt-get install socat
.
There are three challenges in this workshop, each contained within this folder when you clone this repository in git. The ultimate goal of each challenge is to manipulate the executable into reading the flag to you. For each challenge, try to translate the disassembly into C code. After making an attempt, you can verify your guess by checking the actual C source provided. Then, try to exploit it to read you the flag.
Challenge: Easy
Make sure the flag is in the same directory as the easy
program. Once you execute easy
it will listen for instructions on port 12346
.
Challenge: Social
Similar to easy, make sure the flag and host.sh
are in the same directory as social
program. Once you execute social
it will listen for instructions on port 12347
.