Write Sigma Rules to Catch Persistence

Build a detection lab and write Sigma rules to catch a real persistence attack.

Introduction

30 Second Summary

Every time you log into your computer, dozens of programs start automatically. An attacker who slips a malicious program into that startup list has persistent access to your machine, surviving reboots and staying hidden in plain sight.

In this project, you will build a complete detection engineering pipeline. You will simulate a real persistence attack on your Windows machine, analyze the raw telemetry it produces, write a vendor-neutral Sigma detection rule, and deploy it as a live alert in a Wazuh SIEM dashboard.

What You'll Build

A detection that catches an attacker adding a malicious program to your Windows startup registry keys. You execute the attack, watch the evidence appear in your logs, write the rule that spots it, and see the alert fire in real-time on your dashboard.

By the end of this project, you'll have:

  • A working SIEM ingesting live Sysmon telemetry from your Windows machine, so you can see exactly what every process does at the registry level.
  • A hand-written Sigma rule that detects a real Registry Run Key persistence attack (MITRE ATT&CK T1547.001), proving you can build detections from scratch.
  • A custom Wazuh alert that fires the moment the attack is executed, with full ATT&CK mapping visible in your dashboard.
  • Secret Mission: Write a second Sigma rule that detects Scheduled Task persistence and deploy it to Wazuh.

Are there any prerequisites?

This project assumes you have VirtualBox installed with an Ubuntu VM available (Ubuntu 20.04 or higher), and that your host machine runs Windows. You should be comfortable navigating the Linux command line and opening Windows Event Viewer.

Your Ubuntu VM needs at least 4 vCPU, 8 GiB RAM, and 50 GB of storage to run the Wazuh server.

Before We Start

Before We Start...

Before we dive in, let's lock in what you're about to build and why it matters.

In this project, you'll simulate an attacker establishing persistence on your Windows machine via a Registry Run Key, then build the detection that catches it from raw log to alert. This is MITRE ATT&CK technique T1547.001 in action.

Set Up Your Detection Lab

Without a working SIEM ingesting endpoint telemetry, you have zero visibility into what is happening on your machine. This is the fundamental problem every SOC analyst faces on day one.

In this step, you will stand up a complete detection pipeline: a Wazuh SIEM server on your Ubuntu VM, Sysmon endpoint telemetry on your Windows host, and a Wazuh agent that bridges the two.

In this step, get ready to:
  • Install Wazuh 4.14 on your Ubuntu VM using the quickstart installer.
  • Install Sysmon v15.15 on Windows with the sysmon-modular config and deploy the Wazuh agent.
  • Verify that Sysmon events flow from Windows into the Wazuh dashboard.
Install Wazuh 4.14 on your Ubuntu VM

The Wazuh quickstart installer deploys all server components (indexer, manager, dashboard) on a single node. This is ideal for a lab with one agent.

What is Wazuh?

Wazuh is an open-source SIEM (Security Information and Event Management) platform. It collects logs from endpoints, decodes them, and applies detection rules to generate alerts.

Think of it as the central nervous system of a SOC. Every event from every monitored machine flows into Wazuh, where rules decide what is suspicious.

VM hardware requirements

Your Ubuntu VM needs at least 4 vCPU, 8 GiB RAM, and 50 GB storage for the quickstart install. If your VM has less, increase its resources in VirtualBox before continuing.

  • Open a terminal in your Ubuntu VM.
  • Download and run the Wazuh quickstart installer by running this command:
curl -sO https://packages.wazuh.com/4.14/wazuh-install.sh && sudo bash ./wazuh-install.sh -a

What does this command do?

The curl -sO part downloads the installer script silently. The sudo bash ./wazuh-install.sh -a part runs it with the -a flag, which means "install all components" (indexer, manager, and dashboard) on this single machine.

What should I see?

The installation takes 5-10 minutes. When it finishes, the output displays the admin credentials. Look for a line showing the admin username and a generated password.

  • Copy and save the admin password from the installer output somewhere safe. You will need it to log in to the dashboard.

Lost the password?

If you missed the password in the output, extract it by running:

sudo tar -O -xvf wazuh-install-files.tar wazuh-install-files/wazuh-passwords.txt

This prints all generated passwords to the terminal.

  • Confirm the dashboard is accessible by opening a browser on your Windows host and navigating to https:// followed by your Ubuntu VM's IP address.
  • Accept the self-signed certificate warning.
  • Log in with username admin and the password you saved.

You should see the Wazuh dashboard home page with zero agents connected.

Can't reach the dashboard?

Make sure your Ubuntu VM's network adapter is set to Bridged Adapter in VirtualBox so your Windows host can reach it on the local network.

Run ip addr inside the VM to confirm the IP address. If the IP changed, use the new one in your browser.

help me connect to my Wazuh dashboard from my Windows host

