This post presents a practical approach to performing a MiTM (Man-in-The-Middle) attack against a version of APT (Advanced Packet Tool) used until recently by Debian 7 (which just reached its EOL back in May 2018). During a recent Device Security Assessment engagement, we found this Linux distribution being used and therefore performed this attack aimed at deceiving a victim into installing a specially modified (backdoored) software package to obtain remote access to the system as root.
Old versions of APT download repository meta-data information and packages use an insecure HTTP channel, and when the Release.gpg signature file is not found, it just shows a warning message to the user alerting of the dangerous situation, giving her/him with the possibility of accepting and continuing with the process. If that by itself is considered dangerous enough, when combined with the –force-yes command line switch of the apt-get tool, something we observed to be used by the Web Management interface of the analyzed device, could make things easier for an attacker.
Although this is not a new attack, when we were working on this PoC for the engagement, we did not come across any blog post or other online resource that condensed and detailed the entire process of exploitation for such a vulnerability, so we thought it would be a good idea to share our experience with others as a reference for similar setups.
During a penetration test performed on a networking device, we observed it was based on a Debian Linux version 7.10 that has just reached its End-Of-Life in May 2018.
This appliance was particularly interesting because it was thought to be entirely managed via a Web GUI by an administrator (think of this interface as a Webmin tool alternative). Therefore, all the configuration parameters and actions should be modified and performed respectively via the provided interface rather than using the OS command line.
In other words, to perform an upgrade of the operating system outdated packages, the administrator should go through the Update Manager functionality to make it obtain a list of new packages and then accept whether to install them or not. This functionality launches the apt-get update, apt-get upgrade and apt-get install commands in the background.
Note: The latest available version of APT tool for this particular distribution is 0.9.7.9+deb7u7
From researching how APT works and the attack vectors associated with this tool, we came across an interesting source of information on the blog of packagecloud.io (see references for more information) that helped us perform an attack Proof of Concept (PoC) against the device by abusing the limitations of the old version of the APT package manager to deceive an administrator into installing an arbitrarily modified (backdoored) version of any system package to obtain remote access with full privileges on the system.
To achieve this, an attacker with access to the network segment where the device is connected needs to perform a Man-in-The-Middle (MiTM) attack between the device and the DNS server used by the device, or between the device and the default gateway that allows reaching the DNS server on another network segment.
In addition, the attacker may need to wait until the administrator decides to check for package updates as part of an administration routine.
In order to design the attack PoC, we will use the well-known divide and conquer strategy to decompose the problem in sub-problems that can be solved individually and then will be put all together to perform the attack and obtain our shell which is what you all want to obtain.
There are a number of things we have to do for this attack:
1. Perform a MiTM between the target device and the DNS server: Create fake DNS responses to make the device obtain a controlled IP address controlled.
2. Backdoor a DEB package: Modify a DEB package to contain the custom script to provide access to the device with the privileges of the user that runs apt, which is root.
3. Metadata files creation: Create the required APT metadata for the modified DEB package to serve via an HTTP Server.
4. Repository deployment: Run a Web server containing the required files and directory structure to serve the new and modified package for the APT tool to download the fake and backdoored package.
For this example, we will use the following infrastructure:
In this section, we describe how to proceed to be in the middle, with our attacker machine, between the target device and the DNS server, in order to send fake IP addresses for the packet repository servers.
The target device can be configured with a DNS server that is located on the same network segment where the target device resides, or it can be located beyond the default gateway. In the first case, we have to make the device believe our attacker machine is the DNS server, and in the second case, we have to make the device believe our attacker machine is the default gateway.
If you know beforehand the IP address of the DNS server (e.g. you somehow obtained the target device network configuration), then it is easy for you to discern where it is located. However, if you don’t know what it is, the first thing you may want to do is to poison the device and the default gateway to sniff the DNS traffic sent from the target device and then discover the IP address of the DNS server.
If, after enough time, there is no traffic, then you may be facing a DNS server located on the same network segment, which can be discovered by performing a port scanning of the devices on the network.
Note: We could also perform an MiTM and forward all the packets going to the package repository IP address to an IP controlled by us running a HTTP proxy in transparent mode, and then use it to modify the HTTP traffic at will. However, this would not work in scenarios where the package repositories have more than one IP address.
Now, we are going to explore how we would proceed with the man-in-the-middle attack for the DNS server located in the same network segment and beyond the default gateway.
Suppose the DNS server used by the target device is located on the same network segment of the device itself. Then we would only perform an ARP spoofing between the device and the DNS server.
This way, we will make the device think the DNS server’s MAC address is the one of the attacker’s machine. Therefore, all DNS query messages will be sent to the attacker machine instead of to the actual DNS server, providing us with the possibility of learning about them and answering with arbitrary data.
In order to respond with fake IP addresses for all the package repository hosts and with valid answers for the rest of the queries, we coded a very simple Python DNS poisoner tool that will help on this matter.
1. Execute the ARP poisoning attack from the attacker machine (10.x.x.111):
The following command example shows the execution of arpspooftool to poison the target machine and make it believe the DNS server has the MAC address of the attacker machine:
2. Execute the DNS poisoning tool on the attacker machine to respond with the IP address of the attacker machine for specific DNS type A queries:
The following command example shows the DNS poisoner running to respond all the DNS type A queries containing the FQDNs that were configured to be faked by the tool with the specified IP addresses. For the rest of the queries it will forward them to an upstream DNS server and then send the response back to the target machine:
The following command example shows the hard-coded list of hosts and their corresponding IP addresses that has to be faked by the DNS poisoner. In this example, we need to fake the IP of the FQDN www.google.com:
When trying to resolve the host name of specified hosts from the target machine that is under an ARP poisoned attack, the fake DNS server will respond with the specified IP address(188.8.131.52 in this case).
See below for the response obtained from the attacker machine when the host www.google.com is queried:
The following command example shows the DNS poisoner tool output. The example below shows that it has received a DNS type A query looking for the IP address of the FQDN www.google.com, and since it is part of its poisoning list , it then sends the response to the target host with the fake IP 184.108.40.206.
Observe it will also forward another query to the upstream DNS server corresponding to the DNS type AAAA.
Now suppose the DNS server used by the target device is located on a network segment that is beyond default gateway. Then we would need to perform an ARP spoofing between the device and its default gateway. Doing this, we would be able to observe and modify all the traffic that goes through the attacker machine.
In particular, we would be able to sniff the DNS traffic sent from the target device, check if the searched FQDN is within the list of hostnames to be faked, and send a fake response to the target device.
In this particular case, as we are acting as the default gateway, we may want to provide full connectivity to the target device so that the attack goes undetected, which means we are going to enable the forwarding of packets on the attacker machine. However, we have to ensure we drop all packages that are destined to the actual DNS server in order to avoid duplication of answers, even though our answer would reach the target device first.
1. Allow IP forwarding via the TCP stack configuration and Iptables:
2.Prevent the target device from reaching the actual DNS server:
3. ARP Spoof the target device and the default gateway:
In this section, we will modify a Debian .DEB package corresponding to a typically used software installed on the target device. The objective is to add a few commands on the postinst executable script that is executed after the package installation (see references for more information). For our PoC, we will modify and backdoor use the latest Samba package version available for the target distribution.
The following is the step by step procedure that will allow us to install our backdoor code on the target operating system:
1. Locate the package version we need to modify: since we know the exact Linux distribution used by the device and the package repositories, we can obtain the exact version of the latest Samba package available:
With the output above, we will be able to see the package can be obtained from the repository: http://repo.device_vendor.com/pool/s/sa/samba_4.4.5+dfsg-4~bpo7+4_amd64.deb, we can then downloaded the package and proceeded to modify it.
2. Extract, modify, and repack the package: the first task will want to do is to extract the file system tree and the control information files from the package archive. Next, we will modify the required files. Lastly, we will build the archive again.
Extract the archive filesystem and control information:
Modify the DEBIAN/control file to be interpreted as a new version:
Create a script that will be copied to the target system along with the rest of the original package files and set the adequate permissions to it.
For this PoC we created a simple Bash script that will download a file from an attacker-controlled Web server and execute it:
Note: we will want this script to be executed every 5 minutes on the system. We will make the target system download a file from a Web server, store it on the temporal folder /tmp, make it executable, and finally run it. If the attacker does not want the system to execute it because the attacker already has a backdoor running, then the attacker can stop the Web server and the script on the target system will silently fail on that step.
Add a command at the end of the postinst Debian package control file to make the system call our backdoor every 5 minutes:
Now let’s build the modified package to be ready for delivery:
We now have a specially modified Debian package that will be used to deceive the administrator of the device when the APT tool is used to obtain a list of new packages and install them, either directly or indirectly (via the Web interface).
Note: In case you have realized, for this package re-building task, I used the target machine OS. I would recommend you do so with a replication of the target machine, in case you can get it from the Internet, or at least using the exact same version of the Debian package management system, as you may face some issues when using different versions. For this particular scenario, the target device’s dpkg version was 1.16.17, which uses gzip compression by default. However, my Kali Linux attacker machine has the version 220.127.116.11 which uses xz compression by default. Of course, you can use a command line switch to specify the desired compression method, but when performing a real attack, you want to reduce the mistakes to the minimum.
Once we have the maliciously modified .DEB package, it is time to prepare the required metadata files used by APT to work properly. When updating the target device (i.e. by running apt-get update), it accesses and obtains the following interesting resources, among others:
The device had more repositories configured and accesses much more resources. However, the provided example is the one that is interesting for our purposes, as that repository contains the Samba package at:
The Release.pgp metadata file contains the GPG signature of the Release file that is used by APT to verify the latter was not modified/altered on transit. The Release file of a repository contains a list of resources/paths from where to download the Packages metadata files for the different platforms supported by the repository (e.g. amd64 or i386).
Along with the list of resources, the Release file contains the checksum hashes in three different formats: MD5, SHA1, and SHA256 for each resource, allowing the verification of the Packages files after downloading them from the repository. Bear in mind that the Release file may contain different compression formats for the Packages files, for example: plaintext, gzip, and bzip2 compressed files.
To create our own repository for distributing the backdoored Samba package, we should modify the metadata files Release and the Packages file located under the adequate architecture path (e.g. binary-amd64). In addition, as we don’t know the private key used to sign the original Release file and produce the Release.gpg signature file, we will NOT provide it when requested by the APT tool from the target machine.
The following command output shows the content of the Release file obtained from the actual repository of packages. In red are the lines we want to modify to adapt it to the modified Samba version:
The following command output shows the section of the original main/binary-amd64/Packages file corresponding to the latest Samba version, identified by its SHA1 hash 9b6db96ef0d564adb476b3c6241ae1cc34ba67b9.
We will want to modify and adapt the lines highlighted in red to the modified Samba version:
Note: the Packages file contains a lot more information for all available packages on this repository, including different version of packages. The fake Package we are going to provide will just contain the backdoored Samba version.
In order to create our malicious metadata information for this PoC, we will do the following:
1. Prepare new Packages files: Create a new Packages file containing only the information of the new and fake Samba package, considering the values for the Version, Filename, Size, and checksum fields.
Calculate checksum for the maliciously modified Samba package:
Check the size of the package:
Create a new Packages file with the new information:
Create the Packages.gz file by means of the gzip command:
2. Prepare the new Release file: create a new Release file containing only the information regarding the just created Release and Release.gz files.
Calculate checksum for the new Packages and Packages.gz files and then check their sizes:
Let’s use this information to create the new Release file:
Now that we have our maliciously modified Debian Samba package and all metadata required for mounting a fake repository of packages, we just need to create the required directory tree, store the files in the right places, and launch a simple HTTP server that will be used by the target device, after it is DNS poisoned to point to our repository of packages, to download the backdoored software package.
The following is the list of full paths where the files should reside:
The following command output shows the prepared repository structure:
Finally, to have a working repository, we will run a simple HTTP server as follows:
Now that we have decomposed the problem and analyzed the parts individually, it is time to put all the pieces together and perform the attack against the device.
The scenario for this example has the following parameters:
Given the proposed scenario, we will use our attacker machine to perform a man-in-the-middle attack (using Arpsoof) between the device (10.x.x.115) and the default gateway (10.x.x.3). We need to ensure that Internet traffic is fully allowed so that nothing goes wrong from the device perspective that can make the administrator suspect about us being there.
Also, we will DROP all DNS traffic that points to the configured DNS server (18.104.22.168) on the device so that it cannot reach the service and will run our DNS poisoner tool instead to make it respond to those DNS queries that are being dropped by our machine via Iptables.
Our poisoner will only answer by itself to the pre-configured FQDNs to make the victim think our attacker machine IP address is the one associated to the repository of packets configured on the device and will forward the rest of the queries to the actual DNS server to prevent a disruption of the service.
1. From the attacker machine, setup the forwarding and dropping rules:
Note: Even though I’m showing the DNS DROP Iptables rule along with the other, used to allow our attacker machine to act as a router for the attacked device, I would recommend running it after the DNS poisoner tool so that we reduce the possibilities of producing a disruption of the service and therefore the chances of detection.
2. On the attacker machine, update the DNS poisoner tool to make it respond to the target device when querying for the FQDN associated to the repository of packages with the IP address of the attacker machine and then run it:
3. Now, it is time to launch the MiTM attack using Arspoof from the attacker machine:
4. When an administrator checks the updates via the operating system command line, the following happens:
The administrator runs apt-get update to obtain a list of new packages available from the repository of packages:
Note: observe that for the Release.gpg metadata file hosted on our attacker machine (repo.device_vendor.com), the administrator received an Ignore error, meaning the file was not there.
From the DNS poisoner running on the attacker machine, we can see it received a query for repo.device_vendor.com and sent a fake IP address pointing to the attacker machine itself, where our fake repository will be served via an HTTP server:
From the HTTP server on the attacker machine, we can see a number of metadata files were requested, but only those actually served by us (/dists/wheezy/Release and /dists/wheezy/main/binary-amd64/Packages.gz) were successfully sent to the target machine:
5. After the metadata was successfully updated by the administrator, the admin will probably try to install new packages:
The administrator will run apt-get upgrade to obtain the list of new packages readily available for being installed on the system:
Note: It is important to note that, even though this APT version allows installing packages from an unsigned repository, it will warn the user with a message for all packages obtained from the insecure repository and will require her/him to expressively accept the warning before downloading and installing them.
Tip: The message saying “no crontab for root” should be suppressed from the screen to avoid any suspicions. I leave this up to the reader to find out how to do it.
6. Verification: if the unaware administrator was fooled into installing the backdoored package, then we could verify the following:
On the target machine, a new cron job would have been created. This task would run the script, at the specified location, every 5 minutes as root:
The script on /usr/sbin/samba_update would contain commands to download a file from the attacker machine, modify its permissions for making it an executable, and finally run it on the target system:
Note: Observe this simple backdoor PoC attempting to download a file from the specified server and will try to execute it. If the file is not there (the service is down), then wget will silently fail, and the execution will not be completed. This provides the attacker with the opportunity of raising up an HTTP server every time s/he needs a new script with arbitrary commands or binary file to be executed on the target machine.
7. Obtaining a shell
In order to get a reverse shell on the target machine, we have to create a simple script on the attacker machine and serve it via a HTTP server until the target machine executes the task via cron. The following script will use the netcat tool, installed by default on the target device, to connect back to the attacker machine and provide us with a shell:
At the same time, we have to run a listener on the attacker machine to wait for reverse shell connection:
Up to this point, I hope you have seen the importance of using the latest available security features of the tools we use on a daily basis. Even though it may not be considered to be a security bug of APT, the latest version of the tool provides default options to prevent the user from installing packages from unsigned repositories. In addition, they also support the use of secure repositories accessible via HTTPs, providing another layer of security to prevent man-in-the-middle attacks.
On the other hand, in an attack scenario like the one exposed here, you may consider the warning message presented by the APT tool to the administrator enough to prevent this attack from occurring. However, sometimes developers are not fully aware of the implications of certain parameters related to the command line tools called from the custom source code they create for applications.
The APT apt-get tool provides users with a command line switch named –force-yes that can be used to prevent the tool from prompting when something dangerous occurs, such as the warning we saw during the apt-get upgrade performed by the unaware/unconscious administrator. The following is what the main page says about this option:
Force yes; this is a dangerous option that will cause apt to continue without prompting if it is doing something potentially
harmful. It should not be used except in very special situations. Using force-yes can potentially destroy your system!
Now, continuing with the original story, we explained at the beginning that the analyzed device was supposed to be only managed via a custom Web interface. Therefore, the software update procedure was meant to be performed via an option of this interface. Interestingly, the backend implementation of the update procedure was calling the apt-get tool to install/upgrade packages as follows:
Observe the use of the –force-yes option, which we explained, removes the prompt after the warning messages.
Now that we know how the administration interface updates feature is coded, we could attempt to perform the same attack we did before and observe what is going to be seen by an administrator of this device.
When the administrator accesses the Updates feature via the Web console, s/he will see the device is updated (if that is the case). Observe in the following screenshot of how this is shown to the user:
Then, after the attacker performs the same man-in-the-middle attack we explained so far, the administrator will see the following message:
If the administrator decides to install the updates, s/he will click on the plus sign (+), which will install the available updates obtained from the malicious repository controlled by the attacker:
Then, the device Web interface will show a message indicating the software updates were installed on the device, and it is required to reboot it:
Finally, from the attacker machine, we can observe the backdoor file was requested and then executed by the device, giving the attacker a reverse shell to execute commands on the device underlying operating system as root:
The status quo of “breaking things” is broken. Inconsistent methodologies, tool led approaches, and poorly scoped tests are coming up short in true risk mitigation. Most discouraging is that some of the largest organizations continue to subscribe to these approaches as part of their AppSec initiatives. If you are looking to achieve deeper results, supported by well-founded application threat models, you’ve found your security partner in VerSprite. Explore AppSec Services →