Non-DotNet ETW Tracing

Non-DotNet ETW Tracing

Assign
Date
‣
Status
Completed

What on earth is this?

DFPM.exe uses ETW to trace Sysmon events. To deny Type-1 (binary PE files) payloads, we handle FileCreate in such a way:
notion image
which eventually, calls below when we receive a FileCreate Sysmon Event:
notion image
In case you asking where is Windows (agents) side source-codes: https://github.com/jymcheong/OpenEDR/wiki/6.-FAQ#where-are-the-host-agents-source-codes
Instead of giving the student our host agent codes whole-sale, I am taking parts of it to let the learner experience & contribute in a "controlled manner".

Why Go?

https://github.com/bi-zone/etw so that it does not require installation of .NET Framework.
But depending on the situation (eg. can't hire anyone with Golang experience), then .NETcore has fully portable compilation. Meaning, a standalone EXE. As such, this is optional. ElasticBeats suite is written entirely with Golang.
🧠
Mainly for student to learn something new & relevant to system or backend development.

Write your Golang agent...

To subscribe to "Microsoft-Windows-Sysmon" provider & then print out some FileCreate or whatever events you can simulate.

Dot-Net Way

See https://lowleveldesign.org/2020/08/15/fixing-empty-paths-in-fileio-events-etw/ contrast with Golang. More concerned with kernel.FileIOFileCreate, it is possible the targetPath may be NOT even start with a drive letter.
https://stackoverflow.com/questions/60119460/in-event-tracing-for-windows-etw-traceeventsession-dont-catch-read-event-fro - need run-as-admin.. to debug or step trace in Visual Studio CE, then run-as-admin the VSCE.
 

Write a .NET agent

Subscribe to another provider that is equivalent to Sysmon.FileCreate, such that you can print written target file full path. Note that returned paths can be without drive letter path (see below).

Other Relevant Info

https://en.wikipedia.org/wiki/Path_(computing), path that doesn't start with a drive-letter. Some malware reads raw or device path to get around certain detection btw.
notion image

YJ's Documentation

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.

What is ETW Go?

https://github.com/bi-zone/etw is a Go-package that allows you to receive Event Tracing for Windows (ETW) events in go code.

Installation of Go

Pre-requisites:
  • A text editor - I am using Visual Studio Code, hence the installation steps will be based around VSC.
Follow this link https://golang.org/doc/install on how to download and install Go on your Windows machine.
After installing Go, follow the steps listed here https://golang.org/doc/tutorial/getting-started#code to create a go.mod file (if not your codes will NOT run) and run a sample code to ensure that Go is working.

Installation of ETW Go

Copy lines 5-9 of https://github.com/bi-zone/etw/blob/master/go.mod into the sample go.mod file that you created earlier. Then, run the command go mod tidy .
Run the command go get github.com/bi-zone/etw to download and install ETW Go. You can use the sample code at https://github.com/bi-zone/etw#usage to test if ETW Go is working.
If it is working, your output should look similar to this:
notion image

Writing a Golang agent

Firstly, we need to find Sysmon's GUID so that we can subscribe to it:
notion image
Using the sample codes given in GitHub, I modified the codes such that it is subscribed to Sysmon instead and it only logs FileCreate events:
package main import ( "log" "os" "os/signal" "sync" "github.com/bi-zone/etw" "golang.org/x/sys/windows" ) func main() { // Subscribe to Microsoft-Windows-Sysmon guid, _ := windows.GUIDFromString("{5770385F-C22A-43E0-BF4C-06F5698FFBD9}") session, err := etw.NewSession(guid) if err != nil { log.Fatalf("Failed to create etw session: %s", err) } // Log only FileCreate events cb := func(e *etw.Event) { if data, err := e.EventProperties(); err == nil && e.Header.ID == 11 { log.Printf("FileCreate event: %v created %v", data["Image"], data["TargetFilename"]) } } // `session.Process` blocks until `session.Close()`, so start it in routine. var wg sync.WaitGroup wg.Add(1) go func() { if err := session.Process(cb); err != nil { log.Printf("[ERR] Got error processing events: %s", err) } wg.Done() }() // Trap cancellation. sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, os.Interrupt) <-sigCh if err := session.Close(); err != nil { log.Printf("[ERR] Got error closing the session: %s", err) } wg.Wait() }
References:
 
To generate a FileCreate event, I created a text file in the Downloads directory.
This was the FileCreate event generated by Sysmon:
notion image
This was the output of my go script:
notion image

Writing a .NET agent

Firstly, install Microsoft.Diagnostics.Tracing.TraceEvent package to your Visual Studio project. Follow the steps in https://docs.microsoft.com/en-us/nuget/quickstart/install-and-use-a-package-in-visual-studio#nuget-package-manager on how to install a package using NuGet Package Manager.
More information about the TraceEvent library can be found in the following links:
 
using Microsoft.Diagnostics.Tracing.Parsers; using Microsoft.Diagnostics.Tracing.Session; using System; class Program { static void Main(string[] args) { using (var session = new TraceEventSession("FileCreate")) { session.EnableKernelProvider(KernelTraceEventParser.Keywords.DiskFileIO | KernelTraceEventParser.Keywords.FileIOInit | KernelTraceEventParser.Keywords.FileIO); session.Source.Kernel.FileIOCreate += Kernel_HandleFileIoCreate; session.Source.Process(); } } private static void Kernel_HandleFileIoCreate(Microsoft.Diagnostics.Tracing.Parsers.Kernel.FileIOCreateTraceData obj) { Console.WriteLine("FileIOCreate " + obj.FileName); } }
*Note: In order to run the codes, you need to run VS as admin.
To generate a FileCreate event, I created another text file in the Downloads directory.
This is a snippet of the output after running the codes:
notion image
As seen from the red box, it was able to catch the creation of my .txt file. The usage of TraceEvent library allows us to catch much more FileCreate events as compared to Sysmon.
 
There is also an existing command-line tool called wtrace that uses the TraceEvent library to catch FileIO operations as well.
Snippet of output from wtrace:
notion image
By running the command wtrace.exe --handlers file -f FileIO/Create in admin cmd, wtrace will start capturing FileIO/Create events.
Â