
غلاف بلغة C# لـ ETW يقوم بتسلسل بيانات الأحداث من وضع النواة ووضع المستخدم إلى JSON للبحث عن التهديدات وتحليل البرامج الضارة والاستجابة للحوادث، مع تكامل Yara وإرسال إلى Elasticsearch.
SilkETW & SilkService هما غلافان مرنان بلغة C# لـ ETW، يهدفان إلى تجريد تعقيدات ETW وإعطاء المستخدمين واجهة بسيطة لأداء البحث والاستبطان. بينما لكلا المشروعين تطبيقات دفاعية (وهجومية) واضحة، يجب اعتبارهما في المقام الأول أدوات بحثية.
لسهولة الاستهلاك، يتم تسلسل بيانات الإخراج إلى JSON. يمكن كتابة بيانات JSON إلى ملف وتحليلها محليًا باستخدام PowerShell، أو تخزينها في سجل الأحداث لنظام Windows، أو إرسالها إلى بنية تحتية تابعة لجهات خارجية مثل Elasticsearch.
لمزيد من المعلومات حول مستقبل SilkETW & SilkService، راجع قسم خارطة الطريق.
لمزيد من الخلفية حول SilkETW و SilkService، يرجى الرجوع إلى الموارد التالية.
تم بناء SilkETW على .Net v4.5 ويستخدم عددًا من مكتبات الطرف الثالث، كما هو موضح أدناه. يرجى الاطلاع على LICENSE-3RD-PARTY لمزيد من التفاصيل.
ModuleId Version LicenseUrl
-------- ------- ----------
McMaster.Extensions.CommandLineUtils 2.3.2 https://licenses.nuget.org/Apache-2.0
Microsoft.Diagnostics.Tracing.TraceEvent 2.0.36 https://github.com/Microsoft/perfview/blob/master/LICENSE.TXT
Newtonsoft.Json 12.0.1 https://licenses.nuget.org/MIT
System.ValueTuple 4.4.0 https://github.com/dotnet/corefx/blob/master/LICENSE.TXT
YaraSharp 1.3.1 https://github.com/stellarbear/YaraSharp/blob/master/LICENSE
استخدام سطر الأوامر بسيط إلى حد ما ويتم التحقق من صحة إدخال المستخدم في المقدمة التنفيذية. انظر الصورة أدناه لمزيد من التفاصيل.

