Onix: Finding Pokémon in your Acrobat (Revealing a new attack surface)
October 02, 2018 | Abdul-Aziz HaririFinding new targets to audit is always fun. At the same time, it can be a challenging task –especially if we’re going to start auditing the target from scratch. It can also be quite tedious and time consuming. While going through the ups and downs of auditing a new target, I usually take some time off to check the status of my old buddies. And by old buddies I mean targets that I’m already familiar with. One of the targets that I always go back to and one that has a sweet spot in my heart is Adobe Acrobat Pro DC. The fact that it has so many features integrated, from image to document parsing and a lot more, makes it a great target.
Every year in preparation for Pwn2Own in March, I usually fly to Austin the week before the event to help with the preparation and setup. While waiting for the laptops to finish setup, I decided to have another look at Adobe Acrobat Pro DC, but this time I decided to look at new attack surfaces – ones that I’ve never touched or audited.
Everyone has their own approaches to finding new attack surfaces in a given target. That day I decided to keep it simple: investigate and audit the oldest DLLs. And that’s what I did. I went and sorted the DLL’s in Acrobat’s directory by date and found this gem:
So, Onix32.dll, anyone? (Not to be confused with an onix). In short, Adobe needed a solution to create indexes for searching purposes. It seems that they decided to use a solution provided by Lextek International.
From Lextek’s website:
Great, so far so good – but how is this library used? And what’s the attack surface there?
Onix32 is used to create index files. These index files are complex proprietary binary file formats. Adobe uses the API exposed by Onix32 to do things like create indexes, open indexes, search, etc.
The biggest question is this: How do these index files get parsed inside Adobe? I started looking at different plugins that Acrobat has and stumbled across Catalog.api
. The great thing about the Catalog object is that it exposes a JS API that we can interact with from inside a PDF:
…great? How does this even relate to Onix32? Well, on to some RE…
One of the functions the Catalog plugin is responsible for is opening indexes. It does that using the Onix32 API ixOpenIndex
:
Decompiled Code:
The interesting part of the whole thing is that it can be done through the GUI interface or through JavaScript:
You can even create sample index files for fuzzing purposes from the GUI interface, which is what I did initially.
Most of the index handling done from inside Catalog happens from inside one function I called IndexHandling
:
Armed with all this juicy information, I started thinking of ways to find vulnerabilities. I figured out that there are two things that can be done here:
1 - Audit the Onix32.dll
API usage inside Catalog.api
for vulnerabilities
2 - Write a wrapper for Onix32.dll
and fuzz the API from the DLL directly
Going after API usage vulnerabilities inside Catalog.api
at this point is trivial, given the amount of reversing done. In the end, I was able to find these remote code execution and info disclosure vulnerabilities: ZDI-18-958, ZDI-18-599, and ZDI-18-467.
We can also approach it differently from a fuzzing perspective by mimicking the way Catalog used the API’s. That by itself should not be a problem, because LexTek is generous enough to provide us with API documentation and even data types they’ve used:
The API reference can be found here.
Writing a wrapper for Onix32.dll to fuzz the API from the DLL should not be a problem at this point either, since we know how the API’s can be used, thanks to the help of LexTek’s documentation and code examples. I’ll leave this as an exercise for the readers. In the meanwhile, here’s a teaser of how fast it is to fuzz the DLL directly is:
Using the wrapper, I was able to find several bugs. One interesting vulnerability, ZDI-18-958, that I found (by fuzzing the API through the wrapper) was also found by Sebastian Apelt, who also was looking at this attack vector. Interestingly, Sebastian found another (even better!) way to trigger the index parsing. His way is much better than mine. He was also able to trigger the vulnerabilities from JavaScript but in both Reader and Acrobat Pro. Also, he was able to bypass certain mitigations that were set to restrict index parsing. (Keep an eye on the upcoming ZDI-CAN-6903, along with all the bugs he’s found when it gets released.)
Anyway, the vulnerability was in one of the Onix32.dll API’s, specifically in calling ixStartRetrievalSession
when parsing a malformed index file. While the end result is an untrusted pointer dereference, the bug in its nature is quite unique.
The vulnerability is basically an overflow of the IndexManagerT
object. Using a malformed crafted index file, we can overflow the IndexManagerT
object until we overwrite a FileClassT
pointer, which would later be dereferenced from inside PartitionReaderT::ReaderHeader
.
So how did I control this bug? In a ridiculous way. The value that we were overflowing with seems to be a counter of some sort that is fetched by calculating the number of certain objects. Luckily, I was able to increase this counter in a unique way – by replicating objects inside the index file:
The end result was as good as a Shawarma sandwich:
Conclusion
I thought we knew each other quite well, Acrobat. It turns out you’re always hiding stuff. It’s quite amazing how much you can find in targets that you thought you knew quite well. Finding new attack surfaces in an application is a bittersweet mix of pleasure and challenge at the same time. There are many more details about this research that we’re planning on releasing in the future (along with Sebastian) and possibly presenting the material somewhere. We’ve only scratched the surface here, and it seems as big as the entire Johto region. As always, kudos to Sebastian Apelt for taking things to the next level and pumping more bugs!
On to the next region attack surface! Until then, you can find me on Twitter at @AbdHariri, and follow the team for the latest in exploit techniques and security patches.
Pokémon © 2002-2018 Pokémon. © 1995-2018 Nintendo/Creatures Inc./GAME FREAK inc. TM, ® and Pokémon character names are trademarks of Nintendo.