Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-43805-analysis — تحليل ليوم واحد + إثبات مفهوم (PoC) لمعقّم CVE-2026-43805 (حالة تسابق في IOKit IODMACommand DriverKit RPC، CWE-362) | Kitploit
أدوات/GitHubGitHub/wtcyj/cve-2026-43805-analysis
التحليل الثابتتحليل الذاكرة الجنائيتحليل الثغرات الأمنيةالاستغلالالهندسة العكسيةالأوراق والأبحاثالتعلم والتعليم
GitHubwtcyj/cve-2026-43805-analysis

CVE-2026-43805-analysis

تحليل ليوم واحد + إثبات مفهوم (PoC) لمعقّم CVE-2026-43805 (حالة تسابق في IOKit IODMACommand DriverKit RPC، CWE-362)

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

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2026-43805 — سباق RPC في مشغّل IOKit IODMACommand DriverKit

تحليل ليوم واحد لحالة السباق في Apple IOKit التي تم إصلاحها في iOS/iPadOS 26.6، وmacOS Tahoe 26.6، وSequoia 15.7.8، وSonoma 14.8.8، وwatchOS 26.6. لم يكن هناك إثبات مفهوم عام عندما كُتب هذا، لذا فإن العمل هنا هو: تحديد الكود المُرقَّع من خلال قراءة مصدر XNU الأساسي، وشرح السبب الجذري وصولاً إلى الكائن المُحرَّر، وإعادة إنتاج العيب كنموذج أمين مُتحقَّق منه بأدوات التعقيم.

إشعار Apple مقتضب:

تمت معالجة حالة سباق عبر تحسين التعامل مع الحالة. قد يتمكن تطبيق من التسبب في إنهاء غير متوقع للنظام أو الكتابة في ذاكرة النواة.

مُصنَّف CWE-362 (تنفيذ متزامن مع مزامنة غير سليمة)، CVSS 9.8. الإشعارات: 128066 · 128067 · 128068 · 128071 · 128072.

أين يكمن العيب

يُعرَّض IODMACommand لإضافات DriverKit (dexts) عبر RPC. التطبيقات الخاصة بتلك النقاط الدخولية لـ RPC على جانب النواة هي طرق _Impl في iokit/Kernel/IOUserServer.cpp. يقود dext مخزن DMA عبر ثلاثة منها:

طريقة RPCالسطر (xnu-12377.121.6)هل تحتفظ بـ fInternalState->fDextLock؟
PrepareForDMA_Impl1009نعم — IOLockLock @1033، فتح القفل @1078
CompleteDMA_Impl1084نعم — IOLockLock @1096، فتح القفل @1118
PerformOperation_Impl1154لا — تقرأ fActive وfMemory دون قفل

القفل موجود. IODMACommand::init يخصصه (iokit/Kernel/IODMACommand.cpp السطر 342). اثنان من الأشقاء الثلاثة يأخذانه. الثالث لا يأخذه — والثالث هو الذي يُجري إلغاء الإشارة إلى واصف الذاكرة المشترك. هذا التفاوت هو الثغرة.

لا يزال xnu-12377.121.6 (macOS 26.x، أحدث وسم نشرت Apple مصدره) يُظهر PerformOperation_Impl غير المقفلة، لذا فهو الشجرة المعرّضة للثغرة؛ إصدار مصدر 26.6 الذي يحمل الإصلاح ليس عاماً بعد. المصدر ذو الصلة منسوخ في analysis/IOUserServer_excerpt.cpp.

السبب الجذري

يقوم PerformOperation_Impl بفحص زمني على fActive، ثم يستخدم fMemory:

    if (!fActive) {                        // time-of-check  (no lock held)
        return kIOReturnNotReady;
    }
    ...
    if (length > fMemory->getLength()) {   // time-of-use   (fMemory may be gone)
        return kIOReturnBadArgument;
    }
    ...
    copiedDMA = writeBytes(dmaOffset, buffer.data(), length);   // write into the mapping

CompleteDMA_Impl ينفّذ عملية التفكيك تحت القفل:

    IOLockLock(fInternalState->fDextLock);
    ...
    ret = clearMemoryDescriptor(true);     // see below
    ...
    IOLockUnlock(fInternalState->fDextLock);

وclearMemoryDescriptor(true) (السطر 455 في IODMACommand.cpp) هو ما يقوم فعليًا بتحرير الشيء الذي يكون PerformOperation على وشك الوصول إليه:

    if (fMemory) {
        while (fActive) {
            complete();                    // drains fActive to 0
        }
        ...
        fMemory.reset();                   // releases the IOMemoryDescriptor
    }

إذن التداخل الخطير هو:

  1. تمرّر PerformOperation_Impl الشرط if (!fActive) بينما لا يزال الأمر نشطًا.
  2. تأخذ CompleteDMA_Impl القفل، وتستنزف fActive، وتنفّذ fMemory.reset()، فتحرّر واصف الذاكرة وتتيح تحرير دعمه المثبّت أو إعادة استخدامه.
  3. تُجري PerformOperation_Impl، وهي لا تزال قيد التشغيل، إسنادًا مرجعيًا إلى fMemory الذي أصبح قديمًا في getLength() ثم في writeBytes().

