
تحليل تقني مفصل واستغلال إثبات المفهوم لـ CVE-2024-30051، وهو تجاوز سعة المخزن المؤقت في الكومة في مكتبة DWM Core لويندوز مما يتيح تصعيد الامتيازات المحلية إلى مستوى Integrity System.
في هذه التدوينة، سأشرح ثغرة في مكتبة DWM الأساسية لنظام Microsoft Windows قمت بتحليلها أثناء تطوير استغلال لـ Core Impact. تسمح للمهاجم غير المصرح له بتنفيذ تعليمات برمجية كمستخدم DWM بصلاحيات نظام التكامل (Integrity System) (CVE-2024-30051).
نظرًا لعدم توفر معلومات عامة كافية في ذلك الوقت لتطوير الاستغلال، اضطررت إلى إجراء هندسة عكسية كثيرة، لذا سأعرض هنا كيفية إجراء الهندسة العكسية للتصحيح KB5037771 لنظام Windows 23H2 باستخدام IDA PRO. سأستخدم BINDIFF لإجراء مقارنة ثنائية بين dwmcore.dll الإصدار 10.0.22621.3447 والإصدار 10.0.22621.3593، وسأشرح كيفية حدوث تجاوز سعة الكومة (heap overflow)، ثم سأستغله لرفع الامتيازات، وأخيرًا سأُنشئ PoC عملي.
الفهرس:
[Windows DWM Core Library Elevation of Privilege Vulnerability (CVE-2024-30051) 1](#windows-dwm-core-library-elevation-of-privilege-vulnerability-cve-2024-30051)
[تفاصيل الثغرة: 2](#تفاصيل-الثغرة)
[المقارنة لاكتشاف الخلل: 3](#المقارنة-لاكتشاف-الخلل)
[تحليل PoC الذي يستغل CVE-2024-30051: 8](#تحليل-poc-الذي-يستغل-cve-2024-30051)
[1) التهيئة 8](#التهيئة)
[2) الحوكة (Hooking) 8](#الحوكة-hooking)
[3) إنشاء النافذة 16](#إنشاء-النافذة)
[4) إنشاء الجهاز 16](#إنشاء-الجهاز)
[5) إنشاء المصنع 22](#إنشاء-المصنع)
[6) إنشاء سياق الجهاز 28](#إنشاء-سياق-الجهاز)
[7) إنشاء جهاز التركيب 29](#إنشاء-جهاز-التركيب)
[8) استدعاء دالة hook3 31](#استدعاء-دالة-dcompositioncreatedevice)
[9) إنشاء هدف لـ HWND 32](#إنشاء-هدف-لمقبض-hwnd)
[10) إنشاء سطح 33](#إنشاء-سطح)
[11) استدعاء BeginDraw و EndDraw و CreateVisual 34](#استدعاء-begindraw-enddraw-و-createvisual)
[11) استدعاء Visual SetContent 36](#استدعاء-visual-setcontent)
[12) تحرير الكائنات 38](#تحرير-الكائنات)
[13) التزام جهاز التركيب 38](#التزام-جهاز-التركيب)
[14) استدعاء hook2 39](#استدعاء-hook2)
[15) استدعاء hook 39](#تذكر-أن-الدالة-القابلة-للاختراق-يمكن-الوصول-إليها-باستخدام-بعض-طرق-الفئة-cprimitivegroup.-في-هذه-النقطة-تنشئ-كومة-ثم-يقوم-hook2-بالتقاط-وحفظ-heaphandle-المناظر.)
[16) استدعاء hook4 41](#استدعاء-الدالة-hook4)
[17) تنفيذ رش الكومة (Heap Spray) 49](#تنفيذ-رش-الكومة-heap-spray)
[18) تعديل القطعة الأساسية قبل الإرسال 51](#تعديل-القطعة-الأساسية-قبل-الإرسال)
[19) تصحيح عملية DWM 52](#تصحيح-عملية-dwm)
[20) رفع الامتيازات إلى مستوى نظام التكامل 62](#رفع-الامتيازات-إلى-مستوى-نظام-التكامل)
ثغرة رفع الامتيازات في مكتبة DWM الأساسية لنظام Windows CVE-2024-30051
تاريخ الإصدار: 14 مايو 2024
CNA المخصص: Microsoft CVE-2024-30051
التأثير: رفع الامتيازات
الحد الأقصى للخطورة: مهم
الضعف:
CWE-122: تجاوز سعة المخزن المؤقت على الكومة (Heap-based Buffer Overflow)
CVSS: 3.1 7.8 / 7.2
توجد الثغرة بسبب خطأ في حساب الحجم في عملية قسمة عدد صحيح داخل مكتبة DWM الرئيسية لنظام Windows المسماة dwmcore.dll. يمكن لمستخدم محلي التسبب في تجاوز سعة المخزن المؤقت على الكومة في طريقة CCommandBuffer::Initialize في dwmcore.dll وتنفيذ تعليمات برمجية عشوائية كمستخدم DWM بصلاحيات نظام التكامل (Integrity System Privileges). سيقوم الاستغلال بتنفيذ رش الكومة (Heap Spray) في عملية DWM لتحضير الذاكرة وأخيرًا ينتج تجاوز سعة الكومة في dwmcore.dll والذي سيتم تشغيله عن طريق تحرير أجزاء معينة من رش الكومة.
بمجرد نجاح الاستغلال، ستقوم عملية DWM بتحميل DLL خاص بنا الذي ينفذ تعليماتنا البرمجية أو ملفنا التنفيذي (في حالتنا CMD) كمستخدم DWM الذي يمتلك صلاحيات نظام التكامل.

دعنا نستعرض هذه الثغرة ونرى كيف تسمح لنا بالعمل كمستخدم DWM بمستوى تكامل SYSTEM. لاحظ أنه نظرًا لأن هذا ليس مستخدمًا ينتمي إلى مجموعة المسؤولين، فإن لديه بعض القيود على الصلاحيات.
يمكن تنزيل التصحيح لنظام Windows 11 23H2 من:
https://www.catalog.update.microsoft.com/Search.aspx?q=KB5037771
windows11.0-kb5037771-x64_19a3f100fb8437d059d7ee2b879fe8e48a1bae42.msu
الإصدار الضعيف من dwmcore.dll هو: 10.0.22621.3447
الإصدار المصحح من dwmcore.dll هو: 10.0.22621.3593
من خلال تحليل الدوال المتغيرة، من الواضح أن الإصدار المصحح من CCommandBuffer::Initialize يحتوي على العديد من الكتل المضافة، مما يجعله يبدو مختلفًا تمامًا عن الإصدار غير المصحح.

بعد إجراء الهندسة العكسية الثابتة لتلك الدالة، هناك استدعاءان لـ CD2DSharedBuffer::GetBufferSize.
الاستدعاء الأول يحصل على الحجم الذي سيتم تخصيصه في new والاستدعاء الثاني يحصل على نفس الحجم لـ memcpy.

يبدو كل شيء صحيحًا في البداية. ومع ذلك، قبل التخصيص، يقوم بإجراء بعض العمليات على الحجم.

يحصل على buffer_size و buffer_size2 عن طريق استدعاء نفس الدالة CD2DSharedBuffer::GetBufferSize، ويعيد كلاهما نفس القيمة. لكن في new يقوم بعملية مسبقة، وهي قسمة عدد صحيح لـ buffer_size على 0x90 ثم ضرب الناتج في 0x90، بينما في memcpy يستخدم القيمة المعادة buffer_size2 دون إجراء أي عملية عليها.
بهذه العمليات، وجدت أن الحجم المستخدم في النهاية في new وفي memcpy يمكن أن يكون مختلفًا.
buffer_size = buffer_size2 (الأحجام المعادة)
size_new= buffer_size/0x90 x 0x90
size_memcpy=buffer_size2
على سبيل المثال، إذا كان buffer_size يساوي 0x91
buffer_size = buffer_size2=0x91
size_new= buffer_\ size/0x90 x 0x90 =0x90
size_memcpy= buffer_size2= 0x91
هذا المثال يثبت وجود تجاوز سعة الكومة. إنه ينسخ بايتات أكثر من المخصص، والحجم قابل للتحكم.
على سبيل المثال، إذا كان buffer_size يساوي 0x23f كما استخدم في POC.
buffer_size = buffer_size2=0x23F
size_new= buffer_size/0x90 x 0x90 =0x1b0
size_memcpy== buffer_size2=0x23f
مع تحليل الدالة القابلة للاختراق، أردت أن أرى كيفية الوصول إلى الدالة القابلة للاختراق CCommandBuffer::Initialize. هنا تبدأ الأمور في التعقيد.
بالنظر إلى المراجع لهذه الدالة، يبدو أنه يتم الوصول إليها من طرق الفئة CPrimitiveGroup:

يمكن الوصول إلى هذه الطرق من جدول الدوال الافتراضية (vftable) لكائنات CPrimitiveGroup:

لها منشئ (constructor):

ويتم الوصول إليها بهذه الطريقة:
