Lessons From Pwn2Own Berlin 2025: Building a Hypervisor Escape
Notes from our Master of Pwn winning exploit chain: what worked, what we threw away, and the unreasonably useful primitive we found in the device-emulation path.
Table of Contents
At Pwn2Own Berlin 2025, STAR Labs took home Master of Pwn for a chain that escaped a major hypervisor from inside a guest VM. This is the short version of how we got there. Longer write-up to follow after all patches are deployed.
Target selection
We started with three candidate attack surfaces: the device-emulation path, the virtio back-ends, and the nested-virtualization code path. We picked device emulation because it sees the most attacker-controlled input per unit of code, and because prior research suggested the maintainers had been less aggressive about fuzzing it than the core dispatcher.
The primitive
The bug is a classic TOCTOU on a field read twice during a DMA operation. The first read validates a length field; the second read uses it. Race the second read and you write past the end of a fixed-size buffer on the host heap.
Shaping the exploit
The buffer sits adjacent to a dispatch table we can influence. Overwriting one function pointer in that table was enough for a one-shot hijack into a ROP chain we’d prepositioned earlier in the guest’s memory.
What didn’t work
We spent three weeks on a different primitive (an off-by-one in a string formatter) that we convinced ourselves was exploitable. It wasn’t. The heap layout on the production build left the overflow landing in an unused padding region. Lesson re-learned: verify the crash tells you what you think it does before investing weeks in shaping.
More details after the vendor patches land.