Exploiting XSS with Javascript/JPEG Polyglot

What is a polyglot?

Just like PNG, JPEG, and DOC are valid file types, polyglots are a combination of two different file types. For example Phar + JPEG (PHP archive and JPEG file), GIFAR (Gif and Rar file) Javascript + JPEG, etc.

Applications allow only certain file types on features like file upload and don’t allow other file types like .php or .js files as these can enable the attacker to upload malicious files on the application. Applications perform extension filtering checks like double extensions(.jpg.php) or use of null bytes in extension(.php%00.jpg), file names (.htaccess, .config, etc..), and if the uploaded file’s signature also matches its content type.

The different application uses different methods and polyglots can be used to bypass some of these validation checks.

JPEG Structure

A JPEG image is represented as a sequence of segments where each segment begins with a header. Each header starts with some byte. The payload followed by the header is different as per header type. Common JPEG marker types are as listed below:

0xffd8: “Start of Image”,
0xffe0: “Application Default Header”,
0xffdb: “Quantization Table”,
0xffc0: “Start of Frame”,
0xffc4: “Define Huffman Table”,
0xffda: “Start of Scan”,
0xffd9: “End of Image”

Every binary file contains a couple of headers. They are very important for a file as they define specific information of a file. Most of the headers are followed by length information. This tells us how long that particular segment is.

The start of the image header contains FF D8. If we don’t see it we can assume this is some other file. Another important marker is FF D9 which tells the end of the image.

To make the payload look like a legitimate JPEG file, we will add the length of the header, comment header, null byes to pad and then our javascript attack vector.

Let’s say the attack vector is */=alert(“XSS”)/* Converting it into hexadecimal will look like this.

The payload in hex:-

2A 2F 3D 61 6C 65 72 74 28 22 58 53 53 2E 22 29