There is a saying in the world of journalism – if it bleeds it leads. The same is true in the world of infosec. 2014’s Heartbleed and 2017’s Cloudbleed were headline grabbing vulnerabilities, and the infosec community has been waiting nervously for another bug of equal severity to rear its ugly head.
The Latest "Bleed"
On May 18th, Google’s Chris Evans published a blog post detailing what might be the latest “bleed.” Evans discovered that by sending a specially crafted image file to himself via Yahoo! Mail, the image that he got back included the ghostly remnants of other images, the product of a buffer over-read into system memory, which contained image attachments from other users. He dubbed the vulnerability Yahoobleed. We call it CVE-2017-9098. The vulnerability was severe enough to prompt Yahoo! to pay out a $14,000 bug bounty (which Evans donated to charity and Yahoo matched) and, perhaps more surprisingly, completely retire the ImageMagick library from their ecosystem.
ImageMagick is a library for displaying, converting and editing images and has been around for twenty-six years. Originally designed to convert 24-bit images to 8-bit, almost three decades of improvements, updates, and feature-creep has resulted in a sprawling codebase consisting of more than 1,000 files and 600,000 lines of code. Not surprising then, that in recent years researchers have uncovered a number of serious security flaws in the software. Several of these are documented on the satirically titled ImageTragick.com.
Is that a duck? (Source: Chris Evans / scarybeasts)
The Last ImageMagick CVE?
Evidently the privacy implications of this latest vulnerability were serious enough for Yahoo! to drive the final nail into the coffin. But while it’s unlikely that this is the last CVE we’ll see concerning a significant security flaw in this still widely deployed component, there were circumstances particular to Yahoo!’s implementation of ImageMagick that made the confidentiality impact particularly severe. Let’s delve into the technical details and see why.
Technical Details of CVE-2017-9098
CVE-2017-9098 lies in one of the more obscure of ImageMagick’s coders. The Utah Raster Toolkit Run Length Encoded image format has no business being used on the modern web, but the ImageMagick library still supports it. As the image is being read, the coder allocates a suitable amount of memory via a call to GetVirtualMemoryBlob() in memory.c. This method defaults to allocating memory with malloc(), which, unlike mmap() or calloc(), does not initialise or zero the memory before returning a pointer.
In other words, the memory allocated for the new image already has data in it. The coder then checks the image header for flags that will tell it how to initialise the background. If certain flags are set, and no RLE protocol commands are included in the header, the canvas remains uninitialized. What gets returned in the final image is data from some free()’d portion of memory, and in Yahoo!’s case, this contained images from other user’s e-mail attachments.
So What's the Big Deal?
Normally, this wouldn’t be that big a deal. Every time the application wants to return a thumbnail or a JPEG converted from an e-mail attachment, we would simply invoke a new instance of the convert process, and the data returned would very likely be limited to whatever was in that instance’s stack frame, i.e. the attacker’s own data.
What was peculiar about Yahoo!’s implementation was that the same convert process appeared to have longevity, and handle multiple images from different users. Furthermore, it was evident that Yahoo! were using a non-standard heap implementation. The size of the allocation in Evans’ proof-of-concept was in the region of 4MB. By default, on Linux x86_64, such a large allocation would be handed off from malloc() to mmap(), which would initialise the memory, zeroing it. With Yahoo!, this was not the case.
This vulnerability was patched upstream on March 9th, and included in ImageMagick 7.0.5-2 and 6.9.8-1, both released on March 11th. However, there is an interesting aside here. GraphicsMagick is a fork of ImageMagick created in 2002. This same vulnerability was reported to its maintainers and patched almost a year ago, in March 2016. Particularly astute black hats could have been exploiting this vulnerability for almost a year due to a simple lack of communication between these projects. As Evans is quick to point out, the fault goes both ways. A vulnerability patched in ImageMagick in December 2014 was only remedied in GraphicsMagick in March 2016. As a community, I think we we can do better.