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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-54107 — تحليل السبب الجذري لثغرة CVE-2026-54107: استخدام بعد التحرير (use-after-free) في win32kfull.sys بنظام Windows، مع تصحيح أخطاء حالة السباق، والتحليل الساكن، ورؤى فرز MSRC، وبحث عملي في استغلال النواة. | Kitploit
أدوات/GitHubGitHub/pravin761/cve-2026-54107
التحليل الثابتتحليل الثغرات الأمنيةالاستغلالالهندسة العكسيةمصممي الأخطاءالأوراق والأبحاثالتعلم والتعليماستغلال الملفات الثنائية
GitHubpravin761/cve-2026-54107

CVE-2026-54107

تحليل السبب الجذري لثغرة CVE-2026-54107: استخدام بعد التحرير (use-after-free) في win32kfull.sys بنظام Windows، مع تصحيح أخطاء حالة السباق، والتحليل الساكن، ورؤى فرز MSRC، وبحث عملي في استغلال النواة.

112منذ 2 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

عندما لا يكون ValidateHwnd بوابة: التحليل الجذري لـ CVE-2026-54107

استخدام بعد التحرير (use-after-free) في إدارة دورة حياة النوافذ في win32kfull.sys — كيف وجدته، وكيف أقنعت نفسي بأنه حقيقي، وكيف بدت عملية MSRC فعليًا من منظور الباحث.

CVE-2026-54107 CWE-362 CVSS 8.8 MSRC 11xxxxx Bounty $8,000

كانت الساعة تقترب من الثانية صباحًا عندما توقفت الآلة الافتراضية المستهدفة عن الاستجابة لنبض المُنقِّح (debugger) وسقطت في نقطة توقف عند التعليمات التي قضيت أسابيع أُثبت أنها قابلة للوصول بالضبط. لم يكن تأكيدًا، ولا توقفًا بسبب تلف تجمّع — بل انتهاك وصول بسيط في مسار توزيع الرسائل، أثناء فك إشارة كائن كان قد هُدم بالفعل بواسطة خيط آخر.

تلك النقطة أصبحت CVE-2026-54107، الحالة 11xxxxx لدى MSRC، وتم إصلاحها في تحديث الأمان لشهر يوليو 2026 عبر 27 منتجًا من منتجات Windows.

هذا المنشور هو النصف غير الخاضع لقيود النشر من القصة: السبب الجذري، ولماذا هذه الفئة من الثغرات على ما هي عليه، والمنطق الذي أوصلني إليها. تبقى تفاصيل الاستغلال خارج النطاق.

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

  • 1. لماذا win32k، ولماذا كائنات النوافذ تحديدًا
  • 2. الرائحة التي جعلتني أتوقف
  • 3. السبب الجذري
  • 4. لماذا تصنيف التأثير على ما هو عليه
  • 5. التفنيد جاء أولًا — معظم المرشحين سقطوا
  • 6. التحقق: التحليل الساكن يمنح فرضيات، والمُصحح يمنح الحقيقة
  • 7. بشأن استخدام الذكاء الاصطناعي في أبحاث النواة
  • 8. الجدول الزمني لـ MSRC، بصراحة
  • 9. لمحة
  • 10. ما سأقوله لمن يبدأ
  • 11. ما التالي

1. لماذا win32k، ولماذا كائنات النوافذ تحديدًا

Win32k هو النصف الذي يعمل في وضع النواة من النظام الفرعي الرسومي في Windows. إنه قديم، وضخم، والأهم من ذلك — أنه يمكن الوصول إليه من سياقات من المفترض أن تكون غير موثوقة. هذه الخاصية الأخيرة هي السبب في بقائه هدفًا دائمًا للبحث على الرغم من عشرين عامًا من أعمال التحصين والتصفية وتقييد استدعاءات النظام.

