Quickly Pwned, Quickly Patched: Details of the Mozilla Pwn2Own Exploit

April 05, 2018 | Vincent Lee

At our recent Pwn2Own 2018 competition, Richard Zhu (fluorescence) targeted and successfully exploited Mozilla Firefox with only one bug. After handing over the bug to Mozilla at the contest, they have promptly coordinated an update in less than 24 hours. The response was certainly impressive, but I wanted to take a closer look at the exploit Richard used in the contest.

The Vulnerability

The out-of-bounds write vulnerability lies in libvorbis, which is the reference implementation for Vorbis audio codec decoding. This vulnerability is identified by ZDI-18-263 (CVE-2018-5146) and located deep inside the audio synthesis process of the library. This bug can only be triggered by audio files with type 1 residue encoding, and the out-of-bounds write happens during the residue calculation. Let us look at the vulnerable function vorbis_book_decodev_add():

The heart of the vulnerability results from insufficient array bounds checking in the inner for-loop at line 407 (above). With a crafted Vorbis audio file specifying a sufficiently large book->dim, it is possible to make i greater than n and access the a[] array beyond its bounds in the inner for-loop at line 408.

In Richard’s crafted Vorbis file, he has set the book->dim to 96 and n (not shown) to 1. This allowed him to write past the a[] C array and overwrite other parts of the process memory.

The Fifty Thousand Dollar Exploit

To exploit this vulnerability, Richard sprays the heap with interleaved Javascript Arrays and ArrayBuffers. He loads the crafted Vorbis file to trigger the out-of-bounds write vulnerability to overwrite the length of the Array.  With the corrupted Array, Richard is able to freely read and write into the ArrayBuffer from the corrupted Array.  From there he constructed a fake Javascript Object and hijacked the vtable, used ROP to gain code execution, and launched the second stage of his exploit chain.

From the victim’s perspective, all they did was browse to a website and ended up compromised. From Richard’s perspective, his many hours of work and successful demonstration at Pwn2Own earned him $50,000 USD for this exploit chain.

The Patch

The patch for this vulnerability is straightforward, which likely aided in the speed of the response. The Xiph team added extra checks in the inner loop to guard against out-of-bounds access conditions. The team also removed manual loop-unrolling optimization and patched similar bugs in different residue decoding functions while they were at it.

Conclusion

The quick turnaround time for Mozilla to patch their software was truly amazing, especially since the vulnerability itself did not lie in their code base. You can learn more about how they pull off such an amazing feat in their blog. This bug also serves as a reminder of the large attack surfaces in browsers and an old 3rd-party library might just be the thin end of the wedge that gets the attacker in.

Stay tuned for future blogs detailing other bugs used in this year’s contest. Until then, you can find me on Twitter @TrendyTofu, and follow the team for the latest in exploit techniques and security patches.