Detection Engineering with Wazuh

Write custom SIEM rules that catch real MITRE ATT&CK techniques.

Introduction

30 Second Summary

Think about how a security camera only helps if someone is actually watching the footage. Organizations collect millions of log events from their systems, but without specific rules that flag suspicious behavior, real attacks hide in plain sight.

In this project, you will build a detection engineering lab where you simulate a real credential dumping attack on a Windows endpoint and discover what your SIEM catches versus what it misses. You will then write custom detection rules that close the gap, mapping them to the MITRE ATT&CK framework.

What You'll Build

You will run a credential dumping attack on a Windows VM, watch your custom rule fire a high-severity alert in real-time on the Wazuh dashboard, and see the exact MITRE ATT&CK technique ID tagged alongside it.

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

  • A working detection lab where you simulate a credential dumping attack and watch YOUR rule fire an alert showing "T1003.001 - LSASS Memory Access Detected" in the Wazuh dashboard.
  • The attacker-to-defender mindset shift: you can explain exactly what log field triggers your rule, what Sysmon event captures the behavior, and why it differs from normal system activity.
  • A repeatable detection engineering workflow you can apply to any ATT&CK technique: simulate an attack, observe telemetry, write a rule, test it, validate it live, and tune false positives.
  • Secret Mission: Independently detect suspicious encoded PowerShell execution and build a reusable rule documentation template.

Are there any prerequisites?

This project assumes you already have VirtualBox installed with two VMs ready: an Ubuntu VM with Docker and Docker Compose set up, and a Windows VM with the OS installed (an evaluation ISO is fine).

You should also have basic familiarity with the Linux command line and PowerShell. The Ubuntu VM needs at least 4 CPU cores and 8 GB of RAM to run the Wazuh stack.

Before We Start

Before any hands-on work begins, let's get clear on what you're building and why it matters for your path into detection engineering. This is your moment to commit to the goal so every command, rule, and test you run connects back to a clear purpose.

Deploy Wazuh SIEM on Docker

Before you can write detection rules that catch attackers, you need a central SIEM that receives and analyzes security logs from your endpoints.

In this step, you will deploy Wazuh on Docker. Docker gives you the full stack (manager, indexer, and dashboard) in minutes without manually installing each component separately.

In this step, get ready to:
  • Set the required kernel parameter for the Wazuh indexer.
  • Clone the Wazuh Docker repository and generate SSL certificates.
  • Start all three Wazuh containers and confirm the dashboard is accessible.
Prepare the Docker environment on the Ubuntu VM

The Wazuh indexer needs more virtual memory areas than the Linux default allows. You need to increase the kernel limit before starting the containers.

  • Open a terminal on your Ubuntu VM.
  • Note your Ubuntu VM's IP address by running this command:
hostname -I

You will see one or more IP addresses printed. The first one is typically your VM's primary IP. Write it down because you will use it throughout this project.

  • Increase the virtual memory map count by running this command:
sudo sysctl -w vm.max_map_count=262144

Why do we need to change vm.max_map_count?

The Wazuh indexer maps files directly from disk into memory to speed up searches across your security logs. Linux defaults to a limit of 65530 memory-mapped areas, but the indexer needs at least 262144. Without this change, the indexer container will crash on startup.

  • Verify the setting took effect by running:
sysctl vm.max_map_count

You should see vm.max_map_count = 262144 in the output.

  • Clone the Wazuh Docker repository (version v4.14.7) by running this command:
git clone https://github.com/wazuh/wazuh-docker.git -b v4.14.7

You should see Git downloading the repository files. When it finishes, a wazuh-docker folder appears in your home directory.

Seeing a connection error?

Make sure your Ubuntu VM has internet access. Try ping google.com to confirm connectivity. If your VM uses a host-only network adapter, you may need to add a NAT adapter in VirtualBox for internet access.

Help me troubleshoot network connectivity on my Ubuntu VM in VirtualBox.

Generate certificates and start the stack

The Wazuh components communicate over TLS, so you need to generate SSL certificates before starting the services.

  • Navigate to the single-node deployment directory by running:
cd ~/wazuh-docker/single-node/
  • Generate the SSL certificates by running this command:
docker compose -f generate-indexer-certs.yml run --rm generator

You should see output showing certificate files being created. This generates the TLS certificates that the indexer, manager, and dashboard use to communicate securely.

Seeing a permission denied error?

If Docker requires sudo, prepend sudo to the command. Alternatively, ensure your user is in the docker group by running groups and checking for docker in the output.

