Threat Hunting with ETW events and HELK โ€” Part 1: Installing SilkETW ๐Ÿ„โ€โ™€๐Ÿ„

Roberto Rodriguez
Sep 19, 2019 ยท 14 min read

One of my favorite things to do besides playing with Jupyter Notebooks ๐Ÿ˜† is to identify new data sources that could provide additional context to the analytics that I develop while performing research. From a Windows environment perspective, most of the time, the event logs generated after simulating an adversarial technique, come from sources that are simply enabled by pushing an audit policy or by running auditpol.exe . Even though Windows audit policies allow you to enable several useful events, remember that those are only a subset of all the telemetry available in Windows systems.

There are several other sources of data that are available, but they cannot be easily enabled via an audit policy. However, they are easy to explore interactively with the right tooling and a little bit of knowledge about the Event Tracing for Windows (ETW) concepts.

This post is part of a four-part series which will go over the basics of the ETW model, how to install SilkETW, consume and aggregate ETW events, and at the same time show you how you can leverage the additional telemetry for a few detection use cases with the Hunting ELK (HELK).

In this first post, I will go over the basics of ETW and the installation of an amazing project by Ruben Boonen (@FuzzySec) ๐Ÿป named SilkETW โš”๏ธ

The other three parts can be found in the following links:

Before we even start talking about SilkETW, I believe it is important to start from the basics, and refresh some of the key concepts of the ETW model. I also believe it is important to understand how you could manually enable event tracing for specific ETW providers to learn about the mechanics of it.

What is ETW?

Event Tracing for Windows (ETW) is an efficient kernel-level tracing facility that lets you log kernel or application-defined events to a log file. You can consume the events in real time or from a log file and use them to debug an application or to determine where performance issues are occurring in the application. ETW lets you enable or disable event tracing dynamically, allowing you to perform detailed tracing in a production environment without requiring computer or application restarts.

According to MS docs, the Event Tracing API is broken into three distinct components:

  • Controllers, which start and stop an event tracing session and enable providers
  • Providers, which provide the events
  • Consumers, which consume the events

The following diagram from the Microsoft Ntdebugging Blog helped me to understand how each component relates to each other.

Exploring ETW Components


Another way to create new event trace sessions and enable ETW providers is via the built-in Windows Performance System Tool located at Computer Management> System Tools > Performance . Iโ€™ll go over an example later.

List Event Trace Sessions

logman query -ets

You can also use the Windows Performance System Tool to see what Event Trace Sessions are enabled and the providers providing events to them.

If you also wanted to know what event providers a specific event trace session is subscribed to via logman, you can run the following command:

logman query "EventLog-System" -ets

List ETW Providers

logman query providers

Query Specific ETW Providers

$ETWProviders = logman query providers
$ETWProviders | Where-Object { $_ -Like "*Security*" }

We can select the Microsoft-Windows-Security-Auditing, and query its metadata to get more information about it.

logman query providers Microsoft-Windows-Security-Auditing

You could also get information about specific ETW providers via a tool named Windows Events Providers Explorer (WEPExplorer)

You could also use wevtutil.exe to retrieve information about event logs and publishers ( Thank you Marc Sherman)

> wevtutil.exe get-publisher Microsoft-Windows-Security-Auditing /getevents:true /getmessage:true

Windows Security Auditing ETW Provider Events ๐Ÿ’ฅ

Can I Consume Any ETW Event via the Event Log?

For example, this post from the Microsoft Ntdebugging blog has a great step-by-step tutorial on how to enable event tracing for the Microsoft-Windows-WinINet provider via the Analytic channel.

We can start by using the WEPExplorer tool to get more detailed information about the specific Channels applied to each ETW event. As you can see below, we can see the Microsoft-Windows-WinINet/Analytic channel applied to most of the events from the Microsoft-Windows-WinINet provider. Therefore, they are meant to be consumed by the event log in real-time.

Consume WinINet Events

You might have to restart the event viewer console. You will see a new event log folder named WinINet (Microsoft-Windows-WinINet) under Application and Service Logs > Microsoft > Windows. Click on it and you will see 3 channels. Right-click on the Analytic channel and select Enable Log.

Click Ok.

If you go to a website via Microsoft Edge, you will start seeing events populating the Analytic Channel as shown below:

You can validate that an event trace session for the WinINet provider was enabled by going to Computer Management > System Tools > Performance > Data Collector Sets > Startup Event Trace Sessions as shown below:

What about ETW Events Without a Property Channel?

We can use the Windows Events Providers Explorer (WEPExplorer) tool again and verify if we can consume those ETW events in real-time via the event log. Unfortunately, there are not Channel properties applied to the events.

So What Now?

  • Create an event trace session (manually)
  • Subscribe to the ETW provider
  • Set location of the .etl file that will be created
  • Start the event trace session
  • .etl file is generated
  • Open .etl log via the event log as a saved log file

You can start by creating the event trace session via the Performance System Tool located at Computer Management > System Tools > Performance. You just have to create a new Data Collector Set as shown in the image below:

Give it a name and select Create Manually (Advanced)

Next, select the event trace provider Microsoft-Windows-DotNETRuntime

You are almost done! You can use the view below and modify the properties of the data collector set. For example, select Keywords and then Edit.

