In the beginning of this week we discovered a security flaw in the famous malware analysis framework „Cuckoo Sandbox“. We disclosed this bug to the developers on the 7th of October 2014. Not even three hours later the patch was verified and the updates were supplied by the developers.
The Cuckoo Sandbox Team already did a short write up to explain the nature of the bug: http://cuckoosandbox.org/2014-10-07-cuckoo-sandbox-111.html
We will provide a more detailed explanation and a simple proof-of-concept to exploit this bug. We recommend to update to the latest Cuckoo Sandbox version.
The Cuckoo Sandbox framework consists of a host system that manages one or more sandboxes where malware is run in. At the beginning of the run, the client only contains a small listener that receives the current version of the analysis framework, the configuration for this run (“analysis.conf”) and the malware to be executed from the host. Then the malware is run within the sandboxes and the analysis framework generates logs of the behavior exposed by the malware as well as other information like screenshots. The logs and the screenshots are sent from the sandbox to the host along with files dropped by the malware, as they may contain interesting information like the malware configuration or second stage malware executables downloaded and/or unpacked by the malware.
In the standard version of Cuckoo, the communication between the host and the sandboxes is implemented via a TCP/IP-based text protocol.
If a sandbox uploads a file to the host, it connects to the host on a specified IP and port and starts the upload protocol. The IP and port are configurable on the host and initially transferred to the client in the run configuration “analysis.conf”.
Cuckoo sandbox is free to use and open source software. Therefore it is used by many security companies, law enforcement as well as academic and independent researchers to analyze malware. Due to its free nature, it is probably more widespread in smaller organizations and independent researchers.
The flaw explained below allows analyzed malware to write arbitrary files to arbitrary locations on the host system (sandbox evasion). This possibly enables malware to take control of the host systems.
Generally speaking, this attack allows it for malware authors to break into the systems of those that are trying to fight them. This can be achieved by writing tailored malware that actively tries to exploit Cuckoo sandboxes. Prerequisite is that the attackers can enforce to be executed by a Cuckoo sandbox instance, for example by uploading the malicious files to a public web interfaces to an analysis framework.
On the host side the handler for the TCP/IP protocol contains a class for handling the file uploads that is called when the client sends a line with the string “FILE“. The FileUpload-class then reads the next line where it expects to find a relative path. Comments in the source code of Cuckoo Sandbox hint that expected strings would be “shots/0001.jpg or files/9498687557/libcurl-4.dll.bin”. These strings are split up into their relative directory part and filename for further sanitation.
The expected relative path is sanitized in a way that no path traversal is possible: The whole path must not contain a ‘./’, which could be used to traverse the folders upwards.
A list of blacklisted paths can be defined, which will be matched against the relative folder part. Yet it contains only the string “reports/”.
If those checks are passed, the absolute base path of the storage where all reports are saved (e.g. “/home/cuckoo/Desktop/output/”), as well as the relative folder part are given to a function which will create the folders, if they do not already exist.
As a next step the absolute target path of the file that is about to be uploaded is built by using Python’s built-in os.path.join-function. The paths to be joined are the absolute base path and the assumed relative file path that was sent by the client:
Although security checks are in place, it is still possible to sneak by these checks: The function os.path.join does join the path properly, if the second argument is a relative path. But what happens if we manage to supply an absolute path instead? The documentation covers this case, but it is not necessarily the behavior expected by the programmer:
“[…]If any component is an absolute path, all previous components […] are thrown away, and joining continues[…]” docs.python.org/2/library/os.path.html
This effectively means in our case, that the first argument is completely ignored, if the second argument is an absolute path – now remember that the second argument is the string sent by the client-system.
When the path which the sandbox client sends matches the following criteria, an attacker can write the file to any absolute path on the system, given that Cuckoo Sandbox has the appropriate rights:
Given the circumstance that the malware running on the analysis system can take control of the whole system, it can easily parse the “analysis.conf” of Cuckoo Sandbox to get the IP and Port where the Host is listening. It can then connect to the host and send it an arbitrary file which is written to an arbitrary path, given the above mentioned restrictions.
The “analysis.conf” file does not only supply the port and IP to the client system, but also contains additional information about the sample. One part of this is the path of the malware on the host system. In our proof-of-concept for a host machine running Ubuntu we assume that the malware is located in the user’s home folder. We will then try to write over the user’s .bash_aliases in order to turn the exploit into a command execution, which will trigger the next time a shell is started on the host.
The following code shows one way of exploiting the vulnerability:
Download PoC code as text file.
This exploit obviously only works if the malware on the host system is located in the user’s home folder, so the path is “leaked” into the analysis client. But as the mentioned bug allows you to write as many files to as many locations on the host as you want, you can even brute force the locations.
One good assumption of the Cuckoo Sandbox user name can be taken from the installation manual of Cuckoo Sandbox:
sudo adduser cuckoo
Probably there are even more effective solutions for what file to write to which location in order to turn this into a command execution, but as a proof-of-concept it should suffice to show the severity of this bug.
The actual effects imposed by this sandbox evasion may depend on several factors, primarily the separation of networks, hosts and users. If the Cuckoo sandbox host process is run by a low privileged user, and if the host is used for no other work and is located in a separate network you are less troubled than the other way around. But especially for small companies and independent researchers, this is less likely the case.
You might extract some mitigation strategies from the description above. But our recommendation is: If you use Cuckoo Sandbox and did not yet upgrade your systems, do it now!!!