تم إنشاء SilkService لأن عددًا كبيرًا من الأشخاص أرادوا تشغيل SilkETW بدون واجهة رسومية وأداء جمع ETW من مصادر متعددة في نفس الوقت. بينما هناك جاذبية واضحة لذلك، يجب مراعاة النقاط التالية.
بعد تجميع أو تنزيل حزمة الإصدار، يمكنك تثبيت الخدمة عن طريق إصدار الأمر التالي من موجه مرتفع.
sc create SillkService binPath= "C:\Path\To\SilkService.exe" start= demand
يستقبل SilkService ملف تكوين XML، "SilkServiceConfig.xml"، والذي يجب وضعه في نفس الدليل الذي يحتوي على ملف الخدمة الثنائي. يمكن رؤية مثال على ملف التكوين أدناه.
<SilkServiceConfig>
<!--
This is a user collector
-> Microsoft-Windows-DotNETRuntime
-> GUID or string based name
-->
<ETWCollector>
<Guid>45c82358-c52d-4892-8237-ba001d396fb4</Guid>
<CollectorType>user</CollectorType>
<ProviderName>e13c0d23-ccbc-4e12-931b-d9cc2eee27e4</ProviderName>
<UserKeywords>0x2038</UserKeywords>
<OutputType>url</OutputType>
<Path>https://some.elk:9200/NetETW/_doc/</Path>
</ETWCollector>
<!--
This is a user collector
-->
<ETWCollector>
<Guid>6720babc-dedc-4906-86b9-d0bc0089ec50</Guid>
<CollectorType>user</CollectorType>
<ProviderName>Microsoft-Windows-DNS-Client</ProviderName>
<OutputType>eventlog</OutputType>
<YaraScan>C:\Some\Path\RuleFolder</YaraScan>
<YaraOptions>Matches</YaraOptions>
</ETWCollector>
<!--
This is a kernel collector
-->
<ETWCollector>
<Guid>21ac2393-3bbb-4702-a01c-b593e21913dc</Guid>
<CollectorType>kernel</CollectorType>
<KernelKeywords>Process</KernelKeywords>
<OutputType>file</OutputType>
<Path>C:\Users\b33f\Desktop\kproc.json</Path>
</ETWCollector>
</SilkServiceConfig>
لاحظ أن كل عنصر ETWCollector يجب أن يكون له GUID عشوائي، يستخدم لأغراض التتبع والتسجيل الداخلي. يمكنك إنشاء GUID في PowerShell باستخدام الأمر التالي:
PS C:\> [guid]::NewGuid()
Guid
----
eee52b87-3f32-4651-b0c3-e7bb9af334aa
في وقت التشغيل، سيقوم SilkService بإنشاء مجلد فرعي "Logs" لتسجيل معلومات وقت تشغيل الخدمة. هذا مورد لا يقدر بثمن للاستعلام عن حالة الخدمة والتحقق من التحقق من صحة معلمات الخدمة ومراجعة معلومات الخطأ. يفضل SilkService الإغلاق بأمان إذا واجه أي نوع من الأخطاء، حتى لو كان هذا الخطأ لا يتطلب الإنهاء بشكل صارم. تم اتخاذ قرار التصميم هذا عن قصد لأنه ليست استراتيجية سليمة وجود جامعين معلقين أو تشغيل جزئي.
قم دائمًا بمراجعة سجل الخدمة إذا أوقفت الخدمة نفسها!
من الممكن دائمًا أن يحدث خطأ ما. راجع سجل الخدمة لمزيد من التفاصيل. بينما تم تكوين SilkService لإنهاء وتنظيف جامعي ETW أو الخطأ، فمن الممكن أن يظل جامع قديم مسجلاً بعد إنهاء العملية. لإدراج الجامعين قيد التشغيل، يمكنك استخدام الأمر التالي.
logman -ets
إذا تم تحديد أي جامعين قديمين، يمكن إزالتهم عن طريق إصدار الأوامر التالية من موجه مرتفع.
Get-EtwTraceProvider |Where-Object {$.SessionName -like "SilkService*"} |ForEach-Object {Stop-EtwTraceSession -Name $.SessionName}
Get-EtwTraceProvider |Where-Object {$_.SessionName -like "SilkService*"} |Remove-EtwTraceProvider
يتم تنسيق إخراج JSON، قبل التسلسل، وفقًا للهيكل C# التالي.
public struct EventRecordStruct
{
public Guid ProviderGuid;
public List<String> YaraMatch;
public string ProviderName;
public string EventName;
public TraceEventOpcode Opcode;
public string OpcodeName;
public DateTime TimeStamp;
public int ThreadID;
public int ProcessID;
public string ProcessName;
public int PointerSize;
public int EventDataLength;
public Hashtable XmlEventData;
}
لاحظ أنه اعتمادًا على المزود ونوع الحدث، سيكون لديك بيانات متغيرة في جدول التجزئة XmlEventData. يمكن رؤية نموذج إخراج JSON أدناه لـ "Microsoft-Windows-Kernel-Process" -> "ThreadStop/Stop".
{
"ProviderGuid":"22fb2cd6-0e7b-422b-a0c7-2fad1fd0e716",
"YaraMatch":[
],
"ProviderName":"Microsoft-Windows-Kernel-Process",
"EventName":"ThreadStop/Stop",
"Opcode":2,
"OpcodeName":"Stop",
"TimeStamp":"2019-03-03T17:58:14.2862348+00:00",
"ThreadID":11996,
"ProcessID":8416,
"ProcessName":"N/A",
"PointerSize":8,
"EventDataLength":76,
"XmlEventData":{
"FormattedMessage":"Thread 11,996 (in Process 8,416) stopped. ",
"StartAddr":"0x7fffe299a110",
"ThreadID":"11,996",
"UserStackLimit":"0x3d632000",
"StackLimit":"0xfffff38632d39000",
"MSec":"560.5709",
"TebBase":"0x91c000",
"CycleTime":"4,266,270",
"ProcessID":"8,416",
"PID":"8416",
"StackBase":"0xfffff38632d40000",
"SubProcessTag":"0",
"TID":"11996",
"ProviderName":"Microsoft-Windows-Kernel-Process",
"PName":"",
"UserStackBase":"0x3d640000",
"EventName":"ThreadStop/Stop",
"Win32StartAddr":"0x7fffe299a110"
}
}
يمكنك استيراد إخراج JSON من SilkETW في PowerShell باستخدام الوظيفة البسيطة التالية.
function Get-SilkData {
param($Path)
$JSONObject = @()
Get-Content $Path | ForEach-Object {
$JSONObject += $_ | ConvertFrom-Json
}
$JSONObject
}
في المثال أدناه، سنجمع بيانات أحداث العملية من مزود Kernel ونستخدم تحميلات الصور لتحديد تنفيذ Mimikatz. يمكننا جمع البيانات المطلوبة باستخدام الأمر التالي.
SilkETW.exe -t kernel -kk ImageLoad -ot file -p C:\Users\b33f\Desktop\mimikatz.json
بعد الحصول على البيانات، يصبح من السهل فرزها والبحث عنها وتصفيتها حسب الخصائص التي نهتم بها.

