
Wrapper C# pour ETW qui sérialise les données d'événements du noyau et du mode utilisateur en JSON pour la chasse aux menaces, l'analyse de logiciels malveillants et la réponse aux incidents, avec intégration Yara et envoi vers Elasticsearch.
SilkETW & SilkService sont des wrappers C# flexibles pour ETW, conçus pour abstraire les complexités d'ETW et offrir une interface simple pour effectuer des recherches et de l'introspection. Bien que les deux projets aient des applications défensives (et offensives) évidentes, ils doivent avant tout être considérés comme des outils de recherche.
Pour une consommation facile, les données de sortie sont sérialisées en JSON. Les données JSON peuvent être écrites dans un fichier et analysées localement avec PowerShell, stockées dans le journal des événements Windows ou envoyées vers une infrastructure tierce comme Elasticsearch.
Pour plus d'informations sur l'avenir de SilkETW & SilkService, consultez la section Roadmap.
Pour plus de contexte sur SilkETW et SilkService, veuillez consulter les ressources suivantes.
SilkETW est construit sur .Net v4.5 et utilise un certain nombre de bibliothèques tierces, comme indiqué ci-dessous. Veuillez consulter LICENSE-3RD-PARTY pour plus de détails.
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
L'utilisation en ligne de commande est assez simple et les entrées utilisateur sont validées dans le prologue d'exécution. Voir l'image ci-dessous pour plus de détails.

SilkService a été créé parce qu'un grand nombre de personnes voulaient exécuter SilkETW sans interface et collecter des données ETW pour plusieurs sources simultanément. Bien que cela présente un attrait évident, les points suivants doivent être gardés à l'esprit.
Après avoir compilé ou téléchargé le package de version, vous pouvez installer le service en exécutant la commande suivante à partir d'une invite élevée.
sc create SillkService binPath= "C:\Path\To\SilkService.exe" start= demand
SilkService ingère un fichier de configuration XML, "SilkServiceConfig.xml", qui doit être placé dans le même répertoire que le binaire du service. Un exemple de fichier de configuration est présenté ci-dessous.
<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>
Notez que chaque élément ETWCollector doit avoir un GUID aléatoire, utilisé à des fins de suivi interne et de journalisation. Vous pouvez générer des GUID dans PowerShell à l'aide de la commande suivante :
PS C:\> [guid]::NewGuid()
Guid
----
eee52b87-3f32-4651-b0c3-e7bb9af334aa
Au moment de l'exécution, SilkService crée un sous-dossier "Logs" pour enregistrer les informations d'exécution du service. C'est une ressource inestimable pour interroger l'état du service, vérifier la validation des paramètres du service et examiner les informations d'erreur. SilkService a tendance à s'arrêter proprement s'il rencontre tout type d'erreur, même si cette erreur n'exige pas strictement l'arrêt. Cette décision de conception a été prise délibérément car il n'est pas judicieux d'avoir des collecteurs en suspens ou une opérabilité partielle.
Consultez toujours le journal du service si le service s'arrête de lui-même !
Il est toujours possible que quelque chose se passe mal. Consultez le journal du service pour plus de détails. Bien que SilkService soit configuré pour se terminer et nettoyer les collecteurs ETW en cas d'erreur, il est possible qu'un collecteur obsolète reste enregistré après la fin du processus. Pour lister les collecteurs en cours d'exécution, vous pouvez utiliser la commande suivante.
logman -ets
Si des collecteurs obsolètes sont identifiés, ils peuvent être supprimés en exécutant les commandes suivantes à partir d'une invite élevée.
Get-EtwTraceProvider |Where-Object {$.SessionName -like "SilkService*"} |ForEach-Object {Stop-EtwTraceSession -Name $.SessionName}
Get-EtwTraceProvider |Where-Object {$_.SessionName -like "SilkService*"} |Remove-EtwTraceProvider
La sortie JSON, avant sérialisation, est formatée selon la structure C# suivante.
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;
}
Notez que, selon le fournisseur et le type d'événement, vous aurez des données variables dans la table de hachage XmlEventData. Un exemple de sortie JSON est présenté ci-dessous pour "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"
}
}
Vous pouvez importer la sortie JSON de SilkETW dans PowerShell à l'aide de la fonction simple suivante.
function Get-SilkData {
param($Path)
$JSONObject = @()
Get-Content $Path | ForEach-Object {
$JSONObject += $_ | ConvertFrom-Json
}
$JSONObject
}
Dans l'exemple ci-dessous, nous allons collecter les données d'événements de processus à partir du fournisseur Kernel et utiliser les chargements d'images pour identifier l'exécution de Mimikatz. Nous pouvons collecter les données requises avec la commande suivante.
SilkETW.exe -t kernel -kk ImageLoad -ot file -p C:\Users\b33f\Desktop\mimikatz.json
Avec les données en main, il est facile de trier, rechercher et filtrer les propriétés qui nous intéressent.

SilkETW inclut des fonctionnalités Yara pour filtrer ou étiqueter les données d'événements. Encore une fois, cela a des capacités défensives évidentes, mais cela peut tout aussi facilement être utilisé pour enrichir vos recherches ETW.
Dans cet exemple, nous utiliserons la règle Yara suivante pour détecter l'exécution de Seatbelt en mémoire via execute-assembly de 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*)
}
Nous pouvons commencer à collecter des données ETW .Net avec la commande suivante. L'option "-yo" ici indique que nous devons écrire uniquement les correspondances Yara sur le disque !
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
Nous pouvons voir au moment de l'exécution que notre règle Yara a été déclenchée.

Notez également que nous ne capturons qu'un sous-ensemble des événements "Microsoft-Windows-DotNETRuntime" (0x2038), à savoir : JitKeyword, InteropKeyword, LoaderKeyword et NGenKeyword.
Vous pouvez soit télécharger le code source et le compiler dans Visual Studio. Notez que vous pouvez obtenir l'édition communautaire de Visual Studio gratuitement. Ou vous pouvez récupérer la dernière version pré-compilée depuis les releases.
Pour les détails sur les changements spécifiques aux versions, veuillez vous référer au Changelog.