داخل win32k، يكون كائن tagWND (PWND) مثيرًا للاهتمام بشكل غير عادي لأن عمره يُدار بأكثر من آلية واحدة في الوقت نفسه. النافذة هي:

  • مرجعية بالمقبض (handle)، عبر جدول مقابض المستخدم وعمليات البحث من نمط ValidateHwnd،
  • مرجعية بالمؤشر (pointer)، محمولة عبر الاستدعاءات المتداخلة وتوزيع الرسائل،
  • مرجعية ضمنيًا عبر علاقات الأصل/الفرع والمالك/المملوك والخيط/سطح المكتب،
  • ويتم هدمها عبر مسار تدمير يجب أن يفكك كل ما سبق بالترتيب الصحيح.

أي كائن له عدة مسارات إسناد مستقلة ومسار تدمير مشترك واحد يستحق القراءة بتمعن. هذا ليس ادعاءً بوجود ثغرة — بل هو استدلال إرشادي حول أين تستثمر وقتك.

2. الرائحة التي جعلتني أتوقف

ما جعلني أتوقف عند هذا المكوّن هو سطح الاستيراد. يستورد win32kfull.sys ثلاث بدائيات مرجعية كائنات مميزة من ntoskrnl:```c NTSTATUS ObReferenceObjectByPointer( void *Object, uint32_t DesiredAccess, POBJECT_TYPE ObjectType, char AccessMode);

NTSTATUS ObReferenceObjectByHandle( HANDLE Handle, uint32_t DesiredAccess, POBJECT_TYPE ObjectType, char AccessMode, void **Object, OBJECT_HANDLE_INFORMATION *HandleInformation);

NTSTATUS ObReferenceObjectByName(/* ... */);

ثلاث طرق للدخول، ومسار واحد للخروج عبر `ObfDereferenceObject`.

هذا لا يعني أن الكود خاطئ. إنه يعني أن **الخاصية الثابتة (invariant) موزّعة** — لا توجد دالة واحدة تملك *"هذا الكائن حي الآن،"* لذا تعتمد الصحة على اتفاق كل مستدعي على أي مرجع يحملونه وإلى متى يظل صالحًا.

الثوابت الموزّعة هي المكان الذي تعيش فيه حالات السباق، لأن السباق ليس أبدًا خللًا منطقيًا يمكنك رؤيته في دالة واحدة. بل هو خلل في افتراض مشترك عبر دالتين.

لذلك السؤال الذي بدأت أطرحه على كل دالة تلامس `PWND` لم يكن *"هل هذا الكود صحيح؟"* بل:

> **إذا نُفِّذ جسم هذه الدالة نفسه على خيطين بفارق بضع تعليمات، فأيُّهما يكون على خطأ؟**



## 3. السبب الجذري

الخلل هو **فجوة وقت-الفحص / وقت-الاستخدام (time-of-check / time-of-use) التي تقع بين تحرير المرجع وتفكيك الكائن** في مسار تدمير النافذة، دون مزامنة كافية مع مستهلك متزامن يتحقق من صحة المقبض.

عند تجريده إلى شكله الأساسي:```c
/* Thread A — teardown */
NtUserDestroyWindow(HWND hwnd)
{
    PWND pWnd = ValidateHwnd(hwnd);
    if (pWnd) {
        ObfDereferenceObject(pWnd);   /* reference released */

        /* <-- race window: object may become reclaimable here */

        FreeWindowObject(pWnd);       /* teardown proceeds on a pointer
                                         no longer guaranteed live      */
    }
}

