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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2020-0796 — تحليل تقني وإثبات المفهوم لـ CVE-2020-0796 (SMBGhost)، ثغرة تجاوز عدد صحيح في ضغط SMBv3 تؤدي إلى تصعيد الامتيازات المحلية على Windows 10/Server. | Kitploit
أدوات/GitHubGitHub/datntsec/cve-2020-0796
تصعيد الامتيازاتتحليل الثغرات الأمنيةالاستغلالاستغلال الملفات الثنائية
GitHubdatntsec/cve-2020-0796

CVE-2020-0796

تحليل تقني وإثبات المفهوم لـ CVE-2020-0796 (SMBGhost)، ثغرة تجاوز عدد صحيح في ضغط SMBv3 تؤدي إلى تصعيد الامتيازات المحلية على Windows 10/Server.

عرض المستودع
14منذ 5 سنواتلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2020-0796


نظرة عامة:

تمت إضافة ميزة الضغط إلى SMBv3 بدءًا من إصدار نظام التشغيل Windows 10/Server version 1903، والتي تحتوي على ثغرة تجاوز سعة عدد صحيح (integer overflow) أكدتها Microsoft في 12/03/2020. تسمح للمهاجم بتنفيذ تصعيد الامتيازات المحلية (LPE) وتنفيذ التعليمات البرمجية عن بُعد (RCE). هنا سنتحدث فقط عن ثغرة LPE.

الإصدارات المتأثرة:

  • Windows 10 Version 1903 for 32-bit Systems
  • Windows 10 Version 1903 for x64-based Systems
  • Windows 10 Version 1903 for ARM64-based Systems
  • Windows Server, version 1903 (Server Core installation)
  • Windows 10 Version 1909 for 32-bit Systems
  • Windows 10 Version 1909 for x64-based Systems
  • Windows 10 Version 1909 for ARM64-based Systems
  • Windows Server, version 1909 (Server Core installation)

تحليل عملية فك الضغط (Decompress) لـ SMB:

تحليل ملف srv2.sys، نلاحظ أن الدوال المتعلقة بعملية فك الضغط (Decompress) يتم استدعاؤها كما يلي:``` js Srv2ReceiveHandler | | v Srv2DecompressMessageAsync | | v Srv2DecompressData -------> SrvNetAllocateBuffer | | v SmbCompressionDecompress | | v memcpy

أولاً، يتم استدعاء الدالة `Srv2ReceiveHandler` لاستقبال حزمة بيانات smb واستدعاء دالة مقابلة لبروتوكول `ProtocolId`. إذا كان `ProtocolId` = 0x424D53FC، فسيتم استدعاء الدالة `Srv2DecompressMessageAsync`، والتي ستقوم بدورها باستدعاء الدالة `Srv2DecompressData` لفك ضغط حزمة البيانات. تقوم الدالة `Srv2DecompressData` باستدعاء الدالة `SrvNetAllocateBuffer` لتخصيص `Alloc` لتخزين البيانات بعد فك الضغط، ثم تستدعي الدالة `SmbCompressionDecompress` لفك ضغط حزمة البيانات، وأخيراً تستدعي الدالة `memcpy`. وهكذا، تتكون عملية فك الضغط بأكملها من الخطوات الرئيسية التالية:
- 1. تخصيص (Allocate)
- 2. فك الضغط (Decompress)
- 3. نسخ (Copy)

وفقًا للوثائق التي توفرها Microsoft، يتم استخدام الهيكل `COMPRESSION_TRANSFORM_HEADER` لإرسال واستقبال البيانات المضغوطة بين العميل والخادم. وله الهيكل التالي:``` c
typedef struct _COMPRESSION_TRANSFORM_HEADER
{
   ULONG ProtocolId;
   ULONG OriginalCompressedSegmentSize;
   USHORT CompressionAlgorithm;
   USHORT Flags;
   ULONG Offset;
} ;

هنا نركز فقط على الحقلين الرئيسيين أعلاه وهما:

  • OriginalCompressedSegmentSize هو حجم مقطع البيانات غير المضغوط، بالبايت.
  • Offset هو الإزاحة بالبايت بين نقطة بداية البيانات المضغوطة ونقطة نهاية هيكل _COMPRESSION_TRANSFORM_HEADER.