Help me fix Docker permission issues on my Ubuntu VM.

  • Start all three Wazuh services by running:
docker compose up -d

Docker will pull the Wazuh images (this may take a few minutes on the first run) and start three containers in the background.

What are the three containers?

The Wazuh single-node stack runs three containers. The manager receives and analyzes logs from agents. The indexer stores alerts and enables fast searching. The dashboard provides the web interface where you'll view alerts and write rules.

  • Wait 60 to 90 seconds for the services to fully initialize, then confirm all three containers are healthy by running:
docker compose ps

You should see three containers listed with a running status:

  • single-node-wazuh.manager-1
  • single-node-wazuh.indexer-1
  • single-node-wazuh.dashboard-1

Containers not all running?

If the indexer container is restarting, the vm.max_map_count setting may not have applied. Run sysctl vm.max_map_count to confirm it shows 262144. If not, re-run the sysctl command from earlier and restart the stack with docker compose restart.

If a container shows as unhealthy, check its logs with docker compose logs <service-name> where the service name is wazuh.manager, wazuh.indexer, or wazuh.dashboard.

Help me debug my Wazuh Docker containers that aren't starting properly.

Verify the deployment

All three containers are running. Now confirm you can access the Wazuh dashboard through your browser.

Before you open the dashboard, what do you think you will see at the login page? Think about what credentials the default deployment might use.

  • Open a web browser on your host machine (or inside the Ubuntu VM if it has a desktop).
  • Navigate to the Wazuh dashboard URL:
https://[[UBUNTU_VM_IP="your Ubuntu VM's IP address"]]
  • Your browser will warn about a self-signed certificate. Click Advanced and then Proceed (or Accept the Risk, depending on your browser) to continue.
  • Log in with the default credentials:
  • Username: admin
  • Password: SecretPassword

You should see the Wazuh dashboard load with an overview page. It will show zero agents connected because you have not enrolled any endpoints yet.

Why is the certificate self-signed?

The certificates you generated earlier are self-signed because this is a lab environment. In production, you would replace them with certificates from a trusted certificate authority. The self-signed certificates still encrypt traffic between your browser and the dashboard.

Dashboard not loading?

Make sure you are using https:// (not http://). The dashboard listens on port 443. If using VirtualBox host-only networking, confirm your host can reach the Ubuntu VM's IP by running ping against it from your host terminal.

Help me access the Wazuh dashboard from my host browser.

Your SIEM is live. You have a central brain ready to receive and analyze security logs. Next up, you will instrument your Windows endpoint with Sysmon and the Wazuh agent so the SIEM has real telemetry to work with.

Instrument the Windows Endpoint

Your Wazuh SIEM is up and running, ready to receive logs. But right now it has no idea what is happening on your Windows VM.

A SIEM without endpoint telemetry is blind. In this step, you will install Sysmon for deep process-level visibility and the Wazuh agent to ship those events to your SIEM in real-time.

In this step, get ready to:
  • Install Sysmon with a community-vetted configuration on your Windows VM.
  • Install and enroll the Wazuh agent so your Windows VM reports to your SIEM.
  • Confirm live events are flowing into the Wazuh dashboard.
Install Sysmon with SwiftOnSecurity configuration

Standard Windows Event Logs record basic events, but they miss critical details like which process accessed which other process. Sysmon fills that gap by logging process creation, network connections, and process access events at a level of detail that makes threat detection possible.

  • Switch to your Windows VM.
  • Open a browser and download Sysmon from the official Microsoft Sysinternals page:

https://download.sysinternals.com/files/Sysmon.zip

  • Extract the ZIP file to a folder on your desktop (e.g., C:\Sysmon).
  • Next, download the SwiftOnSecurity Sysmon configuration file. In your browser, navigate to:

https://github.com/SwiftOnSecurity/sysmon-config/blob/master/sysmonconfig-export.xml

  • Click the download raw file button and save sysmonconfig-export.xml into the same folder where you extracted Sysmon (e.g., C:\Sysmon).
  • Open PowerShell as Administrator by right-clicking the Start menu and selecting Windows PowerShell (Admin) or Terminal (Admin).
  • Navigate to your Sysmon folder by running:
cd C:\Sysmon
  • Install Sysmon with the SwiftOnSecurity configuration by running:
.\sysmon64.exe -accepteula -i sysmonconfig-export.xml