Install Sysmon and the Wazuh agent on Windows

Sysmon is a Windows system monitor that logs detailed process, network, and registry activity. The Wazuh agent will forward these Sysmon events to your server for analysis.

What is Sysmon?

Sysmon is a free Microsoft Sysinternals tool that records granular telemetry about what happens on a Windows machine. It logs process creation, network connections, registry changes, and more.

Without Sysmon, Windows Event Viewer only shows basic Security and System events. With Sysmon, you get the detailed fields that make detection engineering possible.

Why sysmon-modular?

Olaf Hartong's sysmon-modular config is actively maintained and maps every module to MITRE ATT&CK techniques. It gives you comprehensive coverage out of the box without needing to write your own config from scratch.

  • Open PowerShell as Administrator (right-click the Start menu, then select Windows PowerShell (Admin) or Terminal (Admin)).
  • Navigate to your Sysmon folder and install Sysmon with the config by running this command:
.\sysmon64 -accepteula -i sysmonconfig.xml

What does this command do?

  • sysmon64 is the 64-bit Sysmon executable.
  • -accepteula accepts the license agreement silently.
  • -i sysmonconfig.xml installs Sysmon as a service using the specified configuration file.

You should see output confirming Sysmon was installed successfully as a service.

  • Verify Sysmon is generating events by opening Event Viewer.
  • Press the Windows key, type Event Viewer, and press Enter.
  • In the left panel, expand Applications and Services Logs > Microsoft > Windows > Sysmon > Operational.

You should see events already appearing in the log. Sysmon is actively recording system activity.

Don't see the Sysmon log?

Make sure you ran the install command from an Administrator PowerShell prompt. If Sysmon is not installed as a service, the log channel will not exist.

Try running Get-Service Sysmon64 in PowerShell to confirm the service is running.

help me troubleshoot my Sysmon installation on Windows

Now install the Wazuh agent so your Windows machine can forward these Sysmon events to the server.

  • In the Wazuh dashboard, click the upper-left menu icon.
  • Navigate to Agents management > Summary.
  • Click Deploy new agent.
  • Select Windows as the operating system.
  • Enter your Ubuntu VM's IP address in the Server address field.
  • Follow the on-screen instructions to download the MSI installer and run the install command shown in the dashboard.

Why use the dashboard to deploy?

The Wazuh dashboard pre-fills the correct manager IP and generates the exact PowerShell command for you. This avoids typos in the MSI install flags.

  • After the MSI install completes, start the Wazuh agent service by running this command in your Administrator PowerShell:
NET START WazuhSvc

You should see a message confirming the Wazuh service started successfully.

Next, configure the agent to forward Sysmon events to the Wazuh server.

  • Open the Wazuh agent config file in Notepad as Administrator by running:
notepad "C:\Program Files (x86)\ossec-agent\ossec.conf"
  • Scroll to the bottom of the file, just before the closing </ossec_config> tag.
  • Add the following block to tell the agent to collect Sysmon events:
<localfile>
  <location>Microsoft-Windows-Sysmon/Operational</location>
  <log_format>eventchannel</log_format>
</localfile>

What does this config do?

  • location specifies the Windows event channel name that Sysmon writes to.
  • log_format set to eventchannel tells the Wazuh agent to read from the Windows Event Log API.
  • Save the file in Notepad (Ctrl+S) and close it.
  • Restart the Wazuh agent to apply the new config by running:
Restart-Service -Name wazuh

The agent now forwards all Sysmon events to your Wazuh server.

Service won't restart?

A typo in ossec.conf will prevent the service from starting. Check that your XML is well-formed. The <localfile> block must be inside the <ossec_config> tags, not outside them.

help me fix my Wazuh agent config on Windows

Verify the full pipeline is working

You now have all the pieces installed. Time to confirm that events flow from Sysmon on Windows all the way into the Wazuh dashboard.

  • Switch to your browser with the Wazuh dashboard open.
  • Click the upper-left menu icon and navigate to Agents management > Summary.

Before you check, predict: do you expect your Windows agent to show as Active or Disconnected?

  • Confirm your Windows agent appears in the list with status Active.

You should see your Windows hostname listed with a green Active status.

  • Click the upper-left menu icon and navigate to Threat Hunting.
  • In the search bar, type sysmon and press Enter.

You should see Sysmon events appearing in the results. These are live events from your Windows machine flowing through the pipeline you just built.

Agent shows Disconnected?

Check that port 1514 (TCP) is open on your Ubuntu VM firewall. Run sudo ufw status to check, and sudo ufw allow 1514/tcp to open it if needed.

Also confirm the Wazuh agent config has the correct Ubuntu VM IP in the <address> field.

help me get my Wazuh agent to connect to the manager

