If you have a look at the file headers of GIF images you see five characters of plain text in the beginning. Why not manipulate binary image data so it looks and works like a complete regular JavaScript file?
Motivation
Manipulated images are very interesting if it comes to web application security. Almost every web app allows users to upload avatar images and make them publicly available. Now data input validation and escaping is mostly done on text content, but my guess is that images hardly ever get checked except for their visual contents. So a manipulated image might pose a significant risk for web apps.
Tools
* A Hex Editor
* A website under our control for testing of the JS
Drink
Following an old tradition of
Fravia for this hack I would recommend having a Cuba Libre with Malteco 10 years.
Approach
First we need a regular small GIF image, let us take a black 1-pixel image. Of course this also works for bigger pictures and makes sense if it should not be too conspicuous. So a portrait of Bill Gates might be better for real life purposes. But for the sake of data economy we are sticking with the 1-pixel image for now.
So this is how the regular GIF looks like in hex mode:
GIFs always start with "GIF89a" or "GIF89b" and the next two 16-bit values are width and height of the image. So let us just set the width to 10799 pixels. In hex this is 0x2a2f and we have to switch the byte order because of Little Endian to 0x2f2a.
This gives us in ASCII
/*
which is the start indicator of multi-line comments in JS. So this means every following character is not interpreted by JS.
Then we proceed to the end of the file and put
*/
to close the comment. We put "=0;" to make a valid variable assignment:
GIF89a/*[GIF data]*/=0;
After that we can add any valid JS we want. In this example
alert('Boom!');
Result:
Exploit
Can this be dangerous? I think yes. Any website that allows uploading of images and making them public could be used for hosting malicious JS code that comes from a trusted website.
When defining an external JS source browsers do not evaluate the MIME type sent by the server. So you can just include those JS files although they are sent by the server with an image MIME type:
<html><head>
<script src="http://exploited.com/images/user32321.gif"></script>
</head><body></body></html>
This cannot be used to craft a XSS attack though, because you would have to insert HTML code into an attacked website, which is not possible by this approach. One idea might be to put HTML into a GIF, but it would have to be loaded by an iframe. And browsers nowadays check MIME types on iframe sources.
Mitigation
Web apps should check GIF images for JS code when uploaded. Best would be to check for a width of 10799 pixels in the GIF header. Total exclusion of GIFs is also an option but might scare some older users away...