AMSI وحدث PowerShell 4104: كيف تعرف وش انشاف فعلًا، بدل اعتبار غياب التنبيه دليل تخفّي؟
شغلت أمرًا سليمًا في المختبر، واشتغل بدون تنبيه. هل هذا يعني أن نظام الحماية ما شافه؟ لا تقدر تجاوب من النتيجة وحدها. قد يكون الكود فُحص ولم يُصنف ضارًا، وقد يكون سُجل دون تنبيه، وقد تكون تنظر في قناة أحداث مختلفة عن إصدار PowerShell المستخدم. هذا المقال يرتب هذه الاحتمالات عمليًا، ويشرح AMSI وScript Block Logging وحدث 4104 كأدلة لها حدود. بنستخدم أمثلة قراءة محلية ونصًا غير حساس، ونتعلم كيف نربط الحدث بالجهاز والجلسة والوقت. الفكرة مفيدة في مختبرات Active Directory وCRTP لأنها تعلمك تفسير الأثر قبل كتابة استنتاج عن الرؤية أو المنع.

ابدأ من ثلاث نتائج مستقلة
النتيجة الأولى وظيفية: هل الأمر أكمل المهمة؟ الثانية تسجيلية: هل ظهر دليل عنه في المصدر الذي راجعته؟ الثالثة أمنية: هل صُنف النشاط وأنتج تنبيهًا أو منعًا؟ يمكن أن ينجح الأمر وتوجد عنه سجلات كاملة دون أي تنبيه، وهذا طبيعي لمثال سليم مسموح. ويمكن أن يُمنع ملف بسياسة تطبيق قبل أن تختبر بقية المسار.
خلنا نفترض دالة تعرض كلمة LabMarker-4104 ثم تنتهي. إذا نجحت، أنت أثبتت تنفيذ الدالة فقط. إذا وجدت نصها في حدث، أثبتت أن مصدر التسجيل المتاح لك احتوى النص. وإذا لم تجد تنبيهًا، لا تضف ادعاءً أن محرك الفحص لم يفحصها، لأن الحكم هذا يحتاج دليلًا مختلفًا.
اكتب هذه النتائج في أعمدة منفصلة أثناء التمرين. الفصل يمنع أخطاء شائعة في التدريب: تسمية كل سماح تجاوزًا، أو اعتبار كل حدث تنبيهًا، أو التعامل مع غياب لوحة محلية كغياب بيانات في المنصة المركزية. ومع الوقت يصير عندك وصف أوضح لما تختبره: التنفيذ، التسجيل، التصنيف، أو الاستجابة، بدل سؤال مبهم عن اكتشاف PowerShell.
كذلك حدد الجهة التي تنتظر الدليل منها. سجل محلي يختلف عن SIEM أو لوحة حماية طرفيات. قد تصل البيانات إلى أحدها دون الآخر بسبب إعداد التجميع. عبارة لم يظهر شيء لا تفيد إلا إذا عرّفت الشيء والمصدر والفترة التي بحثت فيها.
AMSI واجهة فحص، وليست سجلًا موحدًا لكل الأحداث
AMSI اختصار Antimalware Scan Interface. توفر طريقة للتطبيقات الداعمة لتمرير محتوى إلى محرك فحص مسجل. التطبيق يشارك في تقديم المحتوى، والمحرك يقيّمه، ثم يتعامل التطبيق مع النتيجة بحسب تكامله. لا تخلط هذا مع قناة Event Log عامة تضع فيها كل التطبيقات كل النصوص التي تعمل بها.
الصورة في المقال مخطط رسمي من Microsoft يوضح طبقات التطبيقات وواجهة الفحص ومزود المحرك. هي رسم تعليمي للمعمارية، وليست لقطة من مختبرنا ولا إثباتًا أن كل مزود حماية في مؤسسة يستخدم نفس تفاصيل التنفيذ المعروضة. مصدرها: https://learn.microsoft.com/en-us/windows/win32/amsi/how-amsi-helps .
في PowerShell على Windows، توضح Microsoft دعم تمرير ScriptBlocks إلى AMSI في الإصدارات المدعومة، مع تطور التكامل عبر النسخ. لذلك وثق إصدار النظام والمحرك والمنتج، ولا تبن تجربة على افتراض أن اسم PowerShell وحده يكفي لوصف كل البيئة. استخدام PowerShell 7 على منصة أخرى يحتاج مراجعة مختلفة عن Windows PowerShell 5.1.
السؤال المناسب للمراجعة هو ما دليل التكامل والنتيجة الذي يتيحه المنتج في هذه البيئة؟ لا تشغل عينات ضارة ولا تغير واجهة الفحص لكي تختبر الفكرة. مثال سليم يفيد في فهم السلسلة، أما اختبارات قدرات المنع فتحتاج برنامج اختبار منفصلًا متفقًا عليه مع فريق الدفاع ومصادر أدلة مناسبة له.
4104 يصف محتوى ScriptBlock وفق إعداد التسجيل
Script Block Logging يسجل محتوى ScriptBlocks عندما يكون مفعّلًا حسب إعدادات المحرك. حدث 4104 مرتبط بهذا المسار، لكنه لا يساوي تلقائيًا وقوع حادث أو صدور قرار مكافحة برمجيات ضارة. النص المسجل قد يكون أداة إدارة عادية أو تجربة تعليمية أو جزءًا من إجراء مؤسسي موثق.
اقرأ الحدث كدليل محتوى في سياق محدد. ما الجهاز؟ ما وقت الحدث؟ ما المعرف الذي يربط النص؟ وهل النص كامل أم جزء من عدة رسائل؟ لا تعتمد على سطر طويل في واجهة مختصرة وتظن أنه يمثل كل التنفيذ. كذلك محتوى التعريف لا يثبت دائمًا أن كل وظيفة في ذلك النص استُدعيت.
مثال عملي: تعريف دالة يحتوي أمر قراءة، ثم يستدعي المستخدم دالة مختلفة في نفس الجلسة. ظهور تعريف النص في السجل لا يثبت أنك راقبت نتيجة كل أمر داخله. تحتاج ربط الحدث بنشاط الاستدعاء أو نتائج التجربة أو مصادر إضافية إذا كان سؤال الاختبار يطلب ذلك.
هذا مهم في تقارير المختبر: اكتب لوحظ محتوى ScriptBlock، ثم وضح ما الذي تؤكده سجلات أخرى عن التنفيذ. لا تحول الدليل النصي وحده إلى قصة كاملة. كلما فصلت بين معالجة المحتوى وتنفيذ مسار منه والنتيجة النهائية، صارت استنتاجاتك أكثر قابلية للمراجعة وأقل اعتمادًا على التخمين.
القناة الصحيحة تعتمد المحرك
بالنسبة إلى Windows PowerShell، راجع Microsoft-Windows-PowerShell/Operational وفق دليل نسخته. وبالنسبة إلى PowerShell 7 على Windows، يوضح الدليل قناة PowerShellCore/Operational ومتطلبات تسجيل مزود الأحداث. قراءة قناة واحدة ثم إعلان غياب الأثر في إصدار آخر من أسرع الطرق للوصول إلى نتيجة خاطئة.
ابدأ بـ$PSVersionTable لتعرف المحرك الذي نفذ التمرين، ثم اطلب من مسؤول المختبر تأكيد قناة الأحداث وإعداد التسجيل الفعلي. لا تغير تسجيل المزود أو سياسة المؤسسة خلال اختبار القراءة؛ إذا كانت القناة غير موجودة، فهذه معلومة تشغيلية تحتاج مالكًا وإجراء إعداد منفصلًا، وليست دعوة لتجربة تجاوز.
خلنا نفترض أن زميلك استخدم powershell.exe وأنت استخدمت pwsh.exe. قد تكون واجهتا الأوامر متشابهتين، لكن اسم العملية والإصدار والقناة يختلفان. قارن الوقت والجهاز قبل مقارنة السجلات. إذا كانت إحدى الجلسات بعيدة، راجع جهة التنفيذ المناسبة بدل فحص جهاز العميل المحلي فقط.
أحيانًا المنصة المركزية توحد أسماء الحقول أو مصادر الأحداث بطريقة مختلفة عن Event Viewer. لذلك احتفظ باسم القناة الأصلي في ملاحظاتك، واسأل كيف يُحوّل في أداة التجميع. وجود Mapping واضح يوفر عليك تفسيرًا خاطئًا يقول السجل اختفى بينما هو موجود تحت مصدر أو نوع مختلف.
تمرين علامة نصية بدون أسرار
في جهاز مختبر يسمح بالإعدادات المطلوبة، اختر علامة فريدة مثل CyberPTS-Lab-Check-A، وحدد وقت البداية. استخدم نصًا بسيطًا محليًا: & { "CyberPTS-Lab-Check-A" } . هو ScriptBlock يعرض عبارة، ولا يتصل بهدف ولا يفتح ملفًا حساسًا. الهدف أن يكون عندك نشاط معروف يمكن ربطه بالأحداث.
بعدها راجع المصدر المصرح لك. مثال قراءة Windows PowerShell على نفس الجهاز: Get-WinEvent -FilterHashtable @{ LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104; StartTime=(Get-Date).AddMinutes(-15) } -MaxEvents 20 . وفي PowerShell 7 استبدل LogName بالقناة المناسبة إذا كانت موجودة ومسجلة. لا تفترض أن صلاحية المستخدم تسمح بقراءة كل سجل.
الأمر يضيق البحث بنوع الحدث والوقت والحد الأعلى للنتائج. ما زلت تحتاج قراءة النص والحقول وربطها بالعلامة، وقد لا تكون عشرون نتيجة كافية في جهاز مزدحم. وسع الفترة أو الحد وفق نشاط التجربة فقط، بدل سحب كل السجلات دون حاجة. لو ظهرت رسالة قناة غير موجودة أو رفض وصول، سجلها كما هي.
كرر التمرين بعلامة ثانية في جلسة جديدة إذا كنت تتحقق من وصول إعداد تسجيل جديد وافق عليه مالك المختبر. غير عاملًا واحدًا في كل مرة. بذلك تعرف أن الفرق مرتبط بالجلسة أو الإعداد، وليس نتيجة نص مختلف أو عملية مختلفة أو نقل التجربة إلى جهاز آخر.
النص الطويل يحتاج ربط أجزاء الحدث
قد تتوزع نصوص طويلة على عدة رسائل مرتبطة. لذلك عندما تقرأ 4104، راجع حقولًا مثل ScriptBlockId وMessageNumber وMessageTotal إذا كانت موجودة في مخطط الحدث. لا ترتب الأجزاء اعتمادًا على ترتيب عرض الواجهة فقط، ولا تجمع أجزاء من جلسات أو أجهزة مختلفة لأن بينها كلمات متشابهة.
استخرج أسماء الحقول من XML الذي يعرضه الحدث أو من أداة التجميع المعتمدة، بدل الاعتماد على موضع رقمي ثابت داخل Properties دون توثيق. تصميم قراءة يعتمد أسماء الحقول أسهل للمراجعة عند تغير الأدوات. ومع ذلك لا تعدل النص الناتج بحيث يبدو كأنه سطر أصلي واحد دون الإشارة إلى أنه أعيد جمعه.
خلنا نفترض جزءًا أول فيه تعريف مساعد، وجزءًا ثانيًا فيه تعليق، وجزءًا ثالثًا مفقودًا في التجميع. النتيجة الصحيحة أن الدليل جزئي. لا تعوض الجزء المفقود من نسخة الأداة على الإنترنت ثم تنسبه إلى السجل المحلي. يمكن مقارنة المصدر للمساعدة، لكن يبقى فرق واضح بين نص مرصود ونص متوقع.
في التقرير احتفظ بمعرفات الأحداث ومصدرها وتوقيتها، وضع نسخة منقحة مناسبة للجمهور. إذا كان هناك نقص في النقل إلى المنصة المركزية، فتلك ملاحظة تتعلق بتغطية التجميع. لا تكتب أن PowerShell لم يسجل الجزء إلا إذا راجعت المصدر المحلي المصرح وتأكدت من الحد الذي تستطيع إثباته.
عدم ظهور الحدث له أكثر من تفسير
قبل الحكم على الرؤية، راجع: هل التسجيل مفعّل للمحرك الصحيح؟ هل نفذت التجربة في جلسة تعكس الإعداد؟ هل تبحث على جهاز التنفيذ؟ هل الفترة صحيحة؟ وهل المصدر الذي تقرأه يحتفظ بالحدث أو يستقبله؟ هذه أسئلة تحقق مركزة، وليست قائمة لتغيير الحماية حتى تظهر نتيجة ترغب فيها.
قد يكون الحدث موجودًا محليًا ولم يصل إلى SIEM، أو وصل وتأخر فهرسته، أو عُرض دون النص الكامل. وقد ترفض صلاحية المراجع قراءة القناة. كل حالة تحتاج وصفًا مختلفًا. خلطها تحت لم يكتشف النظام يضيع فرصة إصلاح تجميع الأحداث أو أذونات القراءة أو ضبط التوقيت.
استخدم حالة مرجعية من نفس البيئة يوافق عليها الفريق: حدث معروف بزمنه ومصدره، ثم قارنه بالتمرين. إذا غاب الاثنان، فالمشكلة قد تكون في مسار الرؤية الذي تعتمد عليه. إذا ظهر المرجع وغاب التمرين، صار عندك سؤال أضيق عن إعداد أو نوع نشاط أو اختلاف الجلسة.
لا تعمم من مثال قصير إلى كل أدوات Active Directory. المثال يختبر تسجيل المحتوى الذي عالجته بيئتك في تلك المحاولة. أدوات أخرى قد تكون ثنائية أو تستخدم محركًا أو بروتوكولًا مختلفًا، فلا تسير كل أدلتها في القناة نفسها. حدد مصدر الرؤية المناسب لنوع الأداة قبل انتظار حدث لا تنشئه أصلًا.
السجلات نفسها ممكن تحتوي بيانات حساسة
زيادة التسجيل قد تجعل النصوص المدخلة أو معاملات الأوامر ظاهرة في الأحداث. لذلك لا تدخل سرًا في سطر تجربة ثم تصدر السجل كله لتثبت أن التسجيل يعمل. استخدم علامات وبيانات وهمية، وراجع المرفقات قبل مشاركتها. هذه عادة مهمة حتى في جهاز مختبر، لأن النسخ اللاحقة من المخرجات قد تنتقل إلى جمهور أوسع.
تشرح Microsoft Protected Event Logging لحماية محتوى حساس في التطبيقات الداعمة باستخدام تشفير مناسب، مع فصل مادة فك التشفير عن أجهزة التسجيل. لا يعني هذا أن عليك تغييره ضمن اختبار أداة؛ إعداد الحماية وإدارة المفاتيح مسؤولية تشغيلية تحتاج تصميمًا واختبارًا مستقلين.
بالنسبة إلى التقرير، اعرض الجزء الذي يثبت سؤال الاختبار فقط: اسم علامة، وقت، معرف حدث، وحالة وصول. إذا اضطررت إلى الاحتفاظ بدليل أصلي غير منقح، يكون داخل مخزن الأدلة المعتمد وحقوق وصول محددة، لا داخل مقال المجتمع. محتوى المقال التعليمي لا يحتاج بيانات مؤسسة حقيقية حتى يكون مقنعًا.
هذه النقطة تفرق بين زيادة الرؤية وتحسين التحقيق. جمع كل شيء بلا ضبط قد يخلق خطرًا جديدًا أو ضجيجًا يصعب تحليله. المطلوب دليل كافٍ مرتبط بسؤال معروف، وإجراء يحميه، وفترة احتفاظ تناسب الحاجة، مع وضوح حول من يستطيع قراءة النص ومراجعة نتائجه.
قالب ملاحظة عملي لفريق الدفاع
اكتب الملاحظة كواقعة يمكن تكرارها: نفذ حساب مختبر محدد ScriptBlock سليمًا في وقت معلوم، على جهاز معلوم وبإصدار موثق، ثم راجعنا قناة محددة. ظهرت النتيجة الوظيفية، وظهر أو لم يظهر حدث 4104 ضمن فترة البحث، وحالة وصوله إلى المصدر المركزي كانت كذا. لا تضف تفسيرًا غير مثبت.
بعدها حدد سؤال المتابعة. هل نحتاج مراجعة سياسة التسجيل؟ تأكيد مزود الأحداث؟ مقارنة المصدر المحلي والمركزي؟ أم معرفة سبب غياب التنبيه المتوقع من قاعدة معينة؟ كل سؤال له مالك ومصدر أدلة. بهذه الصياغة يستطيع الفريق العمل، بدل استقبال عبارة عامة مثل الأداة لم تُكتشف دون وصف للتجربة.
في إعادة الاختبار استخدم نفس نوع العلامة ونفس الجهاز والهوية، ودوّن الإعداد الذي تغير بإجراء معتمد. لازم تظل التجربة قابلة للمقارنة. إذا نقلتها إلى محرك آخر أو جلسة بعيدة أو جهاز مختلف، فهذه حالة جديدة تحتاج وصفًا مستقلًا حتى لو كان النص نفسه.
المعيار الجيد ليس أن يظهر تنبيه على كل نص، بل أن تحقق البيئة هدفها المتفق عليه: تسجيل كافٍ، تجميع صحيح، وتصنيف واستجابة مناسبين للنشاط. مثالنا يقيس جزءًا محدودًا من هذا الهدف، ولا يدعي تقييم نظام الحماية بالكامل. هذه الحدود تزيد جودة النتيجة لأنها توضح ما الذي تعلمته وما الذي بقي خارج التجربة.
المصادر والربط مع أدوات CRTP
من يفهم الفرق بين التنفيذ والفحص والتسجيل والتنبيه يستطيع قراءة نتائج أدواته بهدوء. في مختبر CRTP المصرح، لا تجعل عدم ظهور نافذة تحذير هدفًا للتجربة. اجعل هدفك فهم الأداة وسياقها وأثرها، ثم التحقق من الأدلة التي تتيحها البيئة. هذه مهارة مفيدة في الاختبار وفي التعاون مع فريق الدفاع.
مرجع المعمارية والصورة: https://learn.microsoft.com/en-us/windows/win32/amsi/how-amsi-helps . مرجع تكامل PowerShell الأمني: https://learn.microsoft.com/en-us/powershell/scripting/security/security-features . سجل PowerShell 7 على Windows: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_logging_windows . ولـWindows PowerShell راجع about_Logging حسب نسخته.
اربط هذا المقال بشرح التنفيذ في الذاكرة داخل المجتمع، ثم انتقل إلى App Control ووضع ConstrainedLanguage. هناك السؤال يختلف مرة ثانية: هل تسمح السياسة بهذا الكود، وبأي قدرات يعمل؟ ترتيب الأسئلة بهذا الشكل يمنعك من جمع كل آليات Windows تحت اسم واحد أو اعتبار كل رفض فشلًا في الشبكة.
قبل تجربة أداة جديدة، اكتب المحرك والهوية والهدف ومصدر الرؤية المتوقع. وإذا كانت النتيجة ناقصة، سمها ناقصة واطلب دليلًا مناسبًا. تعلمك من التجربة يزيد حين تفسر ما رأيته فعلًا، لا حين تبني قصة نجاح أو تخفٍ من غياب إشارة لم تكن تعرف أين يفترض أن تظهر.