Implementing Fuzz Logics with Dharma
January 31, 2019 | Mat PowellHello everyone. My name is Mat and I am a fuzzing addict.
I can’t stop. I’m constantly doing it and craving that next fix. I need it. I’m addicted to the thrill of the hunt -- the anxiety and anticipation for my fuzzers to report a crashing condition. Sometimes that sense of euphoria comes in a matter of seconds. Sometimes hours.
Sometimes days.
And sometimes not at all. And that’s when the withdrawal hits. Hard. So, what does a fuzzing junkie like me do in times like these? They start looking outside the realm of what is comfortable, looking for something to supplement (and even compliment) this addiction.
For me this was Dharma.
Dharma is a generation-based grammar fuzzer provided by Mozilla. It allows a user to define a template, known as a grammar file, then generate content for your pleasure. But how can this be used to give me that next hit? That next crashing condition?
In order to get there, we first need to take a step back. Over the last few months, a lot of my work and research has been focused around Foxit Software, and with good reason. In 2018 Foxit took the number one spot for published advisories through the ZDI program. This is not only great for the vendor to help them with hardening their application, but it also allows us to see some interesting trends and techniques that researchers are using in their efforts as well.
Let’s take a look at the proof-of-concept for ZDI-18-1157. This is a use-after-free in Foxit Reader using the createIcon()
method of a document object and was discovered by Trend Micro researcher Kamlapati Choubey.
The code above defines the array arg1
. Later, it defines a getter for the first item of the array with a callback function that executes app.activeDoc[0].closeDoc()
. It’s worth noting that app.activeDoc[0].closeDoc()
forces the Doc
object to be freed. Finally, createIcon
is called with arg1
being passed as the first argument. The createIcon
function iterates through arg1
which triggers the getter once it iterates over the first element of arg1
.
If we look at the crash generated by this proof of concept, we can see that ECX points to a freed heap object being moved into EAX, which is immediately used in a call statement showing the possibility of remote code execution.
So, using this proof-of-concept, how can Dharma help me find additional bugs using this logic?
First, we need to start by building our grammar file. This will be the “template” Dharma will use to generate our JavaScript content. Let’s look at a basic template:
A basic project consists of three sections: value, variable, and variance. The value section is where we will construct the format for the logic we intend to fuzz. If we needed to leverage any dynamic variables, the variable section is where we would define those. And finally, the variance section acts as the builder for the value section and is where we would also add additional logic for permutations of the generated logic. For this example, we’re going to be primarily focused on the value section. Let’s take a look at Dharma’s command line arguments
This looks pretty straight-forward. For the sake of simplicity, we’re just going to invoke Dhama with the -grammars
parameter, which should give us something like this:
Our definition instructs Dharma to print “hello” and then fill in the blank with something from one of the values defined under stuff.
Now, let’s get to work.
As a baseline, I’m going to be using the JavaScript for Acrobat API Reference from Adobe to help with generating my template for the addField()
method of a Document object. I started here for a couple of reasons. It was something I was comfortable with due to the amount of submissions coming into the program leveraging this method, it seemed flexible enough, and it seemed like a good project for me to start using Dharma. For the sake of your scroll wheel, the template we’re going to be creating today is extremely minimal and crude, but it’s perfect to highlight where Dharma shines.
According to the API documentation, addField()
takes four parameters and returns a Field object.
var foo = this.addField(cName, cFieldType, nPageNum, oCoords)
Here’s a description of these parameters from the Adobe documentation.
Based off of that, we construct a quick, crude representation of that with Dharma.
Passing this file into Dharma would yield results similar to this:
Next, we add just a couple of properties and surround them in a try/catch block. This will handle any issues with our generated JavaScript and continue processing the document in the event of errors. We then create a builder that will call addField()
with in the required parameters, and then attempt to set properties on the returned Field object.
Passing this expanded file into Dharma would yield results along these lines:
Finally, we need to add and implement the free aspect. We will modify our definition like this:
Last but not least, we need to specify our freed variable as a possible value in our template.
Passing the new grammar file into Dharma now provides us with output like this:
Now that we have a working grammar file, we can tell Dharma to generate JavaScript test cases to our heart’s content. Next, we take those JavaScript files and embed them in a PDF that we’ll ultimately feed into Foxit Reader. There are a couple of tools that can help automate this. Personally, I use PDF tools by Didier Stevens. Load up your testing harness and let ‘er rip.
Within a matter of seconds, we get our first crash. Once we minimize the POC we end up with this:
Taking a look at the crash, we can see that EBX references a freed heap object that is being placed into EAX and EAX is immediately used to execute a call instruction.
Conclusion
Dharma is a powerful, grammar-based fuzzer that should be a welcome addition to any fuzzers toolkit. Using similar techniques with different templates I was able to shake a couple more bugs free and reported them to Foxit as ZDI-18-1183, ZDI-18-1162, and ZDI-18-1208. Please keep in mind the grammar file used in this example was gutted significantly for ease of reading, but the principals are the same. With such a tool at your disposal, what will you fuzz next? And if you find anything great, be sure to submit it to our program!
Now if you’ll excuse me, I need to go get my next fix. ☺
You can find me on Twitter @mrpowell, and follow the team for the latest in exploit techniques and security patches.