
Ursachenanalyse und funktionierender Exploit für CVE-2026-78938, eine Typverwechslung in V8 TurboFan, die beliebiges Lesen/Schreiben innerhalb des komprimierten Heaps ermöglicht. Enthält Crash-PoC und zur Laufzeit adressierte Primitiven.
Root-Cause-Analyse und Exploit für CVE-2026-78938, eine Typverwechslung in der TurboFan-Lastentfernungsoptimierung von V8, die in Chrome 152.0.7977.64 (V8 15.2.124.18) behoben wurde. Der Fehler wurde als in freier Wildbahn ausgenutzt gemeldet.
Der Exploit verwandelt den Fehler in ein Out-of-Bounds-Float64Array und von dort
in addrof / fakeobj sowie beliebiges Lesen/Schreiben über den komprimierten V8-Heap.
Alles nach dem initialen Schreibvorgang wird zur Laufzeit lokalisiert — es gibt keine
fest codierten Heap-Offsets in der R/W-Phase.
50597b0bb48a — "[compiler] Invalidate tracked fields on
CheckMaps with instance migration"Getestet auf macOS arm64 gegen ein lokal gebautes d8 beider Versionen.
| Datei | Was es ist |
|---|
pocs/crash.js | Minimaler Auslöser. SIGBUS auf der verwundbaren Version, sauberer Exit auf der gepatchten. |
pocs/rw_final.js | Vollständiger Exploit, Stufe 1: Auslöser + OOB-Array. Eingefroren — siehe „Reproduktion" unten. |
pocs/logic_final.js | Vollständiger Exploit, Stufe 2: addrof/fakeobj/beliebiges R\W, zur Laufzeit von Stufe 1 geladen. |
WRITEUP.md | Vollständige Root-Cause-Analyse und Exploit-Hinweise. |
Baue die beiden d8-Versionen (siehe WRITEUP.md für die genauen Commits und GN-Argumente),
dann vom Repository-Root aus:
# Crash-PoC: SIGBUS auf vuln, sauber auf patched
out/vuln/d8 --allow-natives-syntax --homomorphic-ic --max-valid-polymorphic-map-count=4 pocs/crash.js
out/patched/d8 --allow-natives-syntax --homomorphic-ic --max-valid-polymorphic-map-count=4 pocs/crash.js
# vollständiges R/W: funktioniert auf vuln, bricht sauber auf patched ab
out/vuln/d8 --allow-natives-syntax --homomorphic-ic --max-valid-polymorphic-map-count=4 pocs/rw_final.js
Erwartete Ausgabe auf der verwundbaren Version:
[+] OOB Float64Array len=0x7f000004
[+] after write: victim2.z = 2.5
[+] fakeobj(hn|1) typeof=number
[+] ALL PRIMITIVES VERIFIED
Zwei Dinge sind wichtig:
--homomorphic-ic --max-valid-polymorphic-map-count=4 formen das polymorphe Map-Feedback, sodass
der Migrationspfad im optimierten Code genommen wird. Ohne sie tut der Auslöser
stillschweigend nichts.pocs/rw_final.js ist byte-eingefroren. Der einzelne korrumpierende Schreibvorgang
landet bei einem heap-relativen Offset, der davon abhängt, wo das Opfer-Array
allokiert wird, was wiederum von den exakten Bytes und dem Pfad des Skripts abhängt.
Das Bearbeiten der Datei (oder deren Umbenennung) macht den eingebackenen Offset
ungültig; WRITEUP.md dokumentiert, wie neu kalibriert wird. pocs/logic_final.js
wird nach dem Auslösen des Triggers geladen, kann also frei bearbeitet werden.pocs/rw_final.js, aus den oben genannten
Gründen.Dieses Repository dient Bildungs- und Verteidigungsforschungszwecken. Der Fehler ist im aktuellen Chrome gepatcht; Details sind im V8-Quellbaum öffentlich.