Your detection lab is live. You have a full telemetry pipeline running: Sysmon records detailed events on Windows, the Wazuh agent forwards them, and the Wazuh server decodes and indexes them for analysis. Next up, you will simulate a real persistence attack and see exactly what it looks like in the raw logs.

Simulate a Persistence Attack and Analyze the Raw Telemetry

Your detection lab is live and ingesting endpoint telemetry. Now comes the core question every detection engineer must answer: what does the attack actually look like in the logs?

Before you can write a detection rule, you need to understand exactly what artifacts an attack leaves behind. In this step, you will execute a real persistence technique on your Windows machine and read the raw evidence it produces in Sysmon.

In this step, get ready to:
  • Execute a safe persistence attack simulation using a Registry Run Key.
  • Locate and read the raw Sysmon Event ID 13 telemetry the attack produces.
  • Identify the detection gap in Wazuh's built-in rules.
Simulate the persistence attack

Attackers need their malware to survive a reboot. One of the simplest ways to do this on Windows is to add an entry to the Registry Run Keys. Any program listed there launches automatically when the user logs in.

You will now simulate this technique, classified as MITRE ATT&CK T1547.001 (Boot or Logon Autostart Execution: Registry Run Keys). The command points to a non-existent file, so no actual malware runs.

  • Press the Windows key to open your search bar.
  • Type PowerShell.
  • Right-click Windows PowerShell and select Run as administrator.
  • Click Yes on the User Account Control prompt.
  • Simulate the Registry Run Key persistence attack by running this command:
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "TestPersistence" /t REG_SZ /d "C:\Windows\Temp\payload.exe" /f

What does this command do?

  • reg add writes a new value to the Windows Registry.
  • The path HKCU\Software\Microsoft\Windows\CurrentVersion\Run is the Run Key. Anything listed here auto-starts at login.
  • /v "TestPersistence" names the entry so you can find it later.
  • /d "C:\Windows\Temp\payload.exe" is the fake payload path. This file does not exist, so nothing malicious actually executes.
  • /f forces the write without a confirmation prompt.

You should see the output: The operation completed successfully.

This simulation is safe

The registry key points to C:\Windows\Temp\payload.exe, which does not exist on your machine. No malware is executed. The detection fires on the registry modification itself, not on any payload running.

Locate the Sysmon event in Event Viewer

Sysmon Event ID 13 (RegistryEvent: Value Set) fires every time a registry value is written. Your attack just created one of these events. Time to find it and read the raw telemetry.

  • Switch back to Event Viewer on your Windows machine.
  • In the left pane, expand Applications and Services Logs > Microsoft > Windows > Sysmon > Operational.
  • In the right-hand Actions pane, click Filter Current Log....
  • In the Event IDs field, type 13 and click OK.
  • Scroll through the filtered events and find the one where the TargetObject field contains CurrentVersion\Run\TestPersistence.
  • Click on the event and select the Details tab to see all fields.

You should see an event with TargetObject containing CurrentVersion\Run and Details showing C:\Windows\Temp\payload.exe.

What do these Sysmon fields mean?

  • Image is the process that made the registry change. You will see the path to reg.exe because that is the tool you used.
  • TargetObject is the full registry path that was modified. This tells you exactly which key was written to.
  • Details is the value that was written. In a real attack, this would be the path to the attacker's malware.
  • EventType shows SetValue, confirming this was a value write operation.

These four fields are the detection surface. Any rule you write will match against some combination of them.

Don't see Event ID 13 for your TestPersistence key?

  • Make sure you ran the reg add command in an elevated (Administrator) PowerShell window.
  • Check that the Event Viewer filter is set to 13 only. Clear any other filters that may be hiding results.
  • If no Sysmon events appear at all, confirm Sysmon is running by checking that the Sysmon service is listed as Running in the Services app.

Help me find my Sysmon Event ID 13 event for the Registry Run Key.

Check the Wazuh dashboard for the detection gap

You have confirmed locally that Sysmon captured the attack. Now check whether Wazuh raised a high-severity alert for it.

  • Switch back to the Wazuh dashboard in your browser.
  • Navigate to Threat Hunting in the left menu.
  • In the search bar, add a filter for data.win.system.channel: Microsoft-Windows-Sysmon/Operational.
  • Set the time range to the last 15 minutes so you see recent events.
  • Look for an event referencing CurrentVersion\Run in the event details.

Before you check the alert severity, take a moment to predict: do you think Wazuh raised a high-severity alert for this registry modification, or did it just log it at a low informational level?

You will find that Wazuh's built-in Sysmon rules (rule IDs 61600-62099) decoded the event and logged it. However, no high-severity alert was generated. The rule level is low because the built-in rules are generic. They know a registry value was set, but they do not know that the specific path CurrentVersion\Run is a persistence mechanism.

Why is this a detection gap?

