Blog Post

Flexible Binary Exploitation with Pwndocker

Jun 11, 2020
Click me

Recent Content

Whether you’re looking to create a custom exploit while pentesting a client environment or just working on a HackTheBox or PicoCTF Challenge, you may run into binary exploitation. Binary exploitation is the process of taking an existing application (binary) and manipulating the flow of instructions to execute arbitrary code of your choosing. This can result in reverse shells, exfil of data, or even privilege escalation.

Many protections have been added (ASLR, DEP, FlowGuard, etc) in an attempt to block this type of exploitation; however, we hackers and security researchers are crafty and most of the time find ways to exploit the binary, anyway. One of the difficulties in doing this is being able to create an environment that will accurately simulate the current customer or challenge environment enough to create a reliable exploit.
 
Below is the process I use when working on challenges like DreamDiaries, Rope, and Player2 on HackTheBox. Each of these require different versions of glibc to be exploitable and it’s not the best option to keep changing the libraries on my Linux development workstation. A better option is to leverage the power of docker and create a process where you can test any version of the libraries you need on the fly. I’ve outlined tools and process I’ve used with some success to create ROP chains and heap exploits allowing for reliable binary exploitation.
 

Tools

This is a docker image which has most of the tools needed for stack/heap exploit. The GitHub repo has great instructions which you should follow, but in the run script you'll see the "-v $(pwd)/${ctf_name}" option set which will link a local directory (in this case your current working directory and whatever name you give it) to the docker.
 
For example, I've created a pwndocker.sh script which contains the following:
 
docker run -d \
--rm \
-h pwn \
--name pwn \
-v /home/gridith/challenges/pwn/docker:/ctf/work \
-p 23946:23946 \
--cap-add=SYS_PTRACE \
skysider/pwndocker
 
For any boxes/challenges I'm working on, I make sure to create a subdirectory under /home/gridith/challenges/pwn/docker which will also be available inside the docker under /ctf/work.
 
Now that the environment is "spun up", how do you actually use it?. Well, the easiest way to work with this is to have two or three terminals into the docker and to modify any pwntools scripts to allow for gdb to work. To do this, I've created another bash script ( a simple one) called pwnshell.sh containing the following line:
 
docker exec -it pwn /bin/bash
 
All this one-liner does is jump you to the bash prompt on the Pwndocker container. I typically have two terminal windows up and run the script in each so that I have a pair of Pwndocker prompts available to me, one window for working on your pwntools script and the other for loading GDB.
 

Configuring The Docker

The docker contains a /glibc directory which contains most of the common glibc compiled bins. For example, if you need to work with 2.27, you can have your pwntools script reference:
 
/glibc/2.27/64/lib/ld-2.27.so
 
But be sure to follow the directions on the Pwndocker GitHub page. They show two ways to reference libc: one is by copying to a specific directory such as /tmp and the other is to use pwntools' ability to force load environments. Either way works, but don’t forget to patch the ELF binary if needed as well to make sure it’s using the proper libc.
 

Debugging

In one of your terminal windows run the tmux command (no parameters just tmux). In the other you will run your scripts. If you're using pwntools, I add this snippet to all of my scripts:
 
if args.GDB:
context.terminal = ['tmux', 'new-window']
heapEXE = process('./someELF')
debugger = gdb.attach(heapEXE, '''
break * 0x4011123
c
''')
 
Now when I run the script I add 'GDB' to the args to force gdb to open, set break points, and automatically continue:
 
dpython pwnHeapEXE.py GDB
 
Because tmux is running in the other terminal window, that is where GDB will load and auto attach to your process. You can step through and when you're ready quit GDB, make changes to your script and run again. Vi is not my editor of choice so I typically have a third terminal window open and with nano up editing my script as the docker doesn't contain nano.
 
This was a quick rundown to give you an idea of the setup I use for binary exploitation in the real world and on almost all of the HTB challenges/boxes that involve heap and stack popping. I hope this was helpful!
 
Keep an eye out for more binary exploitation posts to come, including a basic intro to stack overflows, a guide to heap exploitation, and tips for tools such as Ghidra, gdb, and Ida.
Duane Laflotte

Duane Laflotte

As CTO, Duane works to resolve complex technical issues for the team and its partners. He can be found at the bleeding edge of emerging technology and believes that continually feeding curiosity results in prolonged growth and creative solutions to complicated challenges. Duane is an expert technologist in the areas of cryptography, exploit development, networking, programming, and enterprise data storage. As an industry leader, Duane has worked with a wide array of Fortune 500, government, and military organizations - such as Disney, Bank of America, the FBI, SOCOM, DARPA, and the NHL – as a solutions architect, red team lead, and presales engineer. Duane is a highly accomplished engineer who has achieved expert-level certification as an Offensive Security Certified Expert (OSCE) among other credentials such as Offensive Security Certified Professional (OSCP), GIAC Exploit Researcher & Advanced Penetration Tester (GXPN), Certified Ethical Hacker (CEH), Microsoft Certified Professional, and Microsoft Technology Associate. Duane is an active FIRST Robotics volunteer and has coached teams which have earned the prestigious Chairman's Award.