لم يتم توفير أي نص في الإدخال (INPUT) لترجمته. يرجى إرسال المحتوى المطلوب ترجمته.```c /* Thread B — consumer, concurrent / NtUserMessageCall(HWND hwnd, UINT msg, ...) { PWND pWnd = ValidateHwnd(hwnd); / may resolve a handle whose object is mid-teardown */

if (pWnd->fnid == FNID_BUTTON)    /* use-after-free */
    ...

}

يجب أن يتحقق أمران حتى يكون لهذا أهمية، وقد تحقق كلاهما:

**(أ) النافذة حقيقية.** `ValidateHwnd` هي البوابة التي يُفترض أن تجعل الوصول المعتمد على المقابض آمنًا. إذا كان التحقق يمكن أن ينجح ضد كائن بدأ تفكيكه بالفعل، فهذه البوابة ليست بوابة — بل اقتراح.

**(ب) الذاكرة المحررة قابلة للتأثير من قِبل المهاجم.** الحقول التي تُقرأ مباشرة بعد التحقق تتضمن `fnid`، الذي يوجّه توزيع الرسائل. قرار التوزيع المُتخذ من ذاكرة مستعادة هو الفرق بين *"انهيار غير موثوق"* و*"انتهاك لحدود الأمان"*. هذا التمييز هو السبب الكامل لكون هذا CWE-362 مع تأثير تصعيد الصلاحيات (EoP) وليس خلل استقرار.

> إن **الفساد** الملاحظ هو استخدام بعد التحرير (use-after-free)؛ أما **السبب** فهو CWE-362، وهو تنفيذ متزامن يستخدم موردًا مشتركًا دون مزامنة صحيحة. هاتان عبارتان مختلفتان وMSRC تهتم بالثانية. **أبلغ عن السبب، وليس العرض فقط.**

### لماذا سباقات win32k أصعب هيكليًا مما تبدو

إذا كنت قد سبقت خللًا في أنظمة فرعية أخرى، فسوف يُحبِطك win32k، لأن البنية تقاومك بثلاث طرق محددة.

**النوافذ لها تقارب مع الخيوط (thread affinity).** تنتمي النافذة إلى الخيط الذي أنشأها. جزء كبير من النظام الفرعي مبني على افتراض أن الخيط المالك هو من يلمس الكائن، مما يعني أن النهج الساذج "أدر خيطين يستدعيان نفس الواجهة البرمجية" غالبًا لا يُحدث أي تداخل — أنت لا تخلق سباقًا، بل تخلق طابور انتظار. جعل مسارين يصطدمان فعليًا على نفس الكائن يتطلب فهم العمليات التي تنفذ فعليًا على خيط المتصل مقابل تلك التي تُمرَّر إلى خيط المالك.

**توزيع الرسائل يفرض تسلسلًا جزئيًا عليك.** الإرساليات (Sends) والمنشورات (Posts) تتصرف بشكل مختلف، والتوزيع عبر الخيوط يختلف عن التوزيع داخل نفس الخيط مجددًا. بعض ما يبدو فرصة للتوازي يُحوَّل بصمت إلى عملية مرتبة قبل أن يصل حتى إلى الكود الذي يهمك. إذا كنت لا تعرف أي فئة يقع فيها محفزك، فستستنتج أن السباق الحقيقي غير قابل للوصول — وهي نتيجة سلبية كاذبة تبدو مطابقة لـ"لا خلل هنا".

**القسم الحرج مختبئ في المتصل.** يعمل جزء كبير من النظام الفرعي تحت قفل خشن (coarse lock) يُكتسب أعلى بكثير من الدالة التي تنظر إليها. هذا هو أكبر مصدر وحيد لإهدار الوقت في تدقيق win32k: دالة لا تحتوي على أي مزامنة مرئية لكنها آمنة تمامًا لأن كل مسار إليها مُسلسَل بالفعل. **تغطية القفل خاصية عابرة للإجراءات.** يجب أن تصعد في مخطط الاستدعاءات، لا أن تقرأ الدالة فحسب.

تلك النقطة الثالثة هي السبب في أن *"لا يوجد قفل في هذه الدالة"* لا تساوي شيئًا تقريبًا كإشارة، والسبب في أن معظم العمل في هذا البحث أُنفق على قابلية الوصول بدلاً من العيب نفسه.

## 4. لماذا تقييم الأثر هو ما هو عليه
تنزيل الأداة