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 社区版。或者您可以从版本中获取最新的预构建版本。
有关版本特定更改的详细信息,请参阅更改日志。