SilkETW 和 SilkService 是 ETW 的靈活 C# 包裝器,它們旨在抽像出 ETW 的複雜性,並為人們提供一個簡單的介面來執行研究和內省。雖然這兩個項目都有明顯的防禦(和進攻)應用,但它們主要應被視為研究工具。
為了方便使用,輸出資料被序列化為 JSON。 JSON 資料可以寫入檔案並使用 PowerShell 在本機進行分析、儲存在 Windows 事件日誌中或傳送到第 3 方基礎架構(例如 Elasticsearch)。
有關 SilkETW 和 SilkService 未來的更多信息,請參閱路線圖部分。
有關 SilkETW 和 SilkService 的更多背景信息,請參閱以下資源。
SilkETW 是基於 .Net v4.5 構建,並使用許多第 3 方庫,如下所示。請參閱 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:PathToSilkService.exe" start= demand
SilkService 擷取 XML 設定檔“SilkServiceConfig.xml”,該檔案應放置在與服務二進位檔案相同的目錄中。下面可以看到一個範例設定檔。
< SilkServiceConfig >
< 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 >
< ETWCollector >
< Guid >6720babc-dedc-4906-86b9-d0bc0089ec50 Guid >
< CollectorType >user CollectorType >
< ProviderName >Microsoft-Windows-DNS-Client ProviderName >
< OutputType >eventlog OutputType >
< YaraScan >C:SomePathRuleFolder YaraScan >
< YaraOptions >Matches YaraOptions >
ETWCollector >
< ETWCollector >
< Guid >21ac2393-3bbb-4702-a01c-b593e21913dc Guid >
< CollectorType >kernel CollectorType >
< KernelKeywords >Process KernelKeywords >
< OutputType >file OutputType >
< Path >C:Usersb33fDesktopkproc.json Path >
ETWCollector >
SilkServiceConfig >
請注意,每個 ETWCollector 元素應該有一個隨機 GUID,這用於內部追蹤和日誌記錄目的。您可以使用以下命令在 PowerShell 中產生 GUID:
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 雜湊表中將包含變數資料。下面可以看到「Microsoft-Windows-Kernel-Process」->「ThreadStop/Stop」的範例 JSON 輸出。
{
"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 "
}
}
您可以使用下列簡單函數從 PowerShell 中的 SilkETW 匯入 JSON 輸出。
function Get-SilkData {
param ( $Path )
$JSONObject = @ ()
Get-Content $Path | ForEach-Object {
$JSONObject += $_ | ConvertFrom-Json
}
$JSONObject
}
在下面的範例中,我們將從核心提供者收集進程事件數據,並使用映像載入來識別 Mimikatz 執行。我們可以使用以下命令收集所需的資料。
SilkETW.exe -t kernel -kk ImageLoad -ot file -p C:Usersb33fDesktopmimikatz.json
有了手中的數據,就可以輕鬆地對我們感興趣的屬性進行排序、grep 和過濾。
SilkETW 包括用於過濾或標記事件資料的 Yara 功能。同樣,它具有明顯的防禦能力,但它也可以輕鬆地用於增強您的 ETW 研究。
在此範例中,我們將使用以下 Yara 規則透過 Cobalt Strike 的執行組件來偵測記憶體中的 Seatbelt 執行。
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*)
}
我們可以使用以下命令開始收集 .Net ETW 資料。這裡的“-yo”選項表示我們應該只將 Yara 匹配寫入磁碟!
SilkETW.exe -t user -pn Microsoft-Windows-DotNETRuntime -uk 0x2038 -l verbose -y C:Usersb33fDesktopyara -yo matches -ot file -p C:Usersb33fDesktopyara.json
我們可以在運行時看到我們的 Yara 規則被命中。
另請注意,我們僅捕獲「Microsoft-Windows-DotNETRuntime」事件 (0x2038) 的子集,特別是:JitKeyword、InteropKeyword、LoaderKeyword 和 NGenKeyword。
您可以下載原始程式碼並在 Visual Studio 中編譯它。請注意,您可以免費取得 Visual Studio 社群版。或者您可以從版本中取得最新的預建版本。
有關版本特定更改的詳細信息,請參閱更改日誌。