What does this command do?

  • sysmon64.exe is the 64-bit Sysmon binary.
  • -accepteula automatically accepts the Sysinternals license agreement.
  • -i sysmonconfig-export.xml installs Sysmon as a Windows service using the SwiftOnSecurity configuration, which defines what events to capture and what noise to filter out.
  • Verify Sysmon is running by executing:
Get-Service Sysmon64

You should see the service listed with a Status of Running.

Sysmon64 service not showing as Running?

  • Make sure you ran PowerShell as Administrator. Sysmon requires elevated privileges to install.
  • Check that sysmonconfig-export.xml is in the same directory as sysmon64.exe. If it is in a subfolder, the install command cannot find it.
  • help me troubleshoot why Sysmon64 is not installing or running on my Windows VM
Install and enroll the Wazuh agent

Sysmon captures the telemetry, but it stays on the Windows VM until something ships it to your SIEM. The Wazuh agent reads Windows Event Logs (including the Sysmon channel) and forwards them to the Wazuh manager in real-time.

  • Still on the Windows VM, download the Wazuh agent 4.14.7 MSI from the official packages page:

https://packages.wazuh.com/4.x/windows/wazuh-agent-4.14.7-1.msi

  • Once the download completes, navigate in PowerShell (still as Administrator) to the folder containing the MSI. If you saved it to Downloads, run:
cd ~\Downloads
  • Install the agent and point it to your Ubuntu VM (where Wazuh manager is running) by executing:
.\wazuh-agent-4.14.7-1.msi /q WAZUH_MANAGER="[[UBUNTU_VM_IP="your Ubuntu VM IP address"]]"

What does this command do?

  • /q runs a silent (unattended) installation with no GUI prompts.
  • WAZUH_MANAGER tells the agent which server to send logs to. Replace this with the IP address of your Ubuntu VM where the Wazuh Docker stack is running.
  • Start the Wazuh agent service by running:
net start WazuhSvc

You should see a message confirming the service started successfully.

WazuhSvc failed to start?

  • Verify your Ubuntu VM IP is correct. On the Ubuntu VM, run ip addr to confirm its IP address matches what you entered in the install command.
  • Check network connectivity. From the Windows VM, try ping <ubuntu-vm-ip> to confirm the VMs can reach each other.
  • Make sure the Wazuh manager container is still running. On the Ubuntu VM, run docker compose ps from the ~/wazuh-docker/single-node/ directory.
  • help me troubleshoot why my Wazuh agent cannot connect to the manager
Confirm event flow in the dashboard

