Firecracker VM Escape: PwnEscape Part 2 Analysis

Overview of the Firecracker Escape

This exploit demonstrates a method to achieve root-level code execution on a host machine from within a Firecracker microVM. By leveraging a host memory primitive, an attacker can locate the Firecracker process, identify the active vCPU thread, and modify its saved register state to redirect execution upon returning from a KVM_RUN system call.

Locating the Host Process and vCPU Thread

The exploit chain relies on identifying the host-side resources associated with the guest. First, the guest places a unique nonce in a memory page, which is then located in host physical memory using Extended Page Table (EPT) walking. Once the host physical address (HPA) of this page is identified, the attacker uses the host's page tables to perform a reverse mapping, identifying the Firecracker process and its page global directory (PGD).

With the host PGD and the Firecracker binary's load bias (determined by identifying the ELF image via ASLR-resilient mapping), the attacker can inspect the process's memory. The final step in this phase is finding the pt_regs structure for the active vCPU thread. The attacker searches for a frame that matches the expected KVM_RUN ioctl state, including specific instruction pointers, stack pointers, and file descriptors associated with the running microVM.

Redirecting Execution and Payload Delivery

Once the saved register frame is located, the attacker modifies the thread's execution context to inject a malicious payload. By overwriting the saved instruction pointer and stack data, the attacker forces the Firecracker process to execute a write(2) call to its own stderr, effectively proving control.

To ensure stability, the exploit uses a return-oriented approach:

  1. The thread is redirected to a write wrapper to execute the chosen operation.
  2. The return value is cleared using a xor eax, eax; ret sequence to prevent the original KVM_RUN logic from failing due to unexpected return values.
  3. The thread is returned to its original execution path, and the temporary stack modifications are restored to prevent the VMM from crashing.

Security Context and Mitigations

The demonstration was performed on Firecracker v1.16.1 without the use of a jailer. It is important to note that Firecracker's production-grade containment, which includes the use of the jailer utility, seccomp filters, and namespace isolation, is designed to significantly reduce the impact of such escapes.

"A properly jailed and configured firecracker instance would greatly reduce the blast radius of this escape... I'd hope most production firecracker deployments would be doing this already. Not saying that this is any less severe and the root issue is not specific to Firecracker, but to a flaw in the kernel's network code -- they just used an insecure firecracker configuration to demonstrate it." — Commenter @scoodah

While this exploit demonstrates a powerful primitive, its success in a production environment depends on the effectiveness of the host's sandboxing configuration. The underlying vulnerability highlights the risks associated with memory access primitives that allow a guest to interact with host-side process memory.

Sources

Related