A new vulnerability in Debian’s Advanced Package Tool (apt) is the latest big tool in the data center attacker’s arsenal. The vulnerability (CVE-2019-3462) is in Debian’s high-level package management system, which is used by system administrators to install, upgrade and remove software packages. The vulnerability can be exploited when administrators install or upgrade software package on vulnerable servers.
The apt package management software is part of every Debian based Linux distribution, covering Debian, Ubuntu and a whole group of smaller distributions such as Kali, TailsOS and many others. Distrowatch lists over100 active distributions (large and small) based on Debian. All of these are likely to be vulnerable.
Using simple network traffic spoofing and traffic injection techniques, an attacker can easily impersonate an apt server and exploit this vulnerability to bypass security measures and further spread in the network towards the organization’s crown jewels. If exploited, the vulnerability may allow an attacker to run code at root permissions on victim servers and basically perform any action they want, such as installing trojans, ransomware, worms and more.
In this post we will cover some of the technical details of the vulnerability, explain how it can be exploited by an attacker in data centers, and discuss effective ways to mitigate against such attacks.
Lateral movement through apt
On January 22nd, Max Justicz published a write updetailing a vulnerability in the apt client. Using Man in the Middle techniques, an attacker can intercept the apt communication while it downloads a software package, replace the requested package content with their own binary, and execute it with root privileges.
1 – The apt http downloader allows for content injection
2 – By default, apt downloads software packages over HTTP rather than HTTPS
The first flaw allows an attacker to control the behavior of the apt package manager, resulting in an arbitrary code execution. But to reach a situation where an attacker can control content, he must be able to inject himself into the communication between apt and remote servers. This is possible because by default, apt communicates over HTTP (and not HTTPS).
Exploiting this inside a data center network requires traffic redirection capabilities. To execute a traffic redirection maneuver, an attacker will need either to control a privileged location (such as a proxy or router) or to somehow spoof one of the update servers, by abusing a variety of network injection attacks, such as DNS poisoning.
Once the attacker is able to intercept apt traffic, they must wait to see a server update. In many organizations, this happens on a regular basis. Once they capture apt traffic, they can reply with malicious content. From this stage, they can write files that will be parsed by apt , and using different parsing mistakes, cause apt to execute a crafted file with root permissions.
This vulnerability is an excellent opportunity for an attacker to further propagate inside a data center. In many networks, east-west traffic is not monitored and is easy to spoof.
An apt takeover
When the apt process requests a software package, it communicates with a repository server using a spawned worker process such as /usr/lib/apt/methods/http or /usr/lib/apt/methods/ftp. These processes are responsible for handling the nitty gritty details of the specific protocol.
The communication between these worker processes and the apt process is made through a text-based protocol via stdinstdout interface. This interface contains status messages (downloading, waiting, etc.) and control messages (download this, redirect here). Messages are formatted in a similar way to HTTP messages.
For example, 601 Configuration
(…many more lines omitted…)
This example and all following examples are taken from Max Justicz’s excellent write up.
The vulnerability resides inside the http worker. If the worker receives an HTTP redirect reply from the server , the new URI provided by the server is sent to the apt process as is, allowing a malformed URI to inject content.
So while a valid redirection would look like the following text URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
A malicious reply can look like this: URI: http://deb.debian.org/debian/pool/main/c/cowsay/cowsay_3.03+dfsg2-3_all.deb
New-URI: http://deb.debian.org/new-uri Foo: Bar
In this case, the attacker is redirected to a new URI but more importantly the `Foo: Bar` key-value was injected by adding a new line character to the end of the redirection URI.
An attacker can exploit this to inject messages to the communication channel between the apt and its worker. Due to the textual fashion of the protocol between these two processes, the attacker can inject new messages after the New-URI value. The result is that apt will read two messages. One, informing apt that the request was redirected and an additional attacker generated message. This message is under attacker control and he can write that the download request was completed. This can be seen in the following example:
What happened is that the attacker not only injected new values but by knowing the precise protocol was able to inject new messages. Following the above malicious reply, the apt process will send a request for the new URI in response to the 103 Redirect message. Then before waiting for a new reply the apt process will read the injected201 URI Done message and assume the download is complete.
Note that to be able to properly inject content, the attacker must match his attack to the exact version of apt running on the victim, but this can be achieved through trial and error.
The apt protocol
To abuse this vulnerability and run code on a victim machine, we need to take a step back and understand the communication between the client and a repository.
We’ll break down the apt-get update command. When the apt-get update is run, we are requesting the apt package manager to update its list of packages that exist on remote repositories. A typical install has multiple remote repositories to use (saved in /etc/apt/sources.list) and for each one, there is a manifest that lists what packages are available in that repository.
The manifest is stored in a file named Release – a simple text file, listing package files available in the repository with their hash.
For example, a snippet from the Release file for the Debian 9 repository looks like this:
Inside each file listed in Release, there are more file listings, with more hashes, that detail specific files for specific package (deb) files.
“These checksums allow apt to verify that it has downloaded a correct copy of the Packages file, with a checksum that matches the one in the Release file. And when it downloads an individual package, it can also check its checksum against the content of the Packages file. If apt fails at either of these steps, it will abort.” (Taken from the SecureApt entry in the Debian wiki)
From a security point of view, this makes the release file a single point of failure. If an attacker can modify the release file, they can easily feed malicious package files that look legitimate.
The solution to this problem is an additional file named Release.gpg that contains a textual GPG signature. Using the signature stored in this file, apt checks if Release is valid. With this process, the Release file can be validated.
The attack flow – from MitM to code execution
Using this data and the content injection vulnerability, an attacker can write and utilize different files to gain code execution:
The client runs apt update requesting a Release and Release.gpg files from the repository server. In return the attacker provides a malicious Release.gpg file which is a perfectly valid file but with additional data. The gpg file is then stored by apt in a path known to the attacker.
Next, the client runs apt install which leads to a request for a deb package. Then, using the content injection vulnerability, the attacker injects a message directing apt that the deb package was downloaded pointing to the location of the Release.gpg file.
At this point, the apt package manager will parse the Release.gpg file, as if it was a deb package and execute its instructions under root privileges. This “trick” works for two reasons. The deb file format cares about the file content at the start of the file and ignores any appended content. The second is that the gpg tool is very permissive in what it accepts, as long as somewhere in the file the signature appears. The result is an attacker that can construct a file that looks like the following image.
The malicious Release.gpg serves double duty as a PGP signature and a debian file
Fixing a ten year old vulnerability
The fix for the vulnerability is simple and can be seen in git repository of apt (commit 5eb01ec1).
The fix changes the code to ensure that the new URI contains only alphanumeric text and other printable characters. This prevents an attacker from causing content injection or any other manipulation.
The obvious solution to this vulnerability is to securely patch the apt package. This is not trivial because we typically upgrade packages using apt, and the vulnerability is in the upgrade process run by apt! Use the following command line
The command line apt -o Acquire::http::AllowRedirect=false can be used as an alias for apt as a workaround to prevent redirections, according to Debian this may cause security updates to fail and therefore is not a long-term solution.
An alternative solution is to switch apt to use HTTPS , but not all mirrors support HTTPS and this can have a significant bandwidth cost in large networks.
An even better solution will include preventing these types of attacks all together. Apt traffic should only go to well-known machines, either mirrors inside a network or a specific list of machines in the internet. To enforce this, you might want to create a rule that limits traffic originating from apt and its sub processes to specific IPs. This makes sure that an attacker cannot simply rely on redirecting apt traffic to any server controlled by them. This can be achieved with Guardicore Centra, which can easily detect traffic from apt and make sure it goes only to allowed servers (internal or external).
In this image from Centra, we see apt-get communicating with an unknown internal server
This defense method is applicable not only for apt – it should be applied to every critical IT infrastructure in your network, such as DHCP.
An apt concern
This is not the first vulnerability in apt, a similar attack in 2016 was discovered and vulnerabilities have also been found in the Windows Update mechanism. We can assume that more bugs reside in these more than a decade old code bases. Network security professionals should assume update mechanisms can be abused and make sure to harden core IT.