Provoking browser crashes with behavioral fuzzing

Original author: Gareth Heyes
  • Transfer
image

In this article, I will tell you how I used fuzzing to find several crashes in Firefox. Typically, the purpose of fuzzing is to find a failure that indicates memory corruption, but my goal is different: I want to detect an unexpected browser reaction. These can be characters that open or close an unusual tag, or possibly characters that are ignored by the JavaScript parser. Such an unexpected reaction can often be used to conduct XSS attacks, bypassing security filters and avoiding the JavaScript sandbox.

The first error I want to talk about is how to close the HTML comment in a different way. If you read the HTML specification, you know that a comment can be closed with -> or -!>. But how to do it differently? Great question to start fuzzing! You just need to generate the code that will give the answer.

Back in 2008, when I assembled ShazzerFor fuzzing browser behavior, I was limited to approximately 10,000 directions per page. Today, in 2019, everything works faster, so we can fuzz much more often. In addition, using the DOM speeds up fuzzing because you no longer need to add each direction to the current document. It is worth noting that this is an unreliable approach, since you can get different results. Indeed, I have found cases where the DOM allows null values ​​in attribute arguments such as href, but the HTML parser does not. These are still non-critical failures, but you cannot always trust the results to get a complete picture of what the HTML parser will do. However, in most cases it works, and it is much faster than HTML output from the server side.

The first step has already been taken - we have a question: "What characters can close the HTML comment?". To answer it, we need to use existing characters that will close the HTML comment and fuzz characters that we don’t know. The next step is to use appropriate fuzzing software. In my case, I use my Hackvertor tool , but using the local web server I can achieve the same results. The idea of ​​this tool is to put the input in the input field, convert the tags a bit, and do something with the output. Since we have nothing to convert, we can put our code directly in the output field. Therefore, click on the text output area and create an array for storing fuzzy characters and a div element for testing HTML:

log = [];
div=document.createElement('div');

Then we need to fuzz out more than 1,000,000 Unicode characters or, more precisely, 0x10ffff. A simple for loop is all we need:

for(i=0;i<=0x10ffff;i++){

Then we reuse the div element that we created for each character. In this case, I test the position after! So that the character will be entered after! .. Then I use the img element to see if fuzzing was successful. If this element exists, then the HTML comment has been closed, and we have some interesting characters!

div.innerHTML = '-->';

Finally, with querySelector we check if img exists and add characters to the logs. Then I close the if statement and the for loop. Finally, I enter the results in the input field on the left:

if(div.querySelector('img')){
 log.push(i);
 }
}
input.value=log

Here is the full version of the code. You need to open the URL in Firefox, and then put the input characters in the output field and click the “Execute JS” button to fuzz the characters. After completing fuzzing, you should see the numbers in the input field, they correspond to the character codes that were successful. At the time of writing, Firefox (version 67) still allows newline characters - \ n and \ r - after !, to close the comment. I was informed that this has been fixed in future versions of Firefox. So, the last stage of fuzzing is to build your payload, it's pretty simple. You need to replace the character code with the character and add the XSS payload:

 -->

You can use Hackvertor again to test its operation by pasting the above into the output field and then clicking “Test HTML”. A warning window should appear because Firefox (version 67) resolves the new line as part of the final comment.

So this allowed us to find a non-critical error in the Firefox HTML parser. Let's find another one! We need a new question: “What characters can open an HTML comment?”. Instead of going beyond the existing HTML comment, we will now use the HTML comment to go beyond the existing HTML attribute. As I'm sure, you all know that you can open an HTML comment with


Thus, the symbol that we fuzzy will be after the first hyphen. If the character successfully creates an opening HTML comment, it will comment on the div element and thus exit the title attribute. This time, when we run “Execute JS”, ​​we get two results in Firefox (version 67): “0.45”. Code 45 is expected because it is a hyphen, but 0 is a NULL character! This means that Firefox interprets the sequence.
document.body.innerHTML = '
';

Let's switch to JavaScript instead of HTML. I tested every browser and I'm sorry Mozilla, but Firefox is making some kind of game again. I was inspired by the fact that fuzzing from the jinmo123 tweet uses interesting new ES6 features to call functions without parentheses. The question I came up with for fuzzing was: "what characters are allowed after the in or instanceof operators?" Then we again create the code in Hackvertor, it follows a similar pattern, but this time does not use the DOM. First, create an array and a for loop:

log = [];
for(i=0;i<=0x10ffff;i++){

Then we will use eval instead of innerHTML to fuzz our values. First we need to use a try catch block to detect any exceptions caused by invalid characters.

try{
eval("/a/"+String.fromCodePoint(i)+"instanceof function(){}");

The eval function is used to see if our JavaScript is valid. If so, it will go to the next line; if not, it will throw an exception that will be noticed, and then go to the next character. The next line simply registers the character, and then closes the try catch block and the for loop. The function then displays the results in the input field.

log.push(i);
}catch(e){}
}
input.value=log

If you run this code using "Execute JS", you will get a bunch of results! Firefox ignores many characters. If you try the code on Chrome, you will get more reasonable results. Find the character code in the input field that you want to use, in my case it was “1114110” or “0x10fffe” in hex. Now we will create our JavaScript vector:

eval("1337"+String.fromCodePoint(1114110)+"in"+String.fromCodePoint(1114110)+"alert(1337)");

You can also imagine it inside the SVG script:



The latest dual-processor configurations of dedicated servers with 2019 Intel Scalable processors are available on DEDIC.SH :
  • 2x Xeon Silver 4214 - a total of 24 cores
  • 2x Xeon Gold 5218 - a total of 32 cores
  • 2x Xeon Gold 6240 - configuration with 36 cores.

The cost of a server with two Xeon Silver 4214 - from 15210 rubles / month
. We are also ready to collect any configuration for you - write to us !

If large powers of a dedicated server are not required - VDS from 150 rubles / month is what you need!

Also popular now: