Skip to content

Configuration

Jonathan Beierle edited this page Jan 28, 2026 · 10 revisions

Telemetry Configuration

The telemetry EventHorizon collects is determined by the config.json stored in its application folder (typically C:\Program Files\EventHorizon\). As the file extension suggests, the configuration is in JSON format, and allows you to configure the ETW providers and event names that EventHorizon provides to the detection engine. Below is the general layout of config.json, but as a general note the provider field is not required, as EventHorizon uses the provider_guid to subscribe to providers.

[
  {
    "provider": "PROVIDER COMMON NAME",
    "provider_guid": "{PROVIDER GUID}",
    "event_names": [
      "EVENT_TASK_NAME",
      "OTHER_EVENT_TASK_NAME",
      ...
    ],
    "enabled": true|false
  },
  {
    "provider": "OTHER PROVIDER COMMON NAME",
    "provider_guid": "{OTHER PROVIDER GUID}",
    "event_names": [
      "EVENT_TASK_NAME",
      "OTHER_EVENT_TASK_NAME",
      ...
    ],
    "enabled": true|false
  },
  ...
]

Rule Configuration

Rules are placed in a Rules directory within the application folder, so it'll typically be C:\Program Files\EventHorizon\Rules. Simply put your rule(s) (they should be .yaml files) in that directory and when the detection engine starts, it should load your rules. Additionally, if you update or add rules while the detection engine is running, you may run the following command to refresh the detection rules.

& "C:\Program Files\EventHorizon\EventHorizonHelper.exe" reload

Rule Syntax

EventHorizon's rule syntax is meant to closely mimic that of Sigma rules so as to increase ease of use as well as the ability to migrate rules from Sigma to EventHorizon.

title: RULE TITLE HERE
description: DESCRIPTIVE DESCRIPTION HERE
logsource:
    provider: ETW PROVIDER COMMON NAME HERE
    event_name: EVENT TASK NAME HERE
detection:
    {search-identifier} [optional]
        {field|condition: value} [optional]
    condition: BOOLEAN CONDITION HERE
response: SOME_RESPONSIVE_CAPABILITY(SOME PARAMTER(S)) [optional]

Log Sources

Log sources in EventHorizon are made up of two fields: provider and event_name. These fields allow EventHorizon to filter through events in order to feed them to your detection logic and fire an alert should the event match.

The provider field consists of the common name of the provider (not the GUID). For example, the provider could be something like Microsoft-Windows-Sysmon or Microsoft-Windows-Kernel-Process.

The event_name field is the ETW event's task name. There are a few ways to find the event's task name, but perhaps the easiest way is to look at the ETW provider's manifest. Below are a few resources for looking at provider manifests:

Below is a snippet taken from Microsoft-Windows-Kernel-Process

<events>
          <event value="1" symbol="ProcessStart" version="0" task="ProcessStart" opcode="win:Start" level="win:Informational" keywords="WINEVENT_KEYWORD_PROCESS" template="ProcessStartArgs" />
          <event value="1" symbol="ProcessStart_V1" version="1" task="ProcessStart" opcode="win:Start" level="win:Informational" keywords="WINEVENT_KEYWORD_PROCESS" template="ProcessStartArgs_V1" />
          <event value="1" symbol="ProcessStart_V2" version="2" task="ProcessStart" opcode="win:Start" level="win:Informational" keywords="WINEVENT_KEYWORD_PROCESS" template="ProcessStartArgs_V2" />
          <event value="1" symbol="ProcessStart_V3" version="3" task="ProcessStart" opcode="win:Start" level="win:Informational" keywords="WINEVENT_KEYWORD_PROCESS" template="ProcessRundownArgs_V1" />
          <event value="1" symbol="ProcessStart_V4" version="4" task="ProcessStart" opcode="win:Start" level="win:Informational" keywords="WINEVENT_KEYWORD_PROCESS" template="ProcessStartArgs_V4" />
          ...
</events>

If you wanted to write a rule on process creation events, then you would look at the <events> in the provider XML, find the event that corresponds to that, and use the task field in your rule. So, in this example, ProcessStart would be the correct event name in the rule.

As an example, a rule that alerts on instances of cmd.exe being launched would look like:

title: CMD Launched
description: Detects when cmd.exe is launched
logsource:
    provider: Microsoft-Windows-Kernel-Process
    event_name: ProcessStart
detection:
    selection:
        ImageName|endswith: "cmd.exe"
    condition: selection

Responsive Actions

EventHorizon allows you to specify an action to take when a rule is matched. These actions include:

  • Process termination
  • Process suspension
  • Process memory dumping (regional or entire process memory)

Process Termination

The process termination response takes exactly one parameter in the form of a process id, and is not hard coded. In the detection rule, you may pass any of the event's fields (so long as it's a process id) to be terminated. As an example of the flexibility of this rule, you may pass the ParentProcessId from the event to be terminated:

terminate_process(ParentProcessId)

Process Suspension

Similar to the process termination response is the process suspension response. It also takes exactly one parameter from the detection-triggering event that contains a process id then suspends the process

suspend_process(ProcessId)

Process Memory Dump

The process memory dump response dumps either an entire process or a region of a process's memory based off of the parameters given to it (see below sections for more). It will then write the dumped memory onto a file in a specified directory on the system.

Something to keep in mind is that the memory dumping functionality isn't implemented in the same place. Full process memory dumps are done in usermode inside the detection engine while regional dumps are done in kernel mode. The reason for this is due to the complexity of implementing full process memory dumps from the kernel driver. Regional process memory dumps in testing were only seen as a result of ETWTI telemetry and thus provided kernel mode virtual addresses which was convenient for a kernel driver. However, when trying to just dump all of a process's memory it became quickly apparent that it would be more trouble to fit it into the kernel driver.

Full Dump

To dump all of a process's memory, simply pass the process id and a directory path on disk to dump the memory to.

dump_process(TargetProcessId, \\??\\C:\\)

Regional Memory Dump

To dump a specific region of a process's memory you need to pass in 4 things:

  • Process ID
  • Base address
  • Region size
  • Dump directory

Regional memory dumps at the moment are done from the ELAM kernel driver and thus require memory addresses that kernel virtual addresses. While this seems confusing on the surface, regional memory dumps are more frequently used with something like ETWTI, which emits events containing kernel virtual addresses. If there's a reason you have an ETW provider emitting relative virtual addresses for a usermode process and need to dump a memory region, please open an issue.

dump_process(TargetProcessId, BaseAddress, RegionSize, \\??\\C:\\)

Clone this wiki locally