On the Trail to Mobile Pwn2Own

October 27, 2017 | Jasiel Spelman

Next week at the PacSec conference in Tokyo, we’ll be hosting our annual Mobile Pwn2Own competition. Some of the best security researchers in the world will attempt to exploit an Apple iPhone 7, a Google Pixel, a Samsung Galaxy S8, and a Huawei Mate9 Pro. Even though it’s a mountain of work updating, configuring and shipping all of the devices, we look forward to Pwn2Own because we see some innovative and often unexpected security research. More than once, research demonstrated at Pwn2Own has resulted in others investigating similar areas, leading to new cases and future Pwn2Own entries. This type of scenario took place at this year’s Pwn2Own in March when Chaitin Security Research Lab leveraged a bug inspired by a previous ZDI disclosure to exploit Apple Safari and win $35,000 in the process. Here’s how it played out.

The Inspiration

The folks at Chaitin Security Research Lab took notice of ZDI-15-570, a vulnerability in SQLite's fts3_tokenizer function that was reachable from a web browser thanks to WebSQL. By reviewing the advisory and the resulting patch from SQLite, they were able to find other similar bugs in SQLite. This is a common scenario, and it highlights why vendors should perform variant analysis on submitted bugs rather than rely on point fixes.

All of these bugs are present in code that exposes full text search for SQLite, which is implemented through the use of virtual tables. These bugs are particularly dangerous because they allow pointers to be passed around from potentially untrusted sources. Another thing making these bugs interesting is that WebKit's WebSQL Authorizer explicitly denied the creation of any virtual table except for an FTS3 virtual table. When combined with a lack of exploit mitigations in the browser, this allowed for reliable code execution in Safari.

The Execution

Chaitin had five bugs at their disposal to exploit Safari and began their exploit chain with ZDI-17-360, a type confusion bug resulting in the leak of a heap pointer. Now armed with a known pointer in the current process, there were four more type confusion vulnerabilities that they could leverage. Each of these bugs dereference untrusted pointers rather than leak a heap pointer. These were published under ZDI-17-366, ZDI-17-367, ZDI-17-368, and ZDI-17-369 but since they are all incredibly similar, I'm just going to talk about ZDI-17-366.

First let's look at how the optimize FTS3 function is implemented. Within ext/fts3/fts3.c, we can see the following:

The optimize() Function

This is a fairly straight forward routine. Any time we call optimize, we will immediately end up calling fts3FunctionArg. Let’s examine that helper function:

Helper Function

Thanks to the comments, we have the option of seeing the issue from either the code or the documentation! When the optimize function is run, the column being operated on must be a BLOB type and must be the size of a pointer to an Fts3Cursor structure. When that happens, the value in the BLOB will be treated as a pointer to an Fts3Cursor structure and returned to the calling function. Between the ability to leak a heap address and have a controlled address treated as a pointer, there is little stopping full exploitation of these bugs. Chaitin handled this by ensuring an error condition occurred such that sqlite3VdbeTransferError would be called on the controlled pointer. This allowed for controlled arbitrary reads. With that ability, they found the base address of the fts3Module structure, which is the structure that contains all the functions the FTS3 module implements. As a result, they were then able to modify the structure so that one more call into the fts3Module would call a controlled address leading to code execution.

The Fix

We disclosed this Safari bug to Apple as the target was Apple Safari and they had representatives at the contest for disclosure purposes. So how did they patch it?

Here's a snippet of WebCore/Modules/webdatabase/DatabaseAuthorizer.cpp from before the patch:

Pre-patch Code

And here's a snippet from after:

Post-patch Code

Rather than risk any current or future issues with SQLite3’s other virtual tables, they decided to just deny access from WebSQL outright. That should clear up any variants of this attack, as well.

The Future

Obviously, we have no idea what the results of next week’s contest will be. We do know we have several contestants already registered, and we expect multiple devices will be tested at least once. What types of research inspired these exploits? What new research will result from this year’s contest? Stay tuned to this blog and our Twitter account for all the details of the contest as it occurs. And if you’re in Tokyo, we look forward to seeing you at the conference, which – based solely on the location – promises to be a heavenly experience.

You can find me on Twitter at @WanderingGlitch, and follow the team for the latest in exploit techniques and security patches.