ولأن PerformOperation لم تأخذ القفل قط، فإن الخطوة 2 حرة في أن تحلّ في الفجوة بين الخطوتين 1 و3. تنسخ writeBytes بايتات مقدَّمة من المستدعي إلى تعيين DMA تم تحرير دعمه — وبمجرد إعادة استخدام تلك الصفحة لتخصيص نواة آخر، فهذا هو "كتابة ذاكرة النواة" الذي يحذّر منه التنبيه. أصبْه على مسار القراءة بدلًا من ذلك فتحصل على قراءة استخدام-بعد-تحرير / إنهاء غير متوقع.

sequenceDiagram
    participant W as dext thread A — PerformOperation_Impl (no lock)
    participant O as dext thread B — CompleteDMA_Impl (holds fDextLock)
    W->>W: if (!fActive) → active, continue
    Note over W: passed the check, about to use fMemory
    O->>O: IOLockLock(fDextLock)
    O->>O: clearMemoryDescriptor(true): fActive=0, fMemory.reset()  ← FREE
    O->>O: IOLockUnlock(fDextLock)
    W->>W: fMemory->getLength() / writeBytes()  ← USE-AFTER-FREE

إعادة إنتاج الثغرة دون macOS عرضة للاستغلال

يتطلب تفعيل المسار الحقيقي وجود DriverKit dext موقّع بامتياز DriverKit من Apple على إصدار عرضة للاستغلال، وهو أمر غير قابل للوصول من مضيف Windows. بدلاً من ذلك، يعيد poc/race_model.cpp تنفيذ منطق الحالة المشتركة الدقيق للطرق الثلاث — نفس انضباط القفل، ونفس ترتيب الفحص-ثم-التحرير-ثم-الاستخدام — بحيث يمكن ملاحظة العيب مباشرةً:

  • تأخذ PrepareForDMA وCompleteDMA القفل (mutex)؛ بينما لا تفعل PerformOperation ذلك (ما لم تُبنَ باستخدام -DFIXED، الذي يضيف القفل الناقص الوحيد).
  • تُحرّر CompleteDMA الواصف (descriptor)، بما يحاكي fMemory.reset().
  • يشغّل حِمل اختبار السائق (driver harness) الدالة PerformOperation على خيط واحد والدالة CompleteDMA على خيط آخر، واضعاً عملية التدمير داخل نافذة التسابق بإشارة ذرّية (atomic signal) (للتوقيت فقط — فهي ليست أبداً قفلاً على الحالة المشتركة).
cd poc
bash run.sh

بناء مُعرَّض للثغرة:

  • يُبلِّغ ThreadSanitizer عن حالة تسابق على البيانات — operator delete داخل CompleteDMA يتسابق مع قراءة getLength() داخل PerformOperation، مع كون القفل (mutex) محتجزًا من قِبل المُحرِّر فقط. السجل الكامل: evidence/tsan_vulnerable.txt.
  • يُبلِّغ AddressSanitizer عن استخدام بعد التحرير في الكومة (heap-use-after-free): الكائن المُحرَّر في CompleteDMA يُقرأ في PerformOperation::getLength، وقد جرى تخصيصه في PrepareForDMA. السجل الكامل: evidence/asan_vulnerable.txt.
==ERROR: AddressSanitizer: heap-use-after-free ... in MemoryDescriptor::getLength()
freed by thread T0 here:   ... IODMACommand::CompleteDMA()  race_model.cpp:70
allocated by thread T0:    ... IODMACommand::PrepareForDMA() race_model.cpp:61

إصلاح البناء (-DFIXED، القفل المُضاف إلى PerformOperation): كلا المُعقّمين نظيفان وكل عملية تتسلسل بشكل صحيح مقابل الإنهاء. السجلات: evidence/tsan_fixed.txt، evidence/asan_fixed.txt.

هذا يُثبت أن حالة التسابق حقيقية في المنطق وأن القفل ضروري وكافٍ معًا. وهو ليس kernel panic حيًّا — انظر النطاق أدناه.

الإصلاح

اجعل PerformOperation_Impl يُمسك بـ fInternalState->fDextLock عبر فحص fActive وكل وصول إلى fMemory، تمامًا كما يفعل شقيقاه بالفعل. لم يُنشر مصدر Apple 26.6 بعد، لذا فإن analysis/patch.reconstructed.diff هو الإصلاح المُعاد بناؤه من نص الاستشارة ومن تماثل الشقيقين. عندما يصدر المصدر الرسمي، فإن مقارنة IOUserServer.cpp مع xnu-12377.121.6 ستؤكد (أو تصحح) ذلك.

النطاق والصدق

تنزيل الأداة