يتضمن SilkETW وظيفة Yara لتصفية بيانات الأحداث أو وضع علامات عليها. مرة أخرى، هذا له قدرات دفاعية واضحة ولكن يمكن استخدامه أيضًا لتعزيز بحث ETW الخاص بك.
في هذا المثال، سنستخدم قاعدة Yara التالية لاكتشاف تنفيذ Seatbelt في الذاكرة من خلال execute-assembly الخاص بـ Cobalt Strike.
rule Seatbelt_GetTokenInformation
{
strings:
$s1 = "ManagedInteropMethodName=GetTokenInformation" ascii wide nocase
$s2 = "TOKEN_INFORMATION_CLASS" ascii wide nocase
$s3 = /bool\(native int,valuetype \w+\.\w+\/\w+,native int,int32,int32&/
$s4 = "locals (int32,int64,int64,int64,int64,int32& pinned,bool,int32)" ascii wide nocase
condition:
all of ($s*)
}
يمكننا البدء في جمع بيانات ETW الخاصة بـ .Net باستخدام الأمر التالي. يشير الخيار "-yo" هنا إلى أننا يجب أن نكتب فقط مطابقات Yara على القرص!
SilkETW.exe -t user -pn Microsoft-Windows-DotNETRuntime -uk 0x2038 -l verbose -y C:\Users\b33f\Desktop\yara -yo matches -ot file -p C:\Users\b33f\Desktop\yara.json
يمكننا أن نرى في وقت التشغيل أن قاعدة Yara الخاصة بنا قد تم تشغيلها.

لاحظ أيضًا أننا نلتقط فقط مجموعة فرعية من أحداث "Microsoft-Windows-DotNETRuntime" (0x2038)، وتحديداً: JitKeyword و InteropKeyword و LoaderKeyword و NGenKeyword.
يمكنك إما تنزيل المصدر وتجميعه في Visual Studio. يرجى ملاحظة أنه يمكنك الحصول على إصدار المجتمع من Visual Studio مجانًا. أو يمكنك الحصول على أحدث إصدار مسبق البناء من الإصدارات.
للحصول على تفاصيل حول التغييرات الخاصة بالإصدار، يرجى الرجوع إلى سجل التغييرات.