وبالتالي، فإن حزمة البيانات المضغوطة ستبدو كما يلي:

``` c typedef struct _ALLOCATION_HEADER { // ... PVOID UserBuffer; // ... } ALLOCATION_HEADER, *PALLOCATION_HEADER;

NTSTATUS Srv2DecompressData(PCOMPRESSION_TRANSFORM_HEADER Header, SIZE_T TotalSize) { PALLOCATION_HEADER Alloc = SrvNetAllocateBuffer( (ULONG)(Header->OriginalCompressedSegmentSize + Header->Offset), NULL); If (!Alloc) { return STATUS_INSUFFICIENT_RESOURCES; }

ULONG FinalCompressedSize = 0;

NTSTATUS Status = SmbCompressionDecompress(
    Header->CompressionAlgorithm,
    (PUCHAR)Header + sizeof(COMPRESSION_TRANSFORM_HEADER) + Header->Offset,
    (ULONG)(TotalSize - sizeof(COMPRESSION_TRANSFORM_HEADER) - Header->Offset),
    (PUCHAR)Alloc->UserBuffer + Header->Offset,
    Header->OriginalCompressedSegmentSize,
    &FinalCompressedSize);
if (Status < 0 || FinalCompressedSize != Header->OriginalCompressedSegmentSize) {
    SrvNetFreeBuffer(Alloc);
    return STATUS_BAD_DATA;
}

if (Header->Offset > 0) {
    memcpy(
        Alloc->UserBuffer,
        (PUCHAR)Header + sizeof(COMPRESSION_TRANSFORM_HEADER),
        Header->Offset);
}

Srv2ReplaceReceiveBuffer(some_session_handle, Alloc);
return STATUS_SUCCESS;

}

تحليل الدالة `Srv2DecompressData`، نجد أن الدالة تستقبل حزمة بيانات مضغوطة `COMPRESSION_TRANSFORM_HEADER` (Header)، ثم تقوم بتخصيص منطقة ذاكرة (Alloc) باستخدام الدالة `SrvNetAllocateBuffer` مع معامل هو مجموع `Header->OriginalCompressedSegmentSize` + `Header->Offset`، ثم تقوم بفك ضغط البيانات المضغوطة ونسخ البيانات غير المضغوطة إلى `Alloc->Buffer`.

![](https://assets.kitploit.com/production/public/readmes/24501/a5bf8b5059336fb3677162343bace0d0b45085f2eb89e42d85f81e032fe233dc.png)

يحدث خطأ تجاوز سعة عدد صحيح (integer overflow) عندما تستدعي الدالة `Srv2DecompressData` الدالة `SrvNetAllocateBuffer`، حيث تستقبل الدالة `SrvNetAllocateBuffer` في الواقع قيمتين 64 بت، ولكن عند استدعاء `SrvNetAllocateBuffer`، تمرر إليها `Srv2DecompressData` قيمتين 32 بت فقط (ULONG). بينما كل من `OriginalCompressedSegmentSize` و `Offset` هما من نوع ULONG، وعند جمعهما معًا، قد ينتج رقم أكبر من 32 بت. ولهذا يحدث خطأ تجاوز السعة (ببساطة، عند جمع 0xffffffff (`OriginalCompressedSegmentSize`) مع 0x10 (`Offset`) ينتج القيمة 0xf0000000f ولكن الدالة `SrvNetAllocateBuffer` تستقبل فقط القيمة 0x0000000f).

![](https://assets.kitploit.com/production/public/readmes/24501/5ef540fac05ff782b005994410e1c43f18c0503fd134a57e1e6ed50c1fbc8219.png)

سيؤدي خطأ تجاوز السعة إلى تخصيص خاطئ لمنطقة الذاكرة Alloc (حجم التخصيص المطلوب أصغر من الحجم الفعلي)، مما قد يسبب خطأ تجاوز سعة المخزن المؤقت (buffer overflow):

![](https://assets.kitploit.com/production/public/readmes/24501/24c32abbbd764c35df1e73a00b5844711af77018cb54942a9738f5c9cac7ce4a.png)
تنزيل الأداة