Wazuh saw the event and decoded it correctly. It knows a registry value was modified. But it did not distinguish this specific modification from thousands of harmless registry writes that happen every minute on a Windows machine.

A SOC analyst looking at the dashboard would never notice this attack among the noise. This is the gap you will fill in the next step by writing a targeted Sigma detection rule that specifically matches the persistence pattern.

You now understand the full anatomy of a persistence attack from the attacker's action through to the raw telemetry it produces. Next up, you will write a Sigma detection rule that turns this knowledge into an automated alert.

Write Your First Sigma Detection Rule

In Step 2, you saw that Wazuh's built-in Sysmon rules decoded the registry event but did not raise a high-severity alert for it. The rules are generic.

To close that gap, you need a specific, targeted detection rule. Sigma is the industry-standard vendor-neutral format that lets you write a detection once and deploy it to any SIEM. In this step, you will write your first Sigma rule and validate it.

In this step, get ready to:
  • Write a complete Sigma detection rule targeting Registry Run Key persistence.
  • Install sigma-cli and validate your rule passes with no errors.
  • Understand the detection-as-code approach that professional detection engineers use.
Create the Sigma rule file

A Sigma rule is a YAML file that describes malicious behavior in a standard, vendor-neutral format. You will create one that detects the exact registry modification you observed in Step 2.

  • On your Windows host, open a text editor (Notepad, VS Code, or any editor you prefer).
  • Create a new file called persistence_registry_run_key.yml on your Desktop.
  • Paste the following Sigma rule structure into the file:
title: Registry Run Key Persistence
id: f2eb3c07-b27a-4e6f-a2d8-3b1c5e6d9f0a
status: experimental
description: Detects modification of Windows Registry Run Keys, a common persistence technique used by attackers to maintain access across reboots.
references:
    - https://attack.mitre.org/techniques/T1547/001/
author: Your Name
date: 2026-08-03
tags:
    - attack.persistence
    - attack.t1547.001

What do these fields mean?

  • title is a human-readable name for the detection.
  • id is a unique UUID that identifies this rule globally across all Sigma rule repositories.
  • status: experimental means the rule is new and not yet battle-tested in production.
  • tags map the rule to MITRE ATT&CK techniques so analysts can immediately understand the threat context.
  • Now add the detection logic below the tags section:
logsource:
    category: registry_set
    product: windows
detection:
    selection:
        TargetObject|contains: '\CurrentVersion\Run'
    condition: selection
falsepositives:
    - Legitimate software adding itself to startup (e.g., updaters, chat clients)
level: high

What does the detection logic do?

The logsource section tells any SIEM which log category to search. Here, category: registry_set means "look at registry modification events" and product: windows scopes it to Windows logs.

The detection section defines what to match. The TargetObject|contains modifier checks whether the registry path includes \CurrentVersion\Run anywhere in the string. This catches both HKCU and HKLM Run keys.

The level: high classification tells the SOC team this alert deserves immediate attention.

  • Save the file.
  • Confirm the file exists by running this in PowerShell:
ls ~\Desktop\persistence_registry_run_key.yml

You should see the file listed with today's date.

File not found?

  • Make sure you saved it to your Desktop, not another folder.
  • Check the file extension is .yml and not .yml.txt (Notepad sometimes adds .txt silently).

help me find my Sigma rule file on Windows

✔️ Awesome, I've got everything!

Great. Double check you have saved the file before moving on.

ⓧ I'd like to double check the full code

Your complete persistence_registry_run_key.yml should look like this:

title: Registry Run Key Persistence
id: f2eb3c07-b27a-4e6f-a2d8-3b1c5e6d9f0a
status: experimental
description: Detects modification of Windows Registry Run Keys, a common persistence technique used by attackers to maintain access across reboots.
references:
    - https://attack.mitre.org/techniques/T1547/001/
author: Your Name
date: 2026-08-03
tags:
    - attack.persistence
    - attack.t1547.001
logsource:
    category: registry_set
    product: windows
detection:
    selection:
        TargetObject|contains: '\CurrentVersion\Run'
    condition: selection
falsepositives:
    - Legitimate software adding itself to startup (e.g., updaters, chat clients)
level: high
Install sigma-cli and validate the rule

A YAML file can have subtle syntax issues that only surface when a tool tries to parse it. The sigma-cli tool validates your rule against the official Sigma specification.

  • Install sigma-cli by running this command in PowerShell:
pip install sigma-cli

What is sigma-cli?

sigma-cli is the official command-line tool from the SigmaHQ project. It can validate rules for syntax errors, convert them to different SIEM formats, and manage detection rule collections. It requires Python 3.9 or higher.

pip not recognized?

  • If you see an error about pip not being recognized, try python -m pip install sigma-cli instead.
  • If Python is not installed, install Python 3.11+ from python.org and ensure you check "Add Python to PATH" during installation.

help me install sigma-cli on Windows

Before you run the validation, what do you think will happen if your YAML has a typo in the condition field?

  • Validate your Sigma rule by running:
sigma check ~\Desktop\persistence_registry_run_key.yml

You should see a summary line that reports 0 errors, 0 condition errors, and 0 issues.

Seeing errors in the output?

  • If the summary shows rule errors, check your YAML indentation. YAML requires consistent spacing (use 4 spaces, not tabs).
  • If you see a condition error, verify that your condition: selection line matches the name of your selection block exactly.
  • Fix any reported issues, save the file, and run sigma check again until it passes clean.

help me fix sigma-cli validation errors

Understand what you just built

Take a moment to appreciate the power of what you have created.

Why is Sigma vendor-neutral?

Look at your rule file. It does not mention Wazuh, Splunk, Elastic, or any specific SIEM. It describes the behavior (a registry modification to a Run key) in a standard format that can be converted to any platform.

This is the detection-as-code approach that professional detection engineers use. You write once in Sigma, then deploy to whatever SIEM your organization runs. If you change jobs and the new company uses Splunk instead of Wazuh, your detection logic still works.

Why not write Wazuh rules directly?

You could skip Sigma and write a Wazuh XML rule from scratch. But that locks your detection knowledge into one vendor.

Sigma gives you a transferable skill. The same rule you just wrote can be converted to Splunk SPL, Elastic KQL, Microsoft Sentinel, or QRadar queries. In the next step, you will manually translate it to Wazuh's native format to understand both sides.

Your Sigma rule is written, validated, and ready to deploy. Next up, you will translate this detection into Wazuh's native rule format and see it fire a real-time alert.

Deploy the Detection as a Custom Wazuh Rule

You have a validated Sigma rule that describes what to detect. The problem is that a YAML file on your disk does not protect anything. Wazuh cannot read Sigma rules natively.

In this step, you will manually translate your Sigma detection logic into Wazuh's XML rule format and deploy it so alerts fire in real-time whenever the persistence technique is executed.

In this step, get ready to:
  • Create a custom Wazuh rule file that detects Registry Run Key persistence.
  • Restart the Wazuh manager and confirm the rule loads without errors.
  • Validate the detection fires by re-running the attack simulation.
Translate the Sigma logic into a Wazuh custom rule

There is no official pySigma backend for Wazuh, so you will translate the logic by hand. This is intentional. Understanding both formats deepens your comprehension of how detections work under the hood.

Why translate manually instead of using a converter?

Sigma is vendor-neutral. Wazuh uses its own XML rule format. By translating manually, you learn how Sigma's abstract fields (like TargetObject|contains) map to Wazuh's concrete pcre2 field matching. This skill transfers to any SIEM.

  • Switch to your Ubuntu VM terminal. You will create the rule file directly on the Wazuh server.
  • Create the custom rule file by running this command:
sudo nano /var/ossec/etc/rules/custom_persistence_rules.xml
  • Paste the following XML into the file:
<group name="windows,sysmon,persistence,">

  <!-- Detect Registry Run Key persistence (T1547.001) -->
  <rule id="100200" level="12">
    <if_sid>61614</if_sid>
    <field name="win.eventdata.targetObject" type="pcre2">\\CurrentVersion\\Run</field>
    <description>Registry Run Key persistence detected: $(win.eventdata.targetObject)</description>
    <mitre>
      <id>T1547.001</id>
    </mitre>
  </rule>

</group>

What does this rule do?

  • The <group> wrapper organizes this rule under the windows,sysmon,persistence categories.
  • The <if_sid>61614</if_sid> tells Wazuh to evaluate this rule only when a Sysmon Event ID 13 (RegistryEvent: Value Set) fires. Rule 61614 is the built-in Wazuh parent rule for that event.
  • The <field name="win.eventdata.targetObject" type="pcre2"> line uses a PCRE2 regular expression to match any TargetObject containing \CurrentVersion\Run in the registry path.
  • The <mitre> block tags the alert with T1547.001 so it appears under the correct ATT&CK technique in the dashboard.
  • Rule ID 100200 is in the 100000-120000 range reserved for custom rules. Level 12 means high severity.
  • Save and close the file. In nano, press Ctrl+O, then Enter, then Ctrl+X.

Comparing Sigma to Wazuh rule format

Your Sigma rule used TargetObject|contains: '\CurrentVersion\Run'. The Wazuh equivalent is a <field> element with type="pcre2" matching the same pattern. The concept is identical. Only the syntax wrapper changes.

Restart the Wazuh manager and confirm the rule loads

Wazuh only reads rule files at startup. You need to restart the manager for your new rule to take effect.

  • Restart the Wazuh manager by running:
sudo systemctl restart wazuh-manager
  • Before you check the log, predict: do you think the rule loaded successfully, or do you expect an error?
  • Check the Wazuh log for errors by running:
sudo tail -50 /var/ossec/logs/ossec.log | grep -i "error\|custom_persistence"

If the rule loaded correctly, you should see no error lines related to your file. You may see a line indicating the rules were read successfully.

Seeing a rule error on restart?

  • Check for unclosed XML tags. Every <rule> needs a </rule> and every <group> needs a </group>.
  • Confirm your rule ID is 100200 (in the 100000-120000 custom range) and does not collide with another custom rule.
  • Make sure the <if_sid> value is 61614 (a valid parent rule ID).

Still stuck? Help me debug a Wazuh custom rule that fails to load after restart

Validate the detection fires

The moment of truth. Your rule is live. Time to simulate the attack again and see if Wazuh catches it.

  • Switch to your Windows host.
  • Open an elevated PowerShell prompt (Run as Administrator).
  • Before you run the command, predict: will your custom rule fire an alert, or will it stay silent like the built-in rules did?
  • Re-run the attack simulation with a different value name by running:
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "TestPersistence2" /t REG_SZ /d "C:\Windows\Temp\payload.exe" /f

Why a different value name?

Using TestPersistence2 instead of the original TestPersistence proves your rule detects the behavior (any write to the Run key), not a single hardcoded value name. This is what makes detection engineering powerful.

  • Return to the Wazuh dashboard in your browser.
  • Navigate to Threat Hunting (under the Discover/Events section).
  • Search for your alert. Filter or search for Registry Run Key persistence in the description field.

You should see your custom alert with level 12, the description containing "Registry Run Key persistence", and the MITRE ATT&CK section showing T1547.001.

What should the alert look like?

In the Threat Hunting view, your alert will show the rule ID 100200, level 12, and a description like "Registry Run Key persistence detected: HKCU\\...\\CurrentVersion\\Run\\TestPersistence2". The MITRE column will display T1547.001.

Compare this to Step 2 where the same behavior produced only a generic low-severity event. Your custom rule elevated the same raw telemetry into a high-severity, properly tagged alert. That is detection engineering.

Not seeing the alert in the dashboard?

  • Wait 30-60 seconds. Wazuh indexes events asynchronously, so new alerts can take a moment to appear.
  • Confirm the Wazuh manager restarted successfully with no errors (re-run the tail command from the previous substep).
  • Verify your Windows Wazuh agent is still connected. Check the Agents page in the dashboard and confirm your agent shows as Active.
  • Check that you used <if_sid>61614</if_sid> in your rule. If your Sysmon events are decoded by rule 61615 instead, try changing the parent rule ID to 61615, save, and restart the manager again.

Still stuck? Help me troubleshoot why my custom Wazuh rule is not firing alerts

✔️ Awesome, I've got everything!

Great. Double check you have saved custom_persistence_rules.xml and that the Wazuh manager is running.

ⓧ I'd like to double check the full code

Here is the complete /var/ossec/etc/rules/custom_persistence_rules.xml file:

<group name="windows,sysmon,persistence,">

  <!-- Detect Registry Run Key persistence (T1547.001) -->
  <rule id="100200" level="12">
    <if_sid>61614</if_sid>
    <field name="win.eventdata.targetObject" type="pcre2">\\CurrentVersion\\Run</field>
    <description>Registry Run Key persistence detected: $(win.eventdata.targetObject)</description>
    <mitre>
      <id>T1547.001</id>
    </mitre>
  </rule>

</group>

Your detection pipeline is now live. You simulated an attack, wrote a vendor-neutral Sigma rule, translated it into a platform-specific Wazuh rule, and watched the alert fire in real-time. Next up, you will document this detection so any SOC analyst who sees the alert knows exactly how to triage it.

Document Your Detection with ATT&CK Context

Your custom Wazuh rule is firing alerts in real-time when a Registry Run Key persistence attack occurs. You have a complete detection pipeline from raw Sysmon event to SIEM alert. Now you need to make it production-ready.

What happens when this alert fires at 3 AM and a junior analyst is on call? Without documentation, they won't know if it's a real attack or a false positive from a legitimate software update. In this step, you will create analyst-ready documentation and clean up your test environment.

In this step, get ready to:
  • Create a DETECTION_README.md documenting your detection with full ATT&CK context.
  • Clean up your test registry artifacts and confirm Sysmon logs the cleanup.
Create your detection documentation file

Professional SOC teams maintain documentation alongside every detection rule. This documentation tells an analyst what the alert means, how to tell a real attack from a false alarm, and what to do next.

  • Create a new file called DETECTION_README.md in the same folder as your persistence_registry_run_key.yml Sigma rule.
  • Add the technique overview and context by pasting this content:
# Detection: Registry Run Key Persistence (T1547.001)

## ATT&CK Technique

- **Technique**: T1547.001 - Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder
- **Tactic**: Persistence
- **Description**: Adversaries add programs to the Windows Registry Run Keys to execute malware when a user logs in. This provides persistent access without needing to re-exploit the victim.

## Why This Matters

Registry Run Keys are one of the most common persistence mechanisms. Attackers use them because they survive reboots, require no special privileges (HKCU), and blend in with legitimate software entries. Detecting modifications to these keys is a foundational SOC capability.

What does this section cover?

  • The ATT&CK Technique section gives any analyst the official MITRE reference and a plain-English description of what the attack does.
  • The Why This Matters section explains why this specific registry path is high-value for detection. HKCU Run Keys don't require admin privileges, making them a low-barrier persistence option for attackers.
  • Save DETECTION_README.md.
  • Now add the detection logic section below what you just wrote:
## Detection Logic

### Sigma Rule

The file `persistence_registry_run_key.yml` detects any process writing a value to the `CurrentVersion\Run` registry path.

- **Logsource**: category: registry_set, product: windows
- **Detection**: TargetObject containing `\CurrentVersion\Run`
- **Tags**: attack.persistence, attack.t1547.001

### Wazuh Rule

The custom rule in `/var/ossec/etc/rules/custom_persistence_rules.xml` triggers on Sysmon Event ID 13 (RegistryEvent: Value Set) when the TargetObject matches the Run key path pattern. It uses parent rule 61614/61615 with pcre2 matching and tags MITRE T1547.001.

What does this section cover?

This section links your two detection artifacts together. The Sigma rule is the vendor-neutral description of what to detect. The Wazuh rule is the platform-specific implementation that actually fires alerts.

An analyst reading this documentation can trace the logic from the abstract detection (Sigma) to the concrete alert (Wazuh) without digging through config files.

  • Save DETECTION_README.md.
  • Add the final section covering true/false positive guidance and triage steps:
## True Positive vs False Positive

### True Positive Indicators

- Unknown or suspicious process (cmd.exe, powershell.exe, unsigned binary) writing to Run keys
- Value data points to a path in Temp, AppData, or other unusual directories
- No corresponding legitimate software installation event

### False Positive Examples

- Legitimate software installers adding auto-start entries (Spotify, Discord, OneDrive)
- System management tools updating startup configurations
- Recently installed applications registering themselves

## Recommended Triage Steps

1. Identify the process that made the registry change (Image field in Sysmon event)
2. Check if the binary path in the Details field is signed and from a known vendor
3. Correlate with recent software installs or user activity on the endpoint
4. If suspicious, isolate the endpoint and collect the binary for analysis
5. Check for other persistence mechanisms on the same host

Why include false positive examples?

Real-world SOC teams get flooded with alerts. If every Spotify auto-update triggers an investigation, analysts burn out and start ignoring alerts entirely.

By documenting known false positives, you give analysts a quick checklist to eliminate noise. The triage steps then guide them through what to do when the alert is real.

  • Save DETECTION_README.md.

Your documentation file is complete. It covers the full context an analyst needs to triage this alert confidently.

✔️ Awesome, I've got everything!

Great. Double check you've saved DETECTION_README.md with all three sections present.

ⓧ I'd like to double check the full code

Scroll up and confirm your DETECTION_README.md contains these three chunks in order:

  • Chunk 1: The # Detection heading, ## ATT&CK Technique section, and ## Why This Matters section.
  • Chunk 2: The ## Detection Logic section with both Sigma Rule and Wazuh Rule subsections.
  • Chunk 3: The ## True Positive vs False Positive section and ## Recommended Triage Steps numbered list.

File not saving correctly?

  • Make sure the file extension is .md and not .md.txt. Some editors add a hidden .txt extension.
  • Confirm you are saving in the same folder as your persistence_registry_run_key.yml file.

Help me troubleshoot saving my DETECTION_README.md file.

Clean up your test artifacts

Your test registry keys (TestPersistence and TestPersistence2) are still sitting in your Windows startup path. These point to a non-existent executable, so they won't cause harm. But leaving test artifacts behind is bad practice.

  • Remove both test registry values by running these commands in an elevated PowerShell prompt:
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "TestPersistence" /f
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "TestPersistence2" /f

What does this command do?

  • reg delete removes a registry value from the specified path.
  • /v specifies the value name to delete.
  • /f forces the deletion without a confirmation prompt.
  • Confirm both commands report success. You should see The operation completed successfully. for each one.

Seeing 'The system was unable to find the specified registry key or value'?

This means the key was already removed. If you only created one test value (TestPersistence but not TestPersistence2), you will see this error for the one that doesn't exist. That is fine. Move on to the next step.

