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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2023-36424 — تصعيد الامتيازات عبر تلف Windows Kernel Pool (clfs.sys) | Kitploit
أدوات/GitHubGitHub/zerozenxlabs/cve-2023-36424
تصعيد الامتيازاتتحليل الذاكرة الجنائيتحليل الثغرات الأمنيةالاستغلالاستغلال الملفات الثنائية
GitHubzerozenxlabs/cve-2023-36424

CVE-2023-36424

تصعيد الامتيازات عبر تلف Windows Kernel Pool (clfs.sys)

عرض المستودع
12923منذ 2 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

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

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

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

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

معلومات

==============

تلف في تجمع نواة ويندوز (clfs.sys) يؤدي إلى تصعيد الامتيازات. (CVE-2023-36424)

يحتوي هذا المستودع على تحليل تقني واستغلال عملي.

المؤلف: Nassim Asrir (@p1k4l4) || https://www.linkedin.com/in/nassim-asrir-b73a57122/

الثغرة

================

يوجد فيض في تجمع (pool overflow) في برنامج تشغيل المرشح الصغير clfs.sys. يمكن قراءة معلومات حول هذا على:

1 - https://googleprojectzero.blogspot.com/2021/01/hunting-for-bugs-in-windows-mini-filter.html

2 - https://www.zerodayinitiative.com/blog/2021/7/19/cve-2021-31969-underflowing-in-the-clouds

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

سنأخذ في الاعتبار إصدار clfs.sys 10.0.22621.2134 (ويندوز 11 22H2 22621.2215)

الدالة HsmFltProcessHSMControl مسؤولة عن معالجة FSCTLs الخاصة بمرشح السحابة. بالنسبة لعملية برمز 0xC0000003، فإنها ستستدعي في النهاية HsmFltProcessUpdatePlaceholder .

بعد بعض المعالجة، سيصل تدفق التنفيذ إلى HsmiOpUpdatePlaceholderDirectory ثم أخيرًا إلى HsmpRpCommitNoLock:

root@kitploit:~
__int64 __fastcall HsmpRpCommitNoLock(__int64 a1, __int64 a2, struct _FILE_OBJECT *a3, char a4, char a5)

{ .....

v26 = FileObject; LODWORD(v9) = HsmpRpReadBuffer(*(PFLT_INSTANCE *)(v164 + 32), FileObject, (unsigned __int16 **)&P); // [1*]

HsmDbgBreakOnStatus((unsigned int)v9);

if ( (_DWORD)v9 == -1073741195 ) .....

goto LABEL_55; }

if ( (v9 & 0x80000000) != 0i64 )

goto LABEL_9;}
 

if ( (*(_DWORD *)P & 0xFFFF0FFF) != dword_1C0027650 )// Is
Cloud Reparse Tag?
{
LODWORD(v9) = 0xC000CF0B;
.....
goto LABEL_54;
}
v32 = *((unsigned __int16 *)P + 2);
v9 = (unsigned int)HsmpRpValidateBuffer((__int64)P + 8, v32); [2*]
.....
Pool2 = ExAllocatePool2(0x100i64, 0x4000i64, 'pRsH'); // [3*]
v146 = (_DWORD *)Pool2;
v13 = (void *)Pool2;
if ( Pool2 )
{
v64 = v159_10;
v65 = Pool2 + 4;
if ( v8 && *((_WORD *)v8 + 7) > 0xAu )
v64 = *((_WORD *)v8 + 7);
v9 = Pool2 + 20;
v66 = (unsigned int *)(Pool2 + 12);
*(_OWORD *)v65 = 0i64;
*(_WORD *)(Pool2 + 16) = 0;
*(_WORD *)(Pool2 + 18) = v64;
*(_DWORD *)(Pool2 + 12) = 8 * v64 + 16;
*(_DWORD *)v65 = 'pReF';
memset((void *)(Pool2 + 20), 0, 8i64 * v64);
.....
if ( v8 )
{
v127 = 10;
if ( *((_WORD *)v8 + 7) > 0xAu ) // [4*]
{
if ( WPP_GLOBAL_Control !=
(PDEVICE_OBJECT)&WPP_GLOBAL_Control
&& (HIDWORD(WPP_GLOBAL_Control->Timer) & 1) != 0

&& BYTE1(WPP_GLOBAL_Control->Timer) >= 4u )
{
WPP_SF_qiq(WPP_GLOBAL_Control->AttachedDevice, v86,
v87, a2, *(_QWORD *)(v156 + 32), FileObject);
}
while ( v127 < *((_WORD *)v8 + 7) )
{
*(_QWORD *)(v65 + 8i64 * v127 + 16) = *(_QWORD
*)&v8[8 * v127 + 16];
memmove(
(void *)(v65 + *v66),
&v8[*(unsigned int *)&v8[8 * v127 + 20]],
*(unsigned __int16 *)&v8[8 * v127 + 18]); //
[5*]
*(_DWORD *)(v65 + 8i64 * v127 + 20) = *v66;
*v66 += *(unsigned __int16 *)(v65 + 8i64 * v127++ +
18);
}
}
}
.....
}

