The Apple Bug That Fell Near The WebKit TreeMarch 14, 2019 | Jasiel Spelman
Pwn2Own Vancouver is right around the corner so it seemed fitting to talk about an old Pwn2Own bug. Because we recently gave a presentation at OffensiveCon on how Adobe improperly patched some vulnerabilities, it seemed only fair to highlight how Apple has had similar issues.
The vulnerability was in the handling of regular expressions within a JIT-optimized function. If that sentence seems confusing, I'd recommend reading through some of our older blogs, perhaps starting off with this one.
Let’s start off by looking at this proof of concept:
The issue here was caused by the
Object with a custom
valueOf method that can get executed when executing the
This was patched in git commit
c46d3aa42a7c2940d68f9354e06034a587c2de03. Abstract interpreter and Data Flow Graph (DFG) clobberize were modified such that they always clobber state when executing
The patch definitely broke the submitted proof of concept, but unfortunately, there were still a couple of issues lurking in nearby code. As part of the patch, the
RegExpMatchFast operation was still explicitly allowed to execute without any clobbering of state. This operation is supposed to handle the
RegExp.match operation on objects known to be
In Pwn2Own Tokyo, the Fluoroacetate duo brought two Safari JIT vulnerabilities, both of which were also related to handling of RegExp operations within JIT-optimized functions. They're identified by ZDI-19-124/CVE-2019-6217 and ZDI-19-131/CVE-2019-6216.
The first one, identified by ZDI-19-124/CVE-2019-6217, was used as part of Fluoroacetate's iOS Wi-Fi chain. This vulnerability was so close to ZDI-18-606 that I initially worried they had collided, which would have made the chain a partial win at best.
Let's look at the proof of concept for this:
So, how did this not get caught by the patch for ZDI-18-606? The proof of concept for ZDI-18-606 has a
g at the end of it, which specifies that it is a global regular expression that is expected to find all matches rather than stopping at the first one. This difference is enough that it results in a completely different code path that got covered, while the code path handling regular expressions that are not global did not. This was patched in git commit
The second one, identified by ZDI-19-131/CVE-2019-6216, was used as part of Fluoroacetate's Safari chain, and is a variant of the two previously mentioned vulnerabilities.
Let’s look at the proof of concept:
The issue was that
JSArray::push() was being called every time the regular expression matched a portion of the string. As such, it was possible to set a custom mutator method on
Array.prototype in order to break assumptions made about the potential side effects of executing
RegExp.match. This behavior actually violates the spec and amusingly enough, there was an explicit test case in the WebKit repository to ensure this behavior existed. This was patched in git commit
7b9d7c94da59d85ab17ce2fe40056bc1cbbe0887 by removing the non-standard behavior.
There have been a number of Pwn2Own entries where at least one of the bugs in the chain ended up being the result of a failed patch. Now that we’ve covered one example, maybe you’ll find something to bring to a future contest. Maybe we’ll even see one next week. Until then, you can find me on Twitter at @WanderingGlitch, and follow the team for the latest in exploit techniques and security patches.