212 - Attacking VirtualBox and Malicious Chess
Two vulns in VirtualBox, an Out-of-Bounds (OOB) write in the TPM module and an OOB read in VGA. Both ultimately come from the Memory Mapped I/O (MMIO) read handlers.
OOB write in TPM 2.0 module
VirtualBox supports exporting the Trusted Platform Module (TPM) to the guest as an opt-in. If it’s enabled, it’ll emulate the MMIO for the TPM at 0xfed40000
. When accesses are made to the region, the respective read and write handlers will take the number of bytes accessed as cb
and use it to memcpy()
an attacker-controlled command response buffer into a uint64
on the stack. The read handler doesn’t ensure that cb <= 8
, and so by writing a value larger than that of a qword, you can get a stack-based OOB write. In this case, they used the fxrstor64
instruction from x87 support, which reads a 64-byte region to restore the FPU, MMX, XMM, and MXCSR registers. This could be used to smash the return pointer to get code exec on the host.
OOB read in VGA module
Again, the MMIO read handler of the VGA module is responsible for this bug. The read handler would use a guest-controlled address to index into the VGA frame buffer via ((uint32_t *)pThisCC->svga.pbVgaFrameBufferR3)[addr]
. While it tries to ensure addr
is in-range of the frame buffer, its accessed as a 32-bit int array, and so the indexing works out to 4 * addr
, leaving the bounds checking insufficient and allowing a heap-based OOB read.
Exploitation As the heap was unpredictable, they needed to do some heap shaping. It turns out the Host/Guest Communication Manager (HGCM) call object was a perfect candidate, as it was easily callable by the guest via invoking VM service calls and had a vtable pointer as well as linked list pointers for the previous and next object. By using the OOB read, they could leak a vtable and heap pointer, and chain with the OOB write to ROP.