Exploiting XSS using Polyglot JPEGs+Javascript to bypass CSP

Exploiting XSS using Polyglot JPEGs+Javascript to bypass CSP

This vulnerability allows an attacker to use a JPEG polyglot with JavaScript to hide the malicious JavaScript payload in the image successfully without corrupting the image to bypass the site’s CSP. For this exploit you will need two parameters, one to call the malicious image and the other one to upload it.

Polyglot

Polyglot refers to a file or data that is designed to be interpreted or processed as multiple file types or formats. For example, an image polyglot might be a single file that, when opened as an image in one application, displays a picture, and when opened as a different file type in another application, may execute code or reveal hidden content.

JPEG and JPEGs structure

If you do not know what JPEG is, I am not sure if you are in the right place reading this. JPEG has a structure where each segment starts with a header and each header starts with a byte. JPEG has its file signature which in bytes is:

This is how a file is checked if it is a JPEG or not.

Here are some of the marker types in

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”

Exploit

For an exploit, you will also need a parameter to call the image from.

First, choose a payload you are going to use, let’s use a common alert payload for this example which is going to be */=alert(document.cookie)/*. For forging a malicious image I am going to use a GHex editor. First, make sure there are no bytes in your image that have 2F 2A (/*) hex values next to each other or the payload won’t work since it will break the JPEG.

READ  Persistent Backdoor in Android using Kali Linux with a Shell script

Your first header should look like this, if it’s not then find a new image. These are so-called “Magic Bytes” aka File signatures. We already talked about File Signatures. The next step is to change 00 10 which represents the length of the JPEG header. Change it with 2F 2A (hex representation of ‘/*’)which is 12074 bytes. We are going to insert the payload between FF D8 and FF DB bytes. Now we need to add the null bytes in the image as padding to make it a valid image. The calculation for how many null bytes we need is 12074 (2F 2A)-16–27 (which is the number of characters of the payload, change this regarding to the size of your payload) for me this number is 12031. Which means we need to add 12031 null bytes to the image.

Now your Image bytes should look like this:

Now insert your payload in a hex format after the null bytes, you can use this site to convert your payload.

The last step for forging an image is to close the javascript comment at the end before FF D9 bytes which means it is the end of an image. You can edit the last four bytes as 2A 2F 2F 2F and that is it!

The code you can use to execute the the image file is:
<script charset="ISO-8859-1" src="linkToImage"></script>

The reason we are using charset ISO-8859–1 is because there can be encoding-related problems that can create an error so with this we change the encoding format.

READ  Hack Your School Wifi without Cracking

I hope you enjoyed my blog post, found it helpful, and learned something new reading it.

Cybersecurity Evangelist | Offensive Security Consultant (Red Team Operator) | Information Security Analyst