HsmpRpReadBuffer [1*] تسترجع بيانات نقطة إعادة التوجيه. تحتوي هذه البيانات على قيمة من نوع WORD *((_WORD *)v8 + 7) ، تحدد عدد العناصر المنظمة. كل عنصر يحتوي على حقل نوع (Type field) وحجم (Size) وإزاحة (Offset) لحقول البيانات.

أي نوع عنصر في أي مكان محدد بدقة مسبقًا. ولكن فقط للعناصر العشرة الأولى. على سبيل المثال، يجب أن يكون حقل النوع للعنصر الأول مساويًا لـ 0x7.

سينفذ برنامج التشغيل HsmpRpValidateBuffer [2*] للتحقق من البيانات المكتسبة. ثم سيتم [3*] تخصيص تجمع مقسم بصفحات (paged pool) بحجم ثابت 0x4000 بايت. وإذا كانت بيانات نقطة إعادة التوجيه تحتوي على قيمة Count أكبر من 10، فسيتم

نسخ بيانات العناصر بعد العاشر إلى هذا التجمع ذي الحجم الثابت [4*] دون أي فحوصات إضافية.

التحقق داخل HsmpRpValidateBuffer غير كافٍ، لأنه يتحقق فقط من أول 10 سجلات.

root@kitploit:~
__int64 __fastcall HsmpRpValidateBuffer(__int64 pBuf, unsigned int a2)
{
.....
v2 = a2 - 4;
pBuf2 = pBuf + 4;
LOBYTE(v5) = 0;
v6 = 0i64;
if ( a2 <= 4 )
v2 = 0;
v7 = 0;
v8 = *(_DWORD *)pBuf & 0xF;
if ( !v8 )
{
.....
return IsReparseBufferSupported;
}
if ( v8 > 1 )
{
....
}
v9 = 0;
v66 = 0;
if ( v2 < 0x18 )
goto ERROR_EXIT;
v9 = 1;
if ( *(_DWORD *)pBuf2 != 'pReF' )
goto ERROR_EXIT;
v9 = 2;
v10 = (unsigned int *)(pBuf + 0xC);
if ( (*(_BYTE *)(pBuf + 16) & 2) != 0 && *(_DWORD *)(pBuf +
8) != RtlComputeCrc32(0, (PUCHAR)(pBuf + 0xC), v2 - 8) )
goto ERROR_EXIT;
v11 = *v10;
v9 = 3;
if ( v2 < (unsigned int)v11 )
goto ERROR_EXIT;
v12 = *(unsigned __int16 *)(pBuf2 + 0xE);
v9 = 4;
if ( !(_WORD)v12 )
goto ERROR_EXIT;
v13 = 8 * v12 + 16;

v9 = 5;
if ( v13 >= v11 )
goto ERROR_EXIT;
v9 = 0x10000;
for ( i = 0; ; ++i )
{
v15 = *(unsigned __int16 *)(pBuf2 + 0xE);
if ( (unsigned int)v12 >= 0xA ) // [1*]
v15 = 10;
if ( i >= v15 )
break;
}

كما نرى [1*] سيتحقق الكود فقط من أول 10 عناصر ويتجاهل الحالة عندما يكون هناك سجلات أكثر.

الاستغلال

=================

حجم التجمع القابل للاستغلال هو 0x4000. الحجم هو مضاعف للصفحة وبالتالي سيتم استخدام تخصيص المقطع (segment allocation) [3].

للاستغلال، تم استخدام التقنية الموصوفة هنا [4]. استدعاء NtAlpcCreateResourceReserve سينشئ العديد من المقابض (handles) وكتابة واحدة منها بمؤشر إلى كائن _KALPC_RESERVE مزيف سيعطينا القدرة على الكتابة إلى عنوان نواة عشوائي.

لتحضير الذاكرة، نقوم بتخصيص تجمعات متتالية بحجم 0x4000 باستخدام الأنابيب (pipes) [5]. ثم سنقوم بتحرير كل تجمع ثانٍ، لتوفير مكان للمخزن المؤقت القابل للاستغلال.

Alt text

لقراءة عنوان نواة عشوائي، استغل التطبيق الأنابيب. لهذا الغرض سنقوم بكتابة مؤشر AttributeValue لبنية PipeAttribute.

Alt text

وبعد ذلك، يمكننا سرقة رمز النظام (system token) لكتابة رمز (token) في العملية الهدف.

شكرًا على القراءة.

تنزيل الأداة