Taking Control of VMware Through the Universal Host Controller Interface: Part 1
May 07, 2019 | Abdul-Aziz HaririPwn2Own is a heck of an amazing contest. Not only because of all the media and vibe that goes with it, but because of the caliber of skills that we see demonstrated. It’s also quite fascinating to see new people burst onto the scene with mad skills. Additionally, it’s nice to see more of the people involved in the CTF scene participate at Pwn2Own. This year, Fluoroacetate won the Master Of Pwn at Pwn2Own Vancouver with a grand total of $340,000 USD and a brand new Tesla Model 3. What’s amazing about the duo is that they started looking for bugs and writing the exploits in January.
As someone who’s interested in virtualization, I was quite excited to see their VMware exploits. This year, we modified the rules to not require the contestant to run the attempt from a normal user account. This gave the contestants more options in terms of bug hunting. As expected, they never fail to amaze me with their work. They were able to write two exploits for VMware. Both targeted the Universal Host Controller Interface (UHCI). The first was a heap-based overflow and the other was a race condition. Both vulnerabilities require Admin privileges on the guest OS to succeed. Also, what’s interesting about the exploit itself is that Amat Cama of the Fluoroacetate team is, in general, more comfortable writing tools/exploits from a Linux environment. So, during the demonstration, the exploit forced the machine to boot into Linux and then continued execution from there.
Throughout this blog post I will go over the heap-based buffer overflow vulnerability, which is one of my favorite Pwn2Own vulnerabilities.
The Bug
The nature of the bug is quite interesting. Initially, it is a heap overflow when handling specific UHCI requests sent to Bulk endpoints (these endpoints are used to transfer large amounts of data), but it also can be used to trigger an out-of-bounds write condition.
First, when the endpoint receives a frame for processing it fetches a Transfer Descriptor (TD) from the corresponding frame. A check is performed on whether there is an existing URB object. If no object exists, a new URB object is allocated through a function called “NewUrb”. So, what’s a URB object? At first, I was a bit confused with what URB stands for. The Intel UHCI spec [PDF] mentions that URB is USB Request Block, which is a valid structure. After some research, it turns out that the object returned from the NewUrb
function is a wrapper structure around a valid spec USB Request Block (URB). The TD’s type is checked along with the buffer size. If the TD type is 0xE1 (USB_PID_OUT), then the TD buffer is copied to a buffer inside the object returned from the NewUrb
function. If the TD object is of a different type, then it increments the buffer pointer (referenced in the code as purb_data_cursor
).
Triggering the bug is not hard. All that has to be done is craft a TD object with the right length set in the token attribute along with 0x1E/USB_PID_OUT
as the type. See the PoC code below:
The result is quite promising:
This crash highlights the heap-based buffer overflow condition. Nevertheless, if we want to reach the out-of-bounds write condition - crucial for the exploitation of the vulnerability - then we have to craft more TD’s with different types in order to increment the cursor. After that, we then craft another TD object of type USB_PID_OUT to trigger the write.
VMware addressed this bug rather quickly with VMSA-2019-0005. Originally, when I saw Fluoroacetate duo register for the Pwn2Own targets I thought that they would go after something we’d be more familiar with, like the e1000 network driver. Amat decided to target something totally different, in this case to avoid potential collisions with other contestants, which proved a wise choice. Kudos to Fluoroacetate for their awesome bugs, exploits, and their great fun spirit!
Stay tuned for my next blog covering the exploitation of this vulnerability. In that blog, we will cover how Amat abused 3D acceleration features to bypass ASLR, CFG, and achieve code execution. Until then, you can find me on Twitter at @AbdHariri, and follow the team for the latest in exploit techniques and security patches.