Fuzzing browsers in 2014 (and may be for a few more years...)

Since the release of Nduja fuzzer I've received a lot of positive and encouraging feedbacks from the infosec community.

Two years after, pushed by @antisnatchor, I decided to move forwards my fuzzing researches and delivered a new PoC: Fileja, which was presented at Syscan360 conference in Beijng.


During my research I decided to explore 2 less known territories among browser fuzzing algorithms:

  1. fuzzing with time sensitive operations(applies to all browsers)

  2. fuzzing with multiple scripting engines (applies to IE only)


Fuzzing with time sensitive operations

Most of existing DOM fuzzers use JS to dinamically build, crawl and mutate the DOM; all the fuzzing logic is limited to combine DOM Level 1, 2 and 3 APIs calls. This means that any DOM mutation requested by the fuzzer is put on the browser JS event queue and asynchronously executed. In 2012 at DeepSec conference I showed how MutationEvents based on DOM Level 3 APIs are an interesting testcase for introducing more entropy due to their synchronous behaviour. 


Apart from syncronous events, you can stress JS events management by introducing network calls, e.g. XmlHttpRequest and WebSockets.

When dealing with network calls you can introduce into your fuzzer logic:

  • synch or asynch server responses

  • multiple calls using the same xhr/ws object via setTimeout or setInterval API

  • arbitrary delays


The idea here is to use Xhr/Ws calls as a medium to manipulate DOM, so that every Xhr/Ws response contains  JS statements/Callback functions that are evaluated in the context of the DOM. 

This evaluation is influenced by:

  • synch DOM mutations that occurred in the middle of call processing

  • xhr/ws references not disposed when client location page is navigated away

  • race conditions in request/response management

All these scenarios lead to memory corruption bugs in all tested browser, some of them exploitable.


Fuzzing with multiple scripting engines

Starting with IE9, Jscript9.dll is the default scripting engine for JavaScript code. 

However, each script block in a html page can declare, using the "language" property, a different scripting enging to use. 

Possible values, deprecated but still avaliable are: 

  • JScript.Encode

  • VBScript

If the language property is not set, browser loads Jscript9 engine by default. 

Since Jscript.Encode mode is not supported on Jscrip9 engine, when IE9/10/11 encounters a script block marked as Jscript.Encode, IE loads Jscript legacy engine (v.5.8) to decode and execute scripts. 

So IE can hosts both Jscript9 and Jscript engine at runtime, and both engines can talk to the other one.

Similarly to Jscript.Encode, JavaScript can also reference object in VBScript engine.  

So the host  process (iexplore.exe) can initialize several JavaScript engines, and objects created into an engine context can reference objects from any other engine context (JavaScript, Jscript.Encode or VBScript): E.g. An iframe can load an HTML page with a SCRIPT block initialized as JScrpt.Encode or VBScript while the main page scripts run using JScript engine.


When dealing with multiple engine contexts, a given script engine does not have the knowledge of objects status from other contexts: objects could be deleted on the other context, or the whole child frame engine could be deleted as child frame may get closed or navigated away to other sites.

So it's essential to solidly manage cross contexts referecences to avoid access to illegal memory.


In my tests I found that these scenarios are far from being managed in a secure way, causing several memory corruption bugs even in the latest IE 11 version.


Fileja fuzzer

I've been running this fuzzer since 5 months now, and I've spotted something like 15 exploitable vulnerabilities in IE11, Chrome 36 and Safari; they are mostly DEP Violations & UAFs. Interestingly some of the vulnerabilities found on IE11 are still there (not still patched) and look quite exploitable even after the introduction of the delayed free in the MS June patch.


In the released fuzzer there is no logging logic (sorry guys, no spoon-feeding here...): you are free to plug your own logging code into the PoC.

Setup infos and suggestions are included in the README file in the fuzzer package.


For any doubt or info, you can drop me an email.