For example, you can collect a subset of events related to JitKeyword, InteropKeyword, LoaderKeyword and NGenKeyword for .NET activity. If you want to learn why I am interested in those events, you can read this blog post from the Countercept team. After selecting those values, you will get a bitmask: 0x2038 (Remember this! ๐Ÿ˜‰). Next, click Ok and Next.

Select the location of the .etl file. Keep the default location and click Next.

Keep the defaults and click Finish!

You can see the new event trace session available but with status Stopped. You can also double-click on it and check the location and name of the .etl file that will be created once the event trace session gets started.

Right-click on the new event trace session and select Start.

The event trace session is now running, but you wont see it in the event logs unless you grab a copy of the .etl file and open it as a saved log. You wont be able to have a continuous ingestion to the event log. To open the .etl file as a saved log, go to Event Viewer console and click on Action > Open Saved Log.

Select the .etl file associated with your event trace session, and click Open.

Click Yes after getting the prompt to create a copy of it

You can keep the default location to display the external log. Click Ok.

๐Ÿ’ฅThats it! That was easy right?

Even though I was able to get events from the Microsoft-Windows-DotNETRuntime provider, it is not a continuous real-time ingestion to the event log. By default those ETW events donโ€™t have a Channel applied to them. One way to accomplish the real-time ingestion to the event log would be by writing an applications leveraging ETW apis and enable that capability.

Enter SilkETW

My brother Jose Luis Rodriguez and I were so excited about this release that..

We decided to test it in our lab environment and used it to consume events from the Microsoft-Windows-LDAP-Client provider while executing some LDAP filters via Powerview by Will . I will walk through some examples in the next parts of this series. For now, I can show you how to install SilkETW โš”๏ธ


You will see two folders: SilkETW and SilkService. Thats how you differentiate how you will go about running SilkETW.

Also, in the Dependencies folder, you will find binaries that you need to run as pre-requirements ( Do NOT skip this step!)


Event Tracing for Microsoft-Windows-DotNETRuntime

  • -pn Microsoft-Windows-DotNETRuntime
  • -ot eventlog
  • -uk 0x2038
> SilkETW.exe -t user -pn Microsoft-Windows-DotNETRuntime -uk 0x2038 -ot eventlog

Something important to point out in here is that the collection of events is continuous and pushed to the SilkETW-Log event log directly. However, as you can see in your cmd terminal, it is not a collection that will run headless in the background. This is perfect for debugging and analysis of ETW events generated by any execution of code during research. CTRL-C to stop collector!

SilkETW in Headless Mode = SilkService ๐Ÿ”ฅ

sc create SillkService binPath= "C:\Path\To\SilkService.exe" start= demand

Build Your SilkService XML Config

Following our example for Microsoft-Windows-DotNETRuntime events consumed via the event log, you can use this basic config:

Remember that the <Guid> field is a random GUID that you generate. When I started to work with these configs, I thought it was the provider GUID ๐Ÿ˜†. Next, copy the DotNETRuntime config, rename it SilkServiceConfig.xml, and place it in the same directory as the service binary.

Start SilkService ๐Ÿคž

If you open Event Viewer again (restart it), you will see that there is a new event log named SilkService-Log. There you will be able to see a continuous real-time ingestion of ETW events from the Microsoft-Windows-DotNETRuntime provider ๐Ÿ”ฅ ๐Ÿš’

SilkService XML Config Elements

// Define XML elements            
XName CI = XName.Get("ETWCollector");
XName CG = XName.Get("Guid");
XName CT = XName.Get("CollectorType");
XName KK = XName.Get("KernelKeywords");
XName OT = XName.Get("OutputType");
XName P = XName.Get("Path");
XName PN = XName.Get("ProviderName");
XName UTEL = XName.Get("UserTraceEventLevel");
XName UK = XName.Get("UserKeywords");
XName FO = XName.Get("FilterOption");
XName FV = XName.Get("FilterValue");
XName YS = XName.Get("YaraScan");
XName YO = XName.Get("YaraOptions");

Also, check how others are playing with SilkETW for some ideas. This blog post by Mathias Jessen, shows you how to write events to a file (JSON).

SilkETW Event Types

Event ID = 0 -> Collector start

"Collector": "Start",
"Data": {
"Type": "User",
"Provider": "Microsoft-Windows-DotNETRuntime",
"Keywords": "0x2038",
"FilterOption": "None",
"FilterValue": "",
"YaraPath": "",
"YaraOption": "None"

Event ID = 1 -> Collector terminated by user

"Collector": "Stop",
"Error": false

Event ID = 2 -> Collector terminated by error

"Collector": "Stop",
"Error": true,
"ErrorCode": 3

Event ID = 3 -> Event recorded
This is just the raw JSON for the event that was recorded by the collector.

Threat Hunters Forge

Threat Hunting, Data Science & Open Source Projects

Roberto Rodriguez

Written by

Threat Hunters Forge

Threat Hunting, Data Science & Open Source Projects

More From Medium

More on Cybersecurity from Threat Hunters Forge

More on Cybersecurity from Threat Hunters Forge

More on Cybersecurity from Threat Hunters Forge

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and weโ€™ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium โ€” and support writers while youโ€™re at it. Just $5/month. Upgrade