
أداة مراقبة مباشرة لجلسات PowerShell عن بُعد باستخدام ETW لالتقاط وفك ترميز بروتوكول WinRM/PSRP، مما يوفر تتبعات تنفيذ الأوامر وتسجيلها لتحليل الأمن.
توفر RemotePSpy مراقبة مباشرة لجلسات PowerShell عن بُعد، وهو مفيد بشكل خاص للإصدارات الأقدم (ما قبل 5.0) من PowerShell التي لا تتضمن مرافق تسجيل شاملة مدمجة.
تستخدم تتبع الأحداث لنظام Windows (ETW) للحصول على بيانات الرسائل من بروتوكول WinRM المستخدم كوسيلة نقل لـ PowerShell عن بُعد، وتقوم بفك ترميز طبقات البروتوكول المختلفة لتوفير تتبع لأوامر البرامج النصية المنفذة ومدخلاتها/مخرجاتها.
هذه حاليًا نسخة بحثية مبكرة، وبالتالي لا تدعم كل جوانب بروتوكول PowerShell عن بُعد (PSRP). ومع ذلك، يمكنها تقديم رؤى مفيدة حول ما يحدث في جلسة PowerShell عن بُعد.
أسهل طريقة للتثبيت هي باستخدام pip:
pip install remotepspy
يجب تثبيت التبعيات تلقائيًا عند التثبيت عبر pip، ولكن في حال رغبت في التثبيت من المصدر فهي مدرجة هنا:
ملف libwim-15.dll مطلوب فقط عند استخدام مزود ETW الخاص بـ Microsoft-Windows-WinRM (الموصى به والافتراضي) كمصدر بيانات. يُستخدم لفك ضغط كائنات تدفق معينة في بروتوكول WinRM/WSMan تحتوي على أجزاء رسائل PSRP. فقط ضعه في نفس الدليل الذي يحتوي على سكربت Python الرئيسي.
ما عليك سوى تنفيذ RemotePSpy لبدء المراقبة والتسجيل، ثم اضغط على مفتاح الإدخال (Return) عند الانتهاء. سيتم كتابة السجل في دليل العمل الحالي، باسم RemotePSpy.log.
ستقوم الأداة أيضًا بطباعة نسخة تقريبية لما سيراه مستخدم PowerShell عن بُعد على شاشته إلى stdout جنبًا إلى جنب مع المعلومات الأكثر تفصيلاً في ملف السجل. يتوفر تسجيل أكثر تعقيدًا، انظر "التسجيل" أدناه.
إذا قمت بتثبيت Python ليكون في PATH الخاص بك، فستكون نصوص RemotePSpy القابلة للتنفيذ أيضًا في PATH الخاص بك. وإلا فقد تحتاج إلى البحث عنها في دليل حزم موقع Python الخاص بك.
يستخدم RemotePSpy الافتراضي مزود ETW الخاص بـ WinRM (الموصى به) كمصدر بيانات. إذا كنت ترغب في استخدام مزود ETW الخاص بـ PowerShell بدلاً من ذلك، يمكنك تنفيذ RemotePSpy_powershell_prov.
قد ينتج هذا الإصدار بعض التحذيرات غير الضرورية بسبب التعقيد الإضافي لتتبع حالات معينة بناءً على كيفية تقديم البيانات في مزود ETW هذا تحديدًا.
يتكون الكود من عدد من الفئات المعيارية إلى حد ما والتي يمكنها قبول المدخلات على طبقات مختلفة في حزمة البروتوكول. وهذا يسمح بتوصيلها معًا بطرق مختلفة قليلاً اعتمادًا على مصدر البيانات وشكلها. تقبل معظم الفئات دالة استدعاء (callback) تستخدمها لتمرير النتيجة التي تنتجها إلى الطبقة التالية في الحزمة.
فيما يلي وصف للفئات الرئيسية المستخدمة، متبوعًا ببعض تدفقات المعالجة التي توضح أي فئة تغذي أي فئة أخرى في سيناريوهات مختلفة.
ETWWinRM – يحصل على أحداث ETW من مزود WinRM.
ETWPowerShell – يحصل على أحداث ETW من مزود PowerShell.
PowerShellETWParser – يحدد سياق Shell لأحداث ETW الخاصة بـ PowerShell، ويمرر بيانات الأجزاء إلى PSRPDefragmenter. كما يوفر مزامنة للخيوط.
SoapDefragmenter – يعيد تجميع رسائل WSMan SOAP الكاملة من أحداث ETW الخاصة بـ WinRM، ويمرر SOAP الكامل إلى WSManPS.
WSManPS – يقوم بتصفية WinRM غير المرتبط بـ PowerShell، ويتتبع سياق Shell، ويستخرج بيانات أجزاء PSRP من WSMan SOAP، ويمرر بيانات الأجزاء إلى PSRPDefragmenter.
PSRPDefragmenter – يعيد تجميع أجزاء PSRP إلى رسائل PRSP كاملة. يتم تجميع الأجزاء حسب ObjectID، ويتم ضمان تفرد ObjectID من خلال مراعاة سياق Shell. يمرر رسائل PSRP النهائية إلى PSRPParser.
PSRPParser – يفك ترميز رسالة PSRP الثنائية الخام، مستخرجًا تفاصيل الرأس مثل RPID وPipeline ID وMessageType. يمرر الرسائل المفكوكة إلى SimpleCommandTracer.
SimpleCommandTracer – يفسر رسائل PSRP باستخدام MessageType، ويستخرج ويطبع/يسجل الأوامر والوسائط ومخرجاتها. يتضمن فك ترميزًا جزئيًا لكائنات PowerShell المسلسلة. ليس تنفيذًا كاملاً لكل ميزة ممكنة، ولكنه يحاول تغطية معظم الحالات الشائعة للسماح بتتبع التنفيذ.
تدفق المعالجة عند استخدام مزود ETW الخاص بـ Microsoft-Windows-WinRM:
ETWWinRM -> SoapDefragmenter -> WSManPS -> PSRPDefragmenter -> PSRPParser -> SimpleCommandTracer
تدفق المعالجة عند استخدام مزود ETW الخاص بـ Microsoft-Windows-PowerShell:
ETWPowerShell -> PowerShellETWParser -> PSRPDefragmenter -> PSRPParser -> SimpleCommandTracer
يوجد تسجيل شامل في كل طبقة من طبقات حزمة البروتوكول. وهذا يسمح بتصحيح الأخطاء على مستويات مختلفة، وكان مفيدًا بشكل خاص أثناء التطوير. ونأمل أن يكون مفيدًا أيضًا لأي شخص يرغب في التحقيق في PowerShell عن بُعد أثناء العمل، حيث يمكن الحصول على تتبع كامل للبروتوكول في جميع الطبقات الرئيسية.
حاليًا، يجب تعديل الكود المصدري في نهاية السكربت حيث يتم تكوين المسجلات (loggers) لتغيير التسجيل. نأمل أن توفر الإصدارات المستقبلية طريقة أفضل لمثل هذا التكوين.
يتم تعريف كل اسم مسجل بواسطة ثابت، LOGGER_NAME، في الفئة التي تستخدمه. يتم تعريف كل مسجل كطفل لـ "RemotePSpy" (مثل RemotePSpy.etw). برمجيًا، يمكن تكوين المسجلات باستخدام logging.getLogger() مع اسم السجل المناسب.
كمرجع سريع، ستوفر لك المسجلات والمستويات التالية تتبعات للبروتوكول على طبقات مختلفة في البروتوكول:
لاحظ أن SimpleCommandTracer يخرج تتبعًا على stdout أيضًا، وهذا يحاول إلى حد ما محاكاة العرض كما سيراه مستخدم PowerShell عن بُعد. وهذا يختلف عن سجل تتبع الأوامر الذي يسجل كل أمر واستدعاء طريقة خط أنابيب ومخرجات خط الأنابيب بطريقة أكثر دقة، بما في ذلك سياق إضافي مثل RPID وPipeline ID.
فيما يلي ملخص أكثر اكتمالاً لما يظهر في كل سجل وفي أي مستوى:
ERROR:
WARNING:
INFO:
DEBUG:
DEBUG:
ERROR:
WARNING:
INFO:
DEBUG:
ERROR:
WARNING:
INFO:
DEBUG:
INFO:
DEBUG:
DEBUG:
ERROR:
DEBUG:
INFO:
| بيانات السجل الرئيسية | ثابت اسم المسجل | المستوى |
|---|
| تتبع الأوامر | SimpleCommandTracer.LOGGER_NAME | INFO |
| تتبع كامل لأحداث ETW | ETWWinRM.LOGGER_NAME | DEBUG |
| تتبع كامل لرسائل WSMan SOAP | SoapDefragmenter.LOGGER_NAME | INFO |
| تتبع كامل لكل جزء PSRP | PSRPDefragmenter.LOGGER_NAME | DEBUG |
| تتبع كامل لرسائل PSRP | PSRPParser.LOGGER_NAME | DEBUG |