just another infosec blog

Exif XSS using JPEG as media

Ever heard about Exif and why it potentially can put a web site in danger? Exif is an abbreviation for “Exchangeable Image File Format”. Technically it is a file format for storing information in media files. The specification uses the JPEG discrete cosine transform (DCT) for compressed image files and TIFF for uncompressed image files. It also uses RIFFWAV for uncompressed audio files and IMA-ADPCM for compressed audio. Note Exif does not support JPEG 2000, PNG or GIF.

Think of it as a way to store metadata inside, say, a picture. When taking a picture with your phone, the phone will store various nifty things in the picture itself. It’ll store the shutter speed, the camera make and model, resolution and what nots. This is Exif data. You can also store information about copyright, a small picture description, the photographers name and much, much more. This is handy and pretty cool – but also quite dangerous. An attacker can also insert malicious code in the Exif tags.

In this post I am going to guide you through an attack which I conducted in my test lab.

The attack

This attack was aimed at a custom-made web application running in my private sandbox. At first I tested for regular XSS and found it possible by using the search utility of the site. This lead me to suspect that input wasn’t sanitized correctly elsewhere in the application. Noticing there was a picture gallery on the main page tempted me into thinking the developers forgot a thing or two when handling the images.

Outline

Outline for this attack

Creating a JPEG image

Filling the image with Cross Site Scripting content

Uploading the image to the web application

Verifying results

Creating a JPEG image

The very first thing I did was to create a payload carrier. For this I used GIMP to create a wall papered sized JPEG suited for the desktop. Usually I aim at making a large image since I want to exploit that some CMS’s creates several copies of the uploaded image in various sizes. More images means greater chance for success.

The image had a white background with a text stating “XSS” so I could find it later if I needed to look for it. This image was pretty goofy and bland. In order to verify the Exif tags GIMP had made, I issued this command in Kali Linux

exiftool image_file

Filling the image with Cross Site Scripting content

The basis for this attack was to get a piece of Javascript to execute on the target. I chose the most basic script imaginable

<script>alert("XSS");</script>

Nothing fancy. Once executed this would launch an alert box stating “XSS”. I could have made it into something more advanced, but for now I settled with this.

Filling the image with the XSS code was easy (CLI)

exiftool -tag_name=tag_value

Choosing which Exif tag(s) to use is a hit and miss job. For this I basically sat down and took a look at the site to figure out which tags was used by listing out the Exif tags from one picture from the target and comparing to what I saw on-screen. It turned out there was a few tags to try. For a full note on tags, please look here.

I soon found out it was a tedious task to fill all tags with the XSS code. To ease the process I developed a small Python 2.7 script.

You can see the tags I used in the “exifs” array. This script takes to CLI arguments

python xss.py source_image xss_code

Running it will inject the XSS code to the listed Exif’s.

Deploying

Deploying the image was fairly easy. I located the image upload utility and placed my image. This approach can be a hit and miss. Sometimes when testing this method the CMS has already got some filters to protect against these kind of attacks. Often I can bypass this by URL-encoding the XSS or do some other magic.

Result

The image was accepted straight away and now the hunt for locating it began. It turned out that the CMS created a thumbnail image of it. This was used as the preview in a picture carousel on the front page. Sadly the thumbnail didn’t work out as planned. But luckily the carousel resized the image in CSS. Since the carousel displayed the author tag the XSS got executed.

How to avoid

Exif content must be sanitized on output since you can’t sanitize the data inside the image upon upload. Converting the Exif tags on output to HTML entities is the safest approach to mitigate this issue.