
Обёртка на 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 SilkService binPath= "C:\Path\To\SilkService.exe" start= demand
SilkService использует XML-файл конфигурации "SilkServiceConfig.xml", который должен находиться в том же каталоге, что и бинарник службы. Пример файла конфигурации приведён ниже.
<SilkServiceConfig>
<!--
Это пользовательский сборщик
-> Microsoft-Windows-DotNETRuntime
-> Имя на основе GUID или строки
-->
<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:\Some\Path\RuleFolder</YaraScan>
<YaraOptions>Matches</YaraOptions>
</ETWCollector>
<!--
Это сборщик ядра
-->
<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
}
В примере ниже мы соберём данные о событиях процесса от поставщика ядра и используем загрузки образов для идентификации выполнения 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*)
}
Мы можем начать сбор данных .Net ETW с помощью следующей команды. Параметр "-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. Обратите внимание, что вы можете получить Community-версию Visual Studio бесплатно. Либо вы можете взять последнюю предварительно собранную версию из релизов.
Подробную информацию об изменениях в версиях см. в Changelog.