Kuboid
Open Luck·Kuboid.in
Black Hat2024
Open in YouTube ↗

Super Hat Trick: Exploit Chrome and Firefox Four Times

Black Hat1,883 views34:25about 1 year ago

This talk demonstrates four distinct remote code execution (RCE) vulnerabilities discovered in the V8 JavaScript engine and Firefox's SpiderMonkey engine. The researchers detail complex exploitation techniques, including type confusion, integer overflows in JIT compilers, and callback-based memory corruption. These vulnerabilities allow for arbitrary memory read/write operations, ultimately leading to full RCE in modern web browsers. The presentation provides deep insights into browser internals, object models, and the exploitation of JIT-related security flaws.

Exploiting Browser Engines: Lessons from Four Recent RCEs

TLDR: Recent research into V8 and SpiderMonkey internals has uncovered four distinct RCE vulnerabilities stemming from JIT compiler flaws and improper object model handling. These bugs, including CVE-2024-2854, demonstrate how modern browser optimizations like WebAssembly garbage collection can introduce critical memory corruption primitives. Pentesters should prioritize auditing complex JavaScript object interactions and JIT-compiled code paths to identify similar type confusion or integer overflow patterns.

Browser security research has shifted from simple memory corruption to the complex, high-stakes world of JIT compiler exploitation. When we talk about modern browser security, we are really talking about the security of the engines that power them: V8 for Chrome and SpiderMonkey for Firefox. The research presented at Black Hat 2024 highlights that even with massive investment in sandboxing and memory safety, the sheer complexity of optimizing JavaScript and WebAssembly execution creates a massive attack surface.

The Mechanics of Type Confusion and JIT Flaws

The core of these vulnerabilities often lies in the gap between how a developer writes JavaScript and how the engine optimizes that code for execution. In V8, the TurboFan compiler attempts to make code run faster by making assumptions about the types of objects it encounters. If those assumptions are wrong, or if they can be invalidated by a side effect, the engine can be tricked into performing operations on memory that it shouldn't access.

One of the most effective techniques discussed involves manipulating the internal object model of JavaScript sets and maps. By triggering a callback during a set operation, an attacker can force the engine to re-evaluate the state of an object while it is in an inconsistent, partially initialized state. This is a classic "callback issue" in runtime support. If the engine assumes a map is stable when it is actually being modified, it may use an outdated pointer to a memory region that has already been reallocated or cleared.

For those of us in the field, this means that any API that allows for user-defined callbacks—like those found in modern ES2015+ features—is a potential goldmine. When you are testing an application that relies heavily on complex data structures, look for ways to trigger state changes during the execution of built-in methods.

WebAssembly and the New Attack Surface

WebAssembly (Wasm) is no longer just a way to run C++ in the browser; it is a first-class citizen with its own garbage collection (GC) implementation. The introduction of Wasm GC has brought new types like struct and array into the browser's execution environment. As the research shows, the initialization logic for these new types is a prime target for security researchers.

The vulnerability in Firefox’s SpiderMonkey engine regarding WebAssembly instance initialization is a perfect example of a "regrettable" bug. Because the initialization order of these new types was flawed, it was possible to create an array with a controllable length but an incorrect memory allocation size. This leads to an out-of-bounds read/write primitive.

If you are performing a red team engagement or a deep-dive security audit, do not ignore the Wasm components of the target application. Use tools like emcc to compile your own test cases and observe how the browser handles memory allocation for different Wasm types. If you can control the size of an array during its initialization, you have already won half the battle.

Real-World Applicability for Pentesters

These vulnerabilities are not just theoretical exercises for conference stages. They represent the kind of bugs that bug bounty hunters are finding in the wild to achieve full RCE. On a standard penetration test, you might not be looking for a browser engine RCE, but you are likely interacting with applications that use these engines to perform heavy client-side processing.

When you encounter an application that uses complex, dynamically generated JavaScript or Wasm, treat the client-side code as a primary target. If you can find a way to crash the browser tab or cause unexpected behavior in the console, you might be looking at a JIT-related flaw. The impact of these bugs is absolute: once you have an arbitrary read/write primitive in the renderer process, you are one sandbox escape away from full system compromise.

Defensive Considerations

Defending against these bugs is notoriously difficult because they are inherent to the performance-critical code paths of the browser itself. For developers, the best defense is to avoid relying on non-standard or overly complex JavaScript patterns that might trigger edge cases in the JIT compiler. For blue teams, the focus must remain on rapid patching and ensuring that users are always on the latest version of their browser. The OWASP guidance on using vulnerable components is more relevant than ever here; if your users are running an outdated browser, they are essentially running unpatched, known-exploitable code.

Browser security is a cat-and-mouse game where the cat is constantly adding new features that the mouse can exploit. The shift toward more complex, high-performance features like Wasm GC is inevitable, but it comes with a cost. As researchers, our job is to keep digging into these internals, finding the gaps in the logic, and forcing the vendors to tighten their implementations before the bad actors do. Keep your eyes on the JIT, keep testing the edge cases, and never assume that the browser's sandbox is impenetrable.

Premium Security Audit

We break your app before they do.

Professional penetration testing and vulnerability assessments by the Kuboid Secure Layer team. Securing your infrastructure at every layer.

Get in Touch
Official Security Partner
kuboid.in