The agent needs a minute or two to register with the manager. Once it does, you will see your Windows endpoint appear in the Wazuh dashboard and Sysmon events streaming in.

  • Wait 1-2 minutes for the agent to register.
  • Switch back to the Wazuh dashboard in your browser (https://<ubuntu-vm-ip>, logged in as admin).
  • In the left navigation menu, click Agents.
  • Confirm your Windows VM appears in the agent list with status Active.

Agent not showing as Active?

  • Give it another minute and refresh the page. First-time registration can take up to 2 minutes.
  • If the agent still does not appear, on the Windows VM check the agent log at C:\Program Files (x86)\ossec-agent\ossec.log for connection errors.
  • help me figure out why my Wazuh agent is not appearing as Active in the dashboard
  • Click on your Windows agent name to open its detail page.
  • Select the Security Events section.
  • You should see Sysmon events flowing in. Look for entries with Event IDs like 1 (process creation), 3 (network connection), 10 (process access), and 11 (file creation).

Before you check, what do you think you will see when you open Notepad on the Windows VM?

  • On the Windows VM, open Notepad (press the Windows key, type Notepad, press Enter).
  • Wait 10-15 seconds, then return to the Wazuh dashboard Security Events and refresh.
  • You should see a new Sysmon Event ID 1 (process creation) entry for notepad.exe. This proves that every process launch on your Windows VM is now being captured and shipped to your SIEM.

Why does this matter?

Without Sysmon, Windows only logs basic security events. With Sysmon and the Wazuh agent together, you get deep visibility into what every process does on the endpoint. This is the raw material you need to write detection rules in the next steps.

Your Windows endpoint is now fully instrumented. Every process, network connection, and cross-process access is being logged and shipped to your SIEM. Next up, you will simulate a real attack and discover what Wazuh catches with its default rules.

Simulate an Attack and Observe What Wazuh Misses

You have a running SIEM with endpoint telemetry flowing in. That feels like security. But here is the uncomfortable truth: having data is not the same as detecting attacks.

Wazuh ships with thousands of default rules that cover common events. They are broad by design. In this step, you will simulate a real credential dumping attack (MITRE ATT&CK technique T1003.001) and discover firsthand that the default rules either miss it entirely or produce a generic alert with no context about what actually happened.

In this step, get ready to:
  • Install Atomic Red Team on the Windows VM as your attack simulation framework.
  • Simulate a credential dumping attack targeting LSASS memory.
  • Investigate what Wazuh caught and identify the detection gap.
Install Atomic Red Team on the Windows VM

To simulate attacks reproducibly, you need a framework that maps directly to MITRE ATT&CK techniques. Atomic Red Team provides single-command test cases for over 1800 techniques that you can run and clean up safely.

  • Switch to your Windows VM and open PowerShell as Administrator.
  • Set the execution policy to allow script installation by running this command:
Set-ExecutionPolicy Bypass -Scope CurrentUser -Force
  • Install Atomic Red Team with all atomics by running this command:
IEX (IWR 'https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/install-atomicredteam.ps1' -UseBasicParsing); Install-AtomicRedTeam -getAtomics -Force

What does this command do?

This downloads the Invoke-AtomicRedTeam execution framework and all atomic test definitions. The -getAtomics flag pulls the full library of attack simulations. The -Force flag skips confirmation prompts.

Everything installs to C:\AtomicRedTeam\ by default. This may take a few minutes depending on your network speed.

  • Verify the installation succeeded by importing the module and querying the technique you will use:
Import-Module C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1; Get-AtomicTechnique T1003.001

You should see output displaying the technique name "OS Credential Dumping: LSASS Memory" along with a list of available atomic tests.

Command not recognized?

If you see an error about the module not being found, confirm the install path exists by running Test-Path C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1 in PowerShell. If it returns False, re-run the install command above.

If PowerShell blocks the script, make sure you ran the Set-ExecutionPolicy command first and that your PowerShell window is running as Administrator.

Help me troubleshoot why Get-AtomicTechnique is not recognized after installing Atomic Red Team.

Execute the credential dumping simulation

T1003.001 simulates a process accessing LSASS memory. This is the exact technique that tools like Mimikatz use to steal credentials from a running Windows system.

  • First, download any prerequisites the test needs by running:
Invoke-AtomicTest T1003.001 -GetPrereqs

What does this do?

Some atomic tests need external tools (like ProcDump from Sysinternals) to run. The -GetPrereqs flag downloads these tools automatically so the attack simulation can execute properly.

  • Run the first atomic test for T1003.001 by executing:
Invoke-AtomicTest T1003.001 -TestNumbers 1

What just happened?

This simulated a process accessing lsass.exe memory. In a real attack, this is how an attacker extracts passwords, hashes, and Kerberos tickets from a running Windows system.

The Sysmon agent on your Windows VM captured this behavior as a series of events (particularly Event ID 10, which logs process access). The Wazuh agent shipped those events to your SIEM. Now the question is: did the SIEM understand what it received?

  • Wait 30-60 seconds for the events to flow from the Windows agent through to the Wazuh dashboard.
Investigate the Wazuh dashboard: what did it catch?

This is the moment of truth. You just ran a credential dumping attack. Before you look at the dashboard, take a moment to predict what you expect to see.

Do you think Wazuh will show a specific alert about credential dumping? Will it mention LSASS? Will it map the behavior to T1003.001?

  • Switch back to your browser with the Wazuh dashboard open.
  • Navigate to your Windows agent's Security Events section.
  • Filter the events to show only the last 5 minutes.
  • Search for any alert mentioning LSASS, credential dumping, or T1003.

Here is what you will find: either no specific alert at all, or a generic Sysmon Event ID 10 alert with no context about what it means. There is nothing that says "credential dumping" or "LSASS access" with a T1003.001 mapping.

Why did Wazuh miss this?

The SIEM received the telemetry. Sysmon correctly logged that a process accessed lsass.exe memory. But Wazuh's default rules only provide generic alerting for Sysmon events by Event ID.

They do not contain logic that says "a process accessing lsass.exe is suspicious." The default rules see Event ID 10 and record it, but they do not understand the significance of the target being LSASS specifically. This is the gap between having telemetry and having detection.

  • Clean up the attack simulation on your Windows VM by running:
Invoke-AtomicTest T1003.001 -TestNumbers 1 -Cleanup

Why clean up?

Atomic Red Team tests often leave artifacts on disk (dump files, downloaded tools). The -Cleanup flag removes these artifacts so your VM stays in a known-good state for the next test.

Seeing a specific LSASS alert?

If you see a targeted alert about LSASS access, your Wazuh deployment may include community rules or a newer rule pack that was not present in the default install. Check whether the rule ID is in the 61600-62099 range (default Sysmon rules) or in the 100000+ range (custom rules added by your distribution).

For this project, the important observation is whether the alert explicitly names the T1003.001 technique and provides actionable context. A generic "Sysmon Event 10" alert without MITRE mapping still represents the detection gap we are closing.

Help me determine if I'm seeing default Wazuh rules or custom community rules after running T1003.001.

You have now experienced the core problem that detection engineers solve every day. Your SIEM has the data. It just does not know what the data means yet. In the next step, you will write the rule that teaches it.

Write a Custom Detection Rule

In the last step, you ran a real credential dumping simulation and discovered the detection gap firsthand. Your SIEM received the telemetry but its default rules did not understand the significance of a process accessing lsass.exe.

Now you will close that gap by writing your own detection logic. You will author a custom Wazuh rule that says exactly what the default rules do not: "a process accessing LSASS memory is suspicious and maps to MITRE ATT&CK technique T1003.001."

In this step, get ready to:
  • Examine real Sysmon Event 10 telemetry inside the Wazuh manager to understand what LSASS access looks like in logs.
  • Write a custom detection rule in local_rules.xml with proper MITRE ATT&CK mapping.
  • Validate the rule fires correctly using wazuh-logtest.
Understand the telemetry: what does LSASS access look like in logs?

Before writing a detection rule, you need to understand exactly what the attacker behavior looks like in your logs. This is the detection engineer mindset: observe first, then codify what you observed into rule logic.

  • Switch to your Ubuntu VM terminal and access the Wazuh manager container by running:
  • Enter the running Wazuh manager container:
docker exec -it single-node-wazuh.manager-1 bash
  • Search the archives log for Sysmon Event 10 entries that reference lsass by running:
grep -i "lsass" /var/ossec/logs/archives/archives.log | tail -5

You should see JSON log entries containing fields like win.system.eventID set to 10, win.eventdata.targetImage containing lsass.exe, and win.eventdata.sourceImage showing which process did the access.

What are these fields?

Sysmon Event 10 (ProcessAccess) fires whenever one process opens a handle to another. Wazuh decodes the event into the win.eventdata.* namespace.

  • targetImage is the process being accessed (in our case, lsass.exe).
  • sourceImage is the process that opened the handle (the attacker tool).
  • These two fields are the signature you will codify into a rule.
Write the custom rule in local_rules.xml

Wazuh stores custom rules in /var/ossec/etc/rules/local_rules.xml. Your rule will chain from the existing Sysmon Event 10 parent rule (ID 61612) and add specific logic to detect LSASS access.

  • Open the custom rules file for editing inside the container by running:
vi /var/ossec/etc/rules/local_rules.xml
  • Add the following rule block inside the existing <group> tags (or create a new group if the file is empty):
<group name="custom_sysmon,">
  <rule id="100002" level="12">
    <if_sid>61612</if_sid>
    <field name="win.eventdata.targetImage">lsass.exe</field>
    <description>Possible credential dumping: process accessed LSASS memory</description>
    <mitre>
      <id>T1003.001</id>
    </mitre>
  </rule>
</group>

What does this rule do?

  • if_sid 61612 means this rule only evaluates when the parent Sysmon Event 10 rule has already matched. This is called rule chaining.
  • The <field> tag checks if win.eventdata.targetImage contains lsass.exe. Only events where a process accessed LSASS will fire this rule.
  • Level 12 marks this as a high-severity alert (Wazuh levels range from 0 to 16).
  • The <mitre> block maps the alert directly to T1003.001 (OS Credential Dumping: LSASS Memory), so your dashboard shows the exact technique.
  • Rule ID 100002 falls within the custom rule range of 100000 to 120000.
  • Save and close the file (in vi: press Esc, type :wq, then press Enter).

Getting a 'permission denied' error?

Make sure you are inside the Wazuh manager container (your prompt should show the container's hostname, not your Ubuntu VM hostname). If you are not inside the container, run docker exec -it single-node-wazuh.manager-1 bash first.

If vi is not available, try nano instead. Help me edit local_rules.xml inside the Wazuh Docker container

Test the rule with wazuh-logtest

Before restarting the manager and waiting for live events, you can validate your rule logic instantly using wazuh-logtest. This tool lets you paste a sample log line and see which rules fire against it.

  • Inside the manager container, launch the logtest tool by running:
/var/ossec/bin/wazuh-logtest

You will see a prompt that says Type one log per line.

  • Paste a sample Sysmon Event 10 log line that targets lsass.exe. Use one from your archives.log output earlier (the JSON line containing lsass.exe in targetImage).

Finding a sample log line

Open a second terminal to the container (or use Ctrl+Z to background logtest). Run grep -i "lsass" /var/ossec/logs/archives/archives.log | tail -1 and copy the JSON portion of the output (everything after the timestamp and agent header). Paste that into wazuh-logtest.

Before you check the output, predict: do you expect to see your rule fire at Phase 3, or do you think it will only show the generic Sysmon Event 10 match?

After pasting, you should see output like this in Phase 3:

**Phase 3: Completed filtering (rules).
        id: '100002'
        level: '12'
        description: 'Possible credential dumping: process accessed LSASS memory'
        mitre.id: '['T1003.001']'

What does this output confirm?

  • Phase 3 shows your custom rule ID 100002 fired (not just the generic parent rule).
  • The level is 12 (high severity, as you configured).
  • The MITRE mapping T1003.001 is present. This is what will show on the dashboard.
  • Your description appears exactly as written. SOC analysts will see this message when the alert fires.

Rule not firing in Phase 3?

  • Check that if_sid is set to 61612 (the Sysmon Event 10 parent rule). A wrong ID means your rule never evaluates.
  • Verify the field name is exactly win.eventdata.targetImage. Capitalization matters.
  • Make sure your log line actually contains lsass.exe in the targetImage field.
  • Confirm the rule XML is well-formed (no missing closing tags).

Help me debug why my custom rule isn't firing in wazuh-logtest

  • Exit logtest by pressing Ctrl+C.
  • Restart the Wazuh manager to load your new rule into the live analysis pipeline by running:
/var/ossec/bin/wazuh-control restart

Wait 10-15 seconds for the manager to restart. You should see messages indicating the services are starting up.

  • Confirm the manager is running by running:
/var/ossec/bin/wazuh-control status

All services (wazuh-analysisd, wazuh-remoted, etc.) should show as running.

Manager won't restart?

If the restart fails, it usually means your XML has a syntax error. Check the error output for a line number, then re-open local_rules.xml and fix the XML syntax (common issues: missing closing tags, mismatched quotes, or a typo in <group>).

Help me fix a Wazuh manager restart failure caused by my custom rule XML

Your custom detection rule is written, tested, and loaded. In the next step, you will prove it works end-to-end: run the attack again on Windows and watch YOUR alert appear in the Wazuh dashboard with the T1003.001 MITRE tag.

Validate the Detection Live

Your rule passed the logic test inside wazuh-logtest. That proves the pattern-matching works in isolation.

Now you need to prove the full chain works end-to-end: an attack fires on Windows, the Wazuh agent ships the event, the manager evaluates your rule, and the dashboard displays the alert with the correct MITRE ATT&CK technique tag. This is what separates a rule that works on paper from one that works in production.

In this step, get ready to:
  • Re-run the credential dumping simulation and confirm your custom alert appears in the Wazuh dashboard.
  • Investigate false positives and tune your rule to exclude legitimate LSASS access.
  • Document your detection rule for future reference.
Re-run the attack and confirm detection

In Step 3, you ran this same attack and the dashboard showed nothing meaningful. This time, your custom rule is loaded and waiting.

  • Switch to your Windows VM and open PowerShell as Administrator.
  • Import the Atomic Red Team module and re-run the T1003.001 simulation by running:
Import-Module C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1
Invoke-AtomicTest T1003.001 -TestNumbers 1

What does this command do?

This runs the same credential dumping simulation from earlier. A process will attempt to read the memory of lsass.exe, mimicking what tools like Mimikatz do to steal credentials.

The difference now is that your custom rule is actively watching for this exact behavior in the incoming Sysmon Event 10 telemetry.

Before you check the dashboard, think about this: what do you expect to see differently this time compared to Step 3?

  • Wait 30 to 60 seconds for the event to flow from the Windows agent to the Wazuh manager.
  • Switch back to the Wazuh dashboard in your browser.
  • Click into your Windows agent, then navigate to Security Events.
  • In the search bar at the top, type rule.level:>=10 and press Enter to filter for high-severity alerts.
  • Set the time range to the last 5 minutes using the time picker in the top right.

You should see a Level 12 alert with the description "Possible credential dumping: process accessed LSASS memory" and the MITRE ATT&CK technique T1003.001 tagged.

  • Click into the alert to expand the full event data.
  • Look at the win.eventdata.sourceImage field. This tells you exactly which process accessed LSASS memory.

Why does this matter?

Seeing the full event data is what a SOC analyst does during triage. The source process tells you whether this is a known attack tool, a legitimate system process, or something suspicious that needs investigation.

Don't see the alert?

If no Level 12 alert appears after 60 seconds, check these common causes:

  • Make sure the Wazuh manager was restarted after you saved local_rules.xml in the previous step. Run /var/ossec/bin/wazuh-control restart inside the manager container.
  • Confirm the Windows agent is still active. In the dashboard, go to Agents and verify its status is Active.
  • Try widening the time range to 15 minutes in case there was a delay in event delivery.

Need more help? Why isn't my custom Wazuh rule firing for the T1003.001 attack simulation?

Check for false positives

Your rule detects ANY process accessing lsass.exe memory. Some Windows system processes do this legitimately as part of normal operations.

  • Leave your Windows VM running normally for 2 to 3 minutes. Open a few applications, browse the web, let the system settle.
  • Return to the Wazuh dashboard and check Security Events again with the rule.level:>=10 filter.
  • Look for any alerts from your rule that were NOT caused by Atomic Red Team.

If you see alerts where the win.eventdata.sourceImage is a known legitimate process like csrss.exe or services.exe, those are false positives that need tuning.

  • If you observe false positives, access the Wazuh manager container on your Ubuntu VM by running:
docker exec -it single-node-wazuh.manager-1 bash
  • Open your custom rules file for editing:
vi /var/ossec/etc/rules/local_rules.xml
  • Inside your existing rule block, add an exclusion line for each legitimate process. For example, to exclude csrss.exe, add this field with the negate attribute:
<field name="win.eventdata.sourceImage" negate="yes">csrss.exe</field>

What does negate do?

The negate="yes" attribute flips the match logic. Instead of "fire when this field matches," it means "only fire when this field does NOT match." This excludes known-safe processes from triggering your alert while still catching everything else that touches LSASS.

  • Save the file and restart the Wazuh manager to load the updated rule:
/var/ossec/bin/wazuh-control restart
  • Now re-run the attack on your Windows VM to confirm the tuned rule still detects malicious access:
Invoke-AtomicTest T1003.001 -TestNumbers 1
  • Wait 30 to 60 seconds, then check the dashboard again with rule.level:>=10.
  • Your alert should still appear for the Atomic Red Team attack, but no longer fire for the excluded system processes.

No false positives observed?

If your rule did not fire on any legitimate processes during normal usage, no tuning is needed yet. This is a good result. In a production environment, you would monitor over days or weeks before declaring a rule tuned.

Rule stopped firing after tuning?

  • Check that the negate field excludes only the specific process, not a wildcard that accidentally matches the attack tool.
  • Test your updated rule in wazuh-logtest again with a sample log line targeting lsass.exe from a non-excluded process to confirm it still fires.

Still stuck? My Wazuh rule stopped detecting after I added negate exclusions. How do I fix it?

Document your detection

Every detection rule in a production SOC has documentation. When the rule fires at 3 AM and an on-call analyst sees it, they need to know what it means and what to investigate.

  • Record the following information for your rule (use any text file, notes app, or markdown document):
  • Rule ID: the custom ID you chose (in the 100000-120000 range).
  • Description: Possible credential dumping: process accessed LSASS memory.
  • MITRE Technique: T1003.001 (OS Credential Dumping: LSASS Memory).
  • What triggers it: any process accessing lsass.exe memory, captured via Sysmon Event 10.
  • Known false positives: list any processes you excluded (e.g., csrss.exe, services.exe).
  • Tuning decisions: why you excluded those processes and how you confirmed they are legitimate.

Why document detections?

Detection documentation is what separates a professional SOC from a collection of alert noise. Without it, every analyst who sees the alert has to reverse-engineer what it means from scratch.

In interviews, demonstrating that you document your detections shows you think about operability, not just detection logic.

  • Finally, clean up the attack simulation on your Windows VM by running:
Invoke-AtomicTest T1003.001 -TestNumbers 1 -Cleanup

What does cleanup do?

The -Cleanup flag reverses any changes the test made to your system. Atomic Red Team tests are designed to be run and rolled back repeatedly, so your lab stays clean between simulations.

You have now completed the full detection engineering loop: simulate, observe, detect, test, validate live, tune, and document.

You have proven your detection works end-to-end. The attack fired on Windows, traveled through the agent, triggered your custom rule in the manager, and surfaced in the dashboard with full MITRE ATT&CK context. Next up, you will apply this same workflow independently to detect a completely different attack technique.

Secret mission

Detect Suspicious PowerShell Execution

You proved you can write a detection rule with guidance. Can you do it independently for a completely different technique? Attackers frequently use encoded PowerShell commands to slip past basic string-matching defenses. Apply the same detection engineering loop to T1059.001 and prove you own the workflow.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely in VirtualBox VMs on your local machine, 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 Docker stack (3 containers: manager, indexer, dashboard) on Ubuntu VM.
  • Wazuh agent service on Windows VM.
  • Sysmon service and driver on Windows VM.
  • Atomic Red Team files at C:\AtomicRedTeam\ on Windows VM.
  • Custom detection rules in local_rules.xml inside the Wazuh manager container.
  • The cloned wazuh-docker directory on Ubuntu VM.

Keep everything running

No action needed. Choose this if you plan to continue building detections or experimenting with new ATT&CK techniques in the near future.

  • Your Wazuh stack continues running inside Docker on the Ubuntu VM. It consumes RAM and CPU only while the VM is active.
  • Sysmon remains installed on the Windows VM, generating telemetry into the Wazuh agent.
  • Your custom rules in local_rules.xml persist inside the Docker volume.
  • Atomic Red Team stays at C:\AtomicRedTeam\ ready for more tests.

Pause - I'll come back to this later

Shut down the VMs to free up host machine resources while preserving all your work for later.

  • On the Ubuntu VM, stop the Wazuh Docker stack by navigating to ~/wazuh-docker/single-node/ and running:
  • docker compose stop (this halts containers without removing them or their data).
  • On the Windows VM, stop the Wazuh agent service by running net stop WazuhSvc in an elevated command prompt.
  • Shut down both VMs from VirtualBox (right-click the VM, select Close, then Save State).
  • When you return, start the VMs and run docker compose start from ~/wazuh-docker/single-node/ to bring Wazuh back up.

Delete - I don't want to use this again

Remove all project resources and start fresh. Follow these steps on each VM.

On the Ubuntu VM
  • Stop and remove the Wazuh Docker stack (containers, networks, and volumes) by running:
cd ~/wazuh-docker/single-node/
docker compose down -v
  • Remove the cloned repository by running:
rm -rf ~/wazuh-docker
  • Optionally revert the sysctl setting by removing the vm.max_map_count=262144 line from /etc/sysctl.conf (if you added it there) and running sudo sysctl --system.
On the Windows VM (run PowerShell as Administrator)
  • Uninstall Sysmon by running:
sysmon64.exe -u
  • Uninstall the Wazuh agent. Make sure the original MSI is in your working directory, then run:
msiexec.exe /x wazuh-agent-4.14.7-1.msi /qn
  • Delete the Atomic Red Team files by running:
Remove-Item -Recurse -Force C:\AtomicRedTeam
  • Reset the PowerShell execution policy if you no longer need it bypassed:
Set-ExecutionPolicy Restricted -Scope CurrentUser -Force

Delete the VMs entirely

If you no longer need the lab at all, you can delete the Ubuntu and Windows VMs from VirtualBox. Right-click each VM, select Remove, then choose Delete all files. This frees all disk space used by the virtual hard drives.

Nice Work!

Nice Work!

Nice work! You built a fully functional detection engineering lab and wrote custom Wazuh rules that catch real attacker techniques in real-time.

You've learned how to:

  • Build a detection engineering lab with Wazuh SIEM receiving Sysmon telemetry from a Windows endpoint, and experience firsthand how default rules miss specific attacker behaviors.
  • Write custom Wazuh detection rules that catch credential dumping (T1003.001) with proper MITRE ATT&CK technique mapping, then validate them end-to-end with attack simulation, alert confirmation, and false positive tuning.
  • Apply the detection engineering loop: simulate, observe, detect, test, tune, and document.
  • Secret Mission: Independently detect encoded PowerShell execution (T1059.001), proving you can repeat this workflow for any ATT&CK technique.

Ready to quiz yourself?