If you’ve ever compiled an exploit on your computer, and then tried to run it on an older machine, you may have encountered an error like the following:
/lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.34' not found
This error occurs because the glibc
version on the computer you compiled the exploit with is newer than, and not backwards compatible with, the version found on the target machine. When compiling an exploit, it’s better to replicate the target machine environment than to compile on the target machine, especially because the target machine may not have gcc
. In this post I will show you how to create a minimal Debian-based container for the purpose of compiling the exploit, so that it may be executed successfully on the target machine.
This post assumes you’re using a Debian-based Linux distribution.
debootstrap
is a tool that allows you to create a full minimal Debian installation which can be used for various purposes such as compiling an exploit. systemd-nspawn
may be used to run a light-weight container.
Install these tools with the following command:
sudo apt install debootstrap systemd-container
Now it’s time to make a directory to store the files that debootstrap
will retrieve. You can name the directory whatever you’d like, however it must be a sub-directory of /var/lib/machines/
. In my case, I named it exploit
:
sudo mkdir -p /var/lib/machines/exploit
This step is optional, but recommended. Make the directory accessible by only the root user:
sudo chown root:root /var/lib/machines
sudo chmod 700 /var/lib/machines
Now it’s time to retrieve the necessary files to run a minimal Debian-based container to compile the exploit. Ideally, you will want to use the same operating system as the target machine, but usually an old enough version will do. In my case, I will create a minimal Ubuntu 16.04 LTS (Xenial Xerus) container:
sudo debootstrap --variant=buildd xenial /var/lib/machines/exploit
This command will install a minimal Ubuntu
distribution along with the build-essential packages required to compile the exploit in the directory /var/lib/machines/exploit/
. Remember to replace the directory name exploit
with whatever name you chose.
To spawn the container, run:
sudo systemd-nspawn -M exploit
Again, replace exploit
with whatever name you chose. At this point you should have a root shell in the home directory of the root user of your container.
To remove the container, use the following command:
sudo machinectl remove exploit
exploit
here should be the name of the container you’d like to remove.
To finish up, I will give an example of how to use this container to compile an exploit. I’ll compile an example exploit for the CVE-2016-5195 Linux kernel privilege escalation vulnerability, also known as Dirty COW. Download the exploit here.
On my host machine (not the container), I will login as the root user:
sudo su
Then change directories to the root user’s home directory of my container:
cd /var/lib/machines/exploit/root
Replace exploit
with whatever name you chose for your container. Now I will clone the Git repository for the exploit:
git clone https://github.com/firefart/dirtycow
At this point it’s time to spawn the container and compile the exploit. Run the following command to spawn the container:
systemd-nspawn -M exploit
Replace exploit
with the name that you chose. You should now have a shell as the root user inside your container. You should be in the root user’s home directory. I will change directories to the directory containing the exploit source files:
cd dirtycow
Now you simply need to compile the exploit. In this case, I will use the following command to compile the exploit:
gcc -pthread dirty.c -o dirty -lcrypt
Note that the command may be different if you’re using a different exploit. Now I have an executable file called dirty
. All I have to do now is transfer the file to the target machine and execute it.