Help me figure out why my registry delete command is failing.

Before you check Event Viewer, what Sysmon Event ID do you think the registry deletion generates?

  • Open Event Viewer on your Windows host.
  • Navigate to Applications and Services Logs > Microsoft > Windows > Sysmon > Operational.
  • Filter for Event ID 12 (RegistryEvent: Object create and delete).
  • Find the recent events showing your TestPersistence and TestPersistence2 values being deleted from the CurrentVersion\Run path.

Sysmon Event ID 12 logs registry object creation and deletion. You should see entries with EventType DeleteValue and the TargetObject pointing to your test keys.

Why does this matter?

Even the cleanup step produces telemetry. This is the core principle of detection engineering: every action on an endpoint leaves traces. If an attacker tried to cover their tracks by deleting their persistence key, your Sysmon configuration would still capture that deletion event.

Secret mission

Detect Scheduled Task Persistence (T1053.005)

A real attacker does not rely on a single persistence technique. Can you repeat the detection engineering workflow for a second technique, Scheduled Task creation, and deploy a working Wazuh alert independently?

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely on your local machine and VirtualBox VM, so there are no ongoing cloud costs. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • Wazuh 4.14 server (indexer, manager, dashboard) running on your Ubuntu VM.
  • Wazuh agent installed on your Windows host.
  • Sysmon v15.15 installed on your Windows host.
  • sigma-cli installed via pip on your Windows host.
  • Local project files: persistence_registry_run_key.yml, persistence_scheduled_task.yml, and DETECTION_README.md.
  • Custom Wazuh rules file: /var/ossec/etc/rules/custom_persistence_rules.xml on the Ubuntu VM.

Keep everything running

No action needed. Choose this if you are still actively building detections or plan to add more Sigma rules soon.

  • Your Ubuntu VM continues running Wazuh and ingesting Sysmon events from your Windows host.
  • Sysmon remains installed and logging to Event Viewer.
  • Your Sigma rule files and documentation stay on disk for future reference.
  • The VM uses approximately 8 GB of RAM while running.

Pause - I'll come back to this later

Shut down your VM to free up RAM and CPU on your host machine. Your files and configuration stay intact for when you return.

  • In VirtualBox, right-click your Ubuntu VM and select Close then Save State. This preserves the VM exactly as it is.
  • The Wazuh agent on Windows will show as disconnected in the dashboard until you start the VM again.
  • Sysmon continues logging locally on your Windows host. Events will be forwarded to Wazuh once the VM is running again.
  • Your Sigma rule files and DETECTION_README.md remain on disk.

Delete - I don't want to use this again

Remove all project resources and start fresh. Follow each step below to fully clean up.

Remove the Wazuh agent from Windows
  • Open an elevated Command Prompt on Windows.
  • Uninstall the Wazuh agent by running:
msiexec.exe /x wazuh-agent-4.14.7-1.msi /qn

What if I don't have the MSI file?

If you no longer have the original installer file, open Settings then Apps & features on Windows, search for "Wazuh Agent", and click Uninstall.

Uninstall Sysmon from Windows
  • In your elevated Command Prompt, uninstall Sysmon by running:
sysmon64 -u
Uninstall sigma-cli
  • Uninstall sigma-cli by running:
pip uninstall sigma-cli -y
Delete local project files
  • Delete your Sigma rule files and documentation from wherever you saved them on your Windows host:
del persistence_registry_run_key.yml
del persistence_scheduled_task.yml
del DETECTION_README.md
Remove the Wazuh server and Ubuntu VM
  • Start the Ubuntu VM and open a terminal.
  • Download the Wazuh installation assistant and run the uninstall command:
curl -sO https://packages.wazuh.com/4.14/wazuh-install.sh
sudo bash wazuh-install.sh --uninstall
  • After the uninstall completes, shut down the Ubuntu VM.
  • In VirtualBox, right-click the Ubuntu VM, select Remove, then choose Delete all files to reclaim disk space.

Nice Work!

Nice Work!

You just built a complete detection engineering pipeline from scratch. You can now simulate an attack, analyze its telemetry, write a vendor-neutral detection rule, deploy it to a live SIEM, and watch the alert fire in real-time.

You learned how to:

  • Build a detection engineering lab with Wazuh SIEM ingesting live Sysmon telemetry from your Windows endpoint.
  • Simulate a real-world persistence attack (MITRE ATT&CK T1547.001) and write a vendor-neutral Sigma detection rule from scratch using the industry-standard format.
  • Deploy a custom Wazuh rule with full ATT&CK technique mapping that fires alerts in real-time, and document it with analyst triage guidance for your team.
  • Secret Mission: Extended your detection coverage to Scheduled Task persistence (T1053.005) using the same repeatable workflow.

Ready to quiz yourself?