
إثبات مفهوم تعليمي لثغرة PrintNightmare (CVE-2021-1675/34527) مع حمولة محاكاة غير وظيفية، وتحليل تدفق الهجوم، وربط MITRE، وإرشادات الكشف، وخطوات المعالجة.
النوع: إثبات المفهوم — محاكاة (غير وظيفية) CVE: CVE-2021-1675 + CVE-2021-34527 CVSS: 7.8 (LPE) / 8.8 (RCE) الاسم المستعار: PrintNightmare تم التصحيح: يونيو/يوليو 2021 — KB5004945 أُضيف إلى CISA KEV: يوليو 2021
⚠️ الحمولة الخاصة بإثبات المفهوم هذا خيالية بشكل صريح وغير ضارة — فقط 4 بايتات من ترويسة DCE/RPC متبوعة باسم الدالة بنظام ASCII. لا تنفذ كودًا، ولا تثبّت برنامج تشغيل، ولا ترفع الامتيازات. الاستخدام حصريًا لأغراض التعلم وتطوير أنظمة الكشف.
Developed by: HKK$ cat ./vulnerability_summary.txtCVE-2021-1675، المعروف باسم PrintNightmare، هو ثغرة أمنية حرجة لتنفيذ التعليمات البرمجية عن بُعد ورفع الامتيازات المحلية في خدمة Windows Print Spooler. تسمح هذه الثغرة للمهاجمين بتنفيذ تعليمات برمجية عشوائية بامتيازات SYSTEM من خلال استغلال الدالة RpcAddPrinterDriverEx()، المستخدمة للتثبيت عن بُعد لبرامج تشغيل الطابعات دون التحقق المناسب من التحكم في الوصول.
صُنّفت في الأصل على أنها LPE (CVSS 7.8) وتم تصحيحها في تحديث Patch Tuesday لشهر يونيو 2021، ثم أعادت Microsoft تصنيف الثغرة على أنها RCE (CVSS 8.8) في 21 يونيو. لتجنب الالتباس، حصل ناقل RCE على معرّف جديد، CVE-2021-34527 — وكلاهما يُشار إليهما عادةً باسم PrintNightmare.
$ cat ./timeline.txtJun 08, 2021 Microsoft تنشر التصحيح الأولي في Patch Tuesday — CVE-2021-1675 (LPE, CVSS 7.8)
Jun 21, 2021 Microsoft تعيد التصنيف كـ RCE (CVSS 8.8)
Jun 29, 2021 باحثون ينشرون PoC عن طريق الخطأ — معتقدين أنها نفس الثغرة التي تم تصحيحها بالفعل
Jul 01, 2021 تم تخصيص CVE-2021-34527 لناقل RCE — المتميز عن LPE الأصلي
Jul 02, 2021 Microsoft تطلق تصحيحًا طارئًا خارج النطاق: KB5004945
Jul 2021 CISA تضيف إلى كتالوج الثغرات المستغلة المعروفة
استغلال نشط من قبل مجموعات برامج الفدية (Vice Society, Magniber, إلخ.)
$ cat ./architecture.txt┌──────────────────────────────────────────────────────────────────────────┐
│ PRINTNIGHTMARE — ATTACK FLOW │
│ │
│ المهاجم (مستخدم مصادق) WINDOWS PRINT SPOOLER │
│ (spoolsv.exe) │
│ 1. المصادقة بأي حساب ┌────────────────────────────┐ │
│ نطاق صالح │ يعمل كـ SYSTEM │ │
│ │ │ نشط افتراضيًا على جميع │ │
│ 2. الاتصال عبر RPC إلى │ أنظمة Windows، بما فيها │ │
│ named pipe \pipe\spoolss │ وحدات التحكم بالمجال DCs │ │
│ │ └──────────────┬─────────────┘ │
│ │ │ │
│ 3. استدعاء RpcAddPrinterDriverEx() │ │
│ مع مسار إلى DLL خبيثة ────────────────────────────────►│ │
│ (UNC: \\attacker\share\evil.dll) │ │
│ ┌────────────▼────────────┐ │
│ │ Print Spooler يقوم بتحميل│ │
│ │ برنامج التشغيل (DLL) │ │
│ │ كـ SYSTEM دون التحقق من │ │
│ │ المصدر أو السلامة │ │
│ └────────────┬────────────┘ │
│ │ │
│ ◄── RCE / LPE كـ SYSTEM ──────────────────────────────┘ │
│ مستخدم إداري جديد، reverse shell، │
│ نشر برامج فدية، إلخ. │
│ │
│ ───────────────────────────────────────────────────────────────────── │
│ إثبات المفهوم هذا: فقط اتصال TCP + 25 بايت → بدون RPC حقيقي → بدون استغلال │
└──────────────────────────────────────────────────────────────────────────┘
$ cat ./design_decisions.mdfake_rpc_payload = b"\x05\x00\x0b\x03RpcAddPrinterDriverEx"
هذه الحمولة يبلغ حجمها 25 بايت وتوضح مفهومين في وقت واحد:
البايتات 0-3: ترويسة DCE/RPC شرعية
| البايت | القيمة | المعنى |
|---|---|---|
\x05 | 5 | إصدار بروتوكول DCE/RPC (الإصدار 5 — معيار Windows) |
\x00 | 0 | الإصدار الفرعي 0 |
\x0b | 11 | نوع PDU: BIND — الخطوة الأولى في مفاوضات RPC |
\x03 | 3 | الأعلام: `PFC_FIRST_FRAG(0x01) |
البايتات 4-24: اسم الدالة بنظام ASCII
RpcAddPrinterDriverEx — اسم الدالة الثغرة، كنص عادي.
لماذا لا تعمل هذه الحمولة كاستغلال حقيقي؟
إن BIND RPC شرعي يتطلب، بعد ترويسة الـ 4 بايتات:
- max_xmit_frag (2 بايت)
- max_recv_frag (2 بايت)
- assoc_group_id (4 بايت)
- num_ctx_items (1 بايت)
- context_elem[] → Interface UUID الخاص بـ MS-RPRN:
{12345678-1234-ABCD-EF00-0123456789AB}
- transfer_syntaxes → NDR UUID
بدون هذا الهيكل، يرفض Windows الحزمة فورًا. الحمولة، في الواقع، هي مجرد تأكيد على الاتصال — "هل يمكنني الوصول إلى المنفذ 445 بهذه الحمولة الوهمية؟".
sock.connect((target_ip, 445))
لماذا 445 وليس 135 (RPC Endpoint Mapper)؟
يستخدم PrintNightmare SMB named pipe \pipe\spoolss كناقل — وليس RPC المباشر. التدفق الحقيقي هو:
1. اتصال TCP → المنفذ 445 (SMB)
2. مفاوضات SMB + إعداد الجلسة (مصادقة NTLM/Kerberos)
3. اتصال الشجرة → IPC$
4. فتح named pipe → \pipe\spoolss
5. DCE/RPC BIND → واجهة MS-RPRN
6. استدعاء RpcAddPrinterDriverEx() مع NDR marshaling
يحاكي إثبات المفهوم الخطوة 1 فقط — اتصال TCP الأولي — دون تنفيذ الخطوات 2-6.
sock.settimeout(5): مهلة 5 ثوانٍ تمنع إثبات المفهوم من التعليق على المضيفين الذين لا يستجيبون. مفيد للمسح السريع لتوفر المنفذ.
| الجانب | CVE-2021-1675 | CVE-2021-34527 |
|---|---|---|
| الناقل | محلي (LPE) | عن بُعد (RCE) |
| CVSS | 7.8 | 8.8 |
| المصادقة | حساب محلي | حساب نطاق مصادق |
| التصحيح | يونيو 2021 (Patch Tuesday) | يوليو 2021 (خارج النطاق KB5004945) |
| الدالة الثغرة | RpcAddPrinterDriverEx | RpcAddPrinterDriverEx |
| السيناريو | رفع محلي | RCE عن بُعد عبر SMB named pipe |
السبب الجذري في كلاهما هو نفسه: الدالة RpcAddPrinterDriverEx() تفشل في التحقق من مصدر ملفات برامج التشغيل، ولا تفرض قيود امتياز مناسبة لتثبيت برامج التشغيل، ولا تتحقق من صحة أو سلامة ملفات DLL التي يتم تحميلها.
$ cat ./mitre_mapping.ymltactic: Initial Access / Lateral Movement
- T1210 # Exploitation of Remote Services
# استدعاء RPC عبر \pipe\spoolss لمضيف بعيد
# يتطلب بيانات اعتماد نطاق صالحة
tactic: Privilege Escalation
- T1068 # Exploitation for Privilege Escalation
# مستخدم عادي → SYSTEM عبر Print Spooler
# CVE-2021-1675 (LPE): عملية محلية ترفع إلى SYSTEM
tactic: Execution
- T1569.002 # System Services: Service Execution
# DLL خبيثة يتم تحميلها بواسطة spoolsv.exe كـ SYSTEM
# يعادل تنفيذ كود عبر خدمة Windows
- T1055 # Process Injection
# DLL محقونة في سياق عملية spoolsv.exe (SYSTEM)
tactic: Persistence
- T1547.012 # Boot or Logon Autostart: Print Processors
# برنامج التشغيل المسجل يستمر بين عمليات إعادة التشغيل
# مخزن في: HKLM\SYSTEM\CurrentControlSet\Control\Print\