Build a Home SOC Lab with Wazuh

Deploy a Wazuh SIEM, write custom detection rules, and simulate attacks.

Introduction

30 Second Summary

Every time you hear about a data breach on the news, there's a team behind the scenes that either caught it in time or missed it entirely. The difference comes down to how well their detection systems are configured and tested.

In this project, you will build a complete home Security Operations Center lab with a Wazuh SIEM server, custom detection rules mapped to real attack techniques, and automated attack simulations to validate your defenses.

What You'll Build

A production-grade home SOC lab with custom detection engineering, endpoint monitoring, and attack simulation capabilities.

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

  • A Wazuh SIEM server (Manager + Indexer + Dashboard) running on Ubuntu, with a Windows endpoint streaming full Sysmon telemetry and PowerShell Script Block Logging.
  • Three custom detection rules mapped to specific MITRE ATT&CK techniques, plus File Integrity Monitoring configured for sensitive directories.
  • A validated detection pipeline tested with Atomic Red Team attack simulations, proving your rules fire correctly on real techniques.
  • Secret Mission: Configure Active Response to automatically block an IP after repeated failed login attempts.

Are there any prerequisites?

You need a computer with at least 16 GB RAM and 50 GB free disk space to run the virtual machines comfortably. Familiarity with the Linux command line and basic networking concepts (IP addresses, ports) is expected.

Before We Start

Building a home SOC lab requires a few foundational tools before you start creating virtual machines and installing security software. Your Wazuh server will run inside a virtual machine, so you need virtualization software and an operating system image ready to go.

In this step, you will confirm your hardware meets the requirements, install VirtualBox for running VMs, and download the Ubuntu Server ISO that will power your SIEM.

In this step, get ready to:
  • Confirm your system has at least 16 GB RAM and 50 GB free disk space.
  • Install VirtualBox on your host machine.
  • Download the Ubuntu 22.04 LTS Server ISO.
Check your system requirements

The Wazuh all-in-one deployment needs 4 vCPU, 8 GB RAM, and 50 GB storage just for the server VM. Your host machine needs enough resources left over to run your own OS and a Windows endpoint.

  • Confirm your computer has at least 16 GB of total RAM.
  • Confirm you have at least 50 GB of free disk space available for the Ubuntu VM.
  • Confirm you have a Windows 10 or Windows 11 machine available (your host, or a second VM if you have the resources).

How do I check my RAM?

On macOS, click the Apple menu and select About This Mac. On Windows, press Ctrl+Shift+Esc to open Task Manager, then check the Performance tab.

If your machine has only 8 GB RAM, you can still attempt this project, but performance will be tight. 16 GB is the recommended minimum.

Install VirtualBox

VirtualBox is a free, open-source virtualization tool that lets you run entire operating systems inside your current computer. You will use it to host the Ubuntu server that runs your Wazuh SIEM.

  • Open your browser and navigate to the VirtualBox downloads page.
  • Under VirtualBox Platform Packages, click the download link for your operating system (Windows or macOS).
  • Run the downloaded installer and follow the default prompts to complete the installation.

What is VirtualBox?

VirtualBox is a general-purpose full virtualization tool for x86_64 hardware. It lets you create and run virtual machines on your laptop or desktop without needing separate physical servers.

Each virtual machine acts as an isolated computer with its own operating system, network interfaces, and storage. This is how you will build your SOC lab without needing multiple physical machines.

✔️ VirtualBox installed successfully

You should be able to open VirtualBox and see the VirtualBox Manager window. No VMs are listed yet.

ⓧ The installer failed or I see an error

  • On Windows, make sure you ran the installer as Administrator.
  • On macOS, you may need to allow the kernel extension in System Settings > Privacy & Security. Look for a message about Oracle and click Allow.
  • Restart your computer after allowing the kernel extension, then try opening VirtualBox again.
Download the Ubuntu 22.04 LTS Server ISO

Your Wazuh SIEM will run on Ubuntu Server. The Server edition has no graphical interface, which keeps resource usage low and is standard practice for security infrastructure.

  • Open your browser and navigate to the Ubuntu 22.04 LTS release page.
  • Scroll down to the Server install image section.
  • Click the 64-bit PC (AMD64) server install image link to download ubuntu-22.04.5-live-server-amd64.iso.
  • Wait for the download to complete. The file is approximately 2 GB.

Why Ubuntu 22.04 LTS?

Wazuh officially supports Ubuntu 22.04 for its central components. LTS (Long-Term Support) means this version receives security updates for five years, making it a stable foundation for security tooling.

The Server edition skips the desktop GUI entirely, so all 8 GB of your VM's RAM goes directly to Wazuh's indexing and alerting processes.

Download taking too long?

The ISO is about 2 GB. If your connection is slow, look for the BitTorrent download option on the same page for a faster alternative.

Help me find a faster way to download the Ubuntu ISO.

Your host machine is ready. Next up, you will create the Ubuntu VM and install the full Wazuh stack on it.

Set Up the Wazuh Server VM

Every SIEM needs a dedicated server to collect, index, and correlate security events from across your network.

In this step, you will create an Ubuntu Server virtual machine and install the full Wazuh stack on it. This gives you a Manager, Indexer, and Dashboard all running on a single host.

In this step, get ready to:
  • Create an Ubuntu 22.04 Server VM in VirtualBox.
  • Install the Wazuh all-in-one stack using the quickstart installer.
  • Access and verify the Wazuh Dashboard.
Create an Ubuntu 22.04 Server VM

Wazuh requires 4 CPU cores, 8 GB RAM, and 50 GB storage at minimum. You will configure a VirtualBox VM with these specs and install Ubuntu Server on it.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type VirtualBox and press Enter to open it.
  • Click New in the toolbar to start the Create Virtual Machine wizard.
  • In the Name field, enter Wazuh-Server.
  • In the ISO Image field, click the dropdown and select the Ubuntu 22.04 LTS Server ISO you downloaded earlier.
  • VirtualBox auto-detects the OS type. Confirm that Type is set to Linux and Version is set to Ubuntu (64-bit).
  • Check the Skip Unattended Installation checkbox so you can follow the installer prompts manually.
  • Click Next to proceed to the Hardware page.

Why skip unattended installation?

Unattended installation automates the OS setup, but skipping it lets you choose your own username, password, and SSH settings. These matter later when you SSH into the server to manage Wazuh.

  • On the Hardware page, set Base Memory to 8192 MB (8 GB).
  • Set Processors to 4 CPU cores.
  • Click Next to proceed to the Virtual Hard Disk page.
  • Set the disk size to 50 GB.
  • Click Next to review the summary, then click Finish to create the VM.

Before starting the VM, you need to change the network adapter so the VM gets its own IP address on your local network.

  • Select your Wazuh-Server VM in the machine list, then click Settings.
  • Go to the Network section.
  • Change Attached to from NAT to Bridged Adapter.
  • Click OK to save.

Why use Bridged Adapter?

Bridged Adapter gives your VM its own IP address on your home network. This lets your host machine (and later your Windows endpoint) communicate with Wazuh directly using a real IP address, just like a physical server on the network.

Now start the VM and install Ubuntu Server.

  • Double-click your Wazuh-Server VM to start it. The VM boots from the Ubuntu ISO automatically.
  • The Ubuntu installer is text-based. Use the arrow keys, Tab, and Enter to navigate through each screen.
  • Select your language and press Enter.
  • Keep the default keyboard layout and select Done.
  • On the type of install screen, keep Ubuntu Server selected and choose Done.
  • On the network screen, confirm your interface received an IP via DHCP and select Done.
  • Skip the proxy screen (leave it blank) and select Done.
  • Keep the default Ubuntu archive mirror and select Done.
  • On the storage configuration screen, keep Use an entire disk selected and choose Done.
  • Confirm the storage summary and select Done. When warned about a destructive action, select Continue.
  • On the Profile Setup screen, enter a server name, username, and password. Remember these credentials for later.
  • Skip Ubuntu Pro and select Continue.
  • On the SSH screen, press Space to check Install OpenSSH server, then select Done.
  • Skip the Featured Server Snaps screen and select Done.
  • Wait for the installation to complete, then select Reboot Now.

Note your IP address

After Ubuntu finishes installing and reboots, log in with your username and password. Run ip a to find your VM's IP address. Write this down. You will need it to access the Wazuh Dashboard from your host browser.

VM not booting from the ISO?

If you see a black screen with no installer, make sure the Ubuntu ISO is attached in Settings > Storage under the optical drive. Also confirm that your host machine has hardware virtualization enabled in BIOS (often called VT-x or AMD-V).

Help me troubleshoot my VM boot issue

Install Wazuh using the quickstart installer

With Ubuntu running, you will now install the entire Wazuh stack in a single command. The quickstart installer deploys the Wazuh Manager, Wazuh Indexer, and Wazuh Dashboard together on one host.

  • Update your system packages by running this command:
sudo apt update && sudo apt upgrade -y
  • 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?

This command downloads the Wazuh 4.14 installation script from the official Wazuh repository and immediately runs it with the -a flag. The -a flag tells the script to install all components (Manager, Indexer, and Dashboard) on this single host.

The installation takes approximately 5-10 minutes depending on your internet connection. When it completes, it prints the dashboard URL, the username admin, and a randomly generated password.

  • When the installer finishes, copy the admin password from the terminal output and save it somewhere safe.

Missed the password?

If you lost the installer output, retrieve your credentials by running:

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

Installation failed or timed out?

Confirm your VM has internet access by running ping -c 4 google.com. If the ping fails, check that your network adapter is set to Bridged Adapter in VirtualBox settings. Also verify you allocated 8 GB RAM. The installer will fail with less than 4 GB available.

Help me fix my Wazuh installation

Access and verify the Wazuh Dashboard

The Wazuh Dashboard is a web interface where you will monitor security events, view alerts, and manage your agents. You access it from your host machine's browser.

  • On your host machine (not inside the VM), open a web browser.
  • Navigate to the Wazuh Dashboard by entering this URL in your address bar:
https://[[WAZUH_IP="your Ubuntu VM's IP address"]]
  • Your browser will show a security warning about the self-signed certificate. Click Advanced and then Proceed (or Accept the Risk depending on your browser) to continue.
  • Log in with username admin and the password from the installer output.

You should see the Wazuh Dashboard with zero agents connected. This confirms the server is running and ready to receive data from endpoints.

Why does the browser show a certificate warning?

The Wazuh quickstart installer generates a self-signed SSL certificate for HTTPS. Your browser does not trust it because it was not issued by a recognized Certificate Authority. This is perfectly safe for a home lab environment.

Cannot reach the dashboard?

Make sure you are using https:// (not http://) in the URL. If the page still does not load, verify the VM's IP address by running ip a inside the VM. Confirm your host and VM are on the same network (both using Bridged Adapter).

Help me connect to my Wazuh Dashboard

Your Wazuh server is up and running. Next up, you will connect a Windows endpoint with full security telemetry so the SIEM has real data to analyze.

Deploy the Wazuh Agent and Sysmon on Windows

Your Wazuh server is live and waiting for data. A SIEM without endpoints feeding it logs is like a security camera with no lens.

In this step, you will connect your Windows machine to the Wazuh server as a monitored endpoint. You will also install Sysmon to generate rich security telemetry that the default Windows Event Logs do not provide.

In this step, get ready to:
  • Deploy the Wazuh agent on Windows and connect it to your server.
  • Install Sysmon with a security-focused configuration for deep endpoint visibility.
  • Enable PowerShell Script Block Logging so your SIEM captures full script contents.
Deploy the Wazuh agent from the dashboard

The Wazuh agent is lightweight software that runs on your Windows machine. It collects logs and security events, then sends them to the Wazuh Manager over an encrypted channel.

  • In the Wazuh dashboard, click the upper-left menu icon (the three horizontal lines).
  • Expand Agents management in the sidebar.
  • Select Summary.
  • Click Deploy new agent.
  • Select Windows as the operating system.
  • Enter your Wazuh server's IP address (the Ubuntu VM IP) in the Server address field.
  • Give the agent a name (for example, windows-endpoint).
  • The dashboard generates a PowerShell command for you. Copy this command.

What is the Wazuh agent?

The agent is a small service that monitors your endpoint. It watches log sources you configure, collects events in real time, and forwards them to the Wazuh Manager for analysis and alerting.

Once connected, the manager can also push configurations (like File Integrity Monitoring rules) down to the agent remotely.

  • On your Windows machine, open PowerShell as Administrator. Press the Windows key, type PowerShell, right-click Windows PowerShell, and select Run as administrator.
  • Paste and run the generated command from the dashboard. This downloads and installs the Wazuh agent with your server's IP pre-configured.
  • Start the Wazuh agent service by running this command:
NET START WazuhSvc

What does this command do?

NET START WazuhSvc starts the Wazuh agent Windows service. Once running, it immediately begins communicating with your Wazuh Manager and sending security events.

  • Return to the Wazuh dashboard in your browser.
  • Click the upper-left menu icon, expand Agents management, and select Summary.
  • After a minute or two, your Windows agent should appear with a status of Active (green).

Agent not showing as Active?

Make sure your Ubuntu VM and Windows machine are on the same network. Both need to be on the same subnet if you used Bridged Adapter networking in VirtualBox.

Check that the Wazuh server IP you entered during agent deployment matches your Ubuntu VM's actual IP address. Run ip a on your Ubuntu VM to confirm.

Verify the service is running on Windows by opening PowerShell and running Get-Service WazuhSvc. The status should show Running.

Help me troubleshoot why my Wazuh agent is not connecting to the manager.

Install Sysmon with a security-focused configuration

Windows Event Logs capture basic activity, but they miss critical details like full command-line arguments and parent-child process relationships. Sysmon fills this gap by generating detailed telemetry for process creation, network connections, file changes, and more.

  • On your Windows machine, download Sysmon from the official Microsoft Sysinternals page:
Invoke-WebRequest -Uri "https://download.sysinternals.com/files/Sysmon.zip" -OutFile "$env:USERPROFILE\Downloads\Sysmon.zip"

What is Sysmon?

Sysmon (System Monitor) is a Microsoft Sysinternals tool that logs detailed system activity to the Windows Event Log. It tracks process creation with full command lines, network connections, file creation time changes, and more.

Without Sysmon, your SIEM only sees basic Windows events. With it, you gain the visibility needed to detect techniques like encoded PowerShell execution and credential dumping.

  • Extract the ZIP file to a folder. Create C:\Sysmon and extract the contents there:
Expand-Archive -Path "$env:USERPROFILE\Downloads\Sysmon.zip" -DestinationPath "C:\Sysmon" -Force
  • Download the SwiftOnSecurity Sysmon configuration file by running:
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/SwiftOnSecurity/sysmon-config/master/sysmonconfig-export.xml" -OutFile "C:\Sysmon\sysmonconfig-export.xml"

Why use the SwiftOnSecurity configuration?

The SwiftOnSecurity configuration is the industry-standard community template for security monitoring with Sysmon. It filters out noisy, low-value events and focuses on high-signal activity like suspicious process creation and network connections.

Running Sysmon without a configuration generates overwhelming noise. This template gives you security-relevant telemetry from day one.

  • Install Sysmon with the configuration by running this command in the same PowerShell window:
C:\Sysmon\sysmon64 -accepteula -i C:\Sysmon\sysmonconfig-export.xml

What does this command do?

sysmon64 -accepteula -i sysmonconfig-export.xml installs the 64-bit version of Sysmon as a Windows service. The -accepteula flag accepts the license agreement. The -i flag tells Sysmon to install using the specified configuration file.

  • You should see output confirming that Sysmon was installed and the service started successfully.

Seeing an access denied error?

Make sure you are running PowerShell as Administrator. Sysmon installs as a system service and requires elevated permissions.

If you see an error about the file not being found, confirm you extracted the ZIP to C:\Sysmon and that sysmon64.exe exists in that folder.

Help me troubleshoot my Sysmon installation on Windows.

Now you need to tell the Wazuh agent to collect Sysmon logs. The agent does not read Sysmon events by default.

  • Open the Wazuh agent configuration file in Notepad 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 XML block to tell Wazuh to ingest Sysmon logs:
<localfile>
  <location>Microsoft-Windows-Sysmon/Operational</location>
  <log_format>eventchannel</log_format>
</localfile>

What does this configuration do?

This tells the Wazuh agent to subscribe to the Microsoft-Windows-Sysmon/Operational Windows Event Log channel. The eventchannel log format uses the Windows Event Channel API to read events in real time.

Without this entry, Sysmon generates events locally but Wazuh never sees them. This bridge is what makes your Sysmon telemetry visible in the SIEM dashboard.

  • Save the file (Ctrl+S) but keep Notepad open. You will add one more entry in the next substep.

Permission denied when saving?

Make sure you opened Notepad from an Administrator PowerShell window. The Wazuh agent config file is in a protected system directory and requires elevated permissions to edit.

Help me edit the Wazuh agent ossec.conf file on Windows.

Enable PowerShell Script Block Logging

Attackers frequently use PowerShell for post-exploitation because it is built into every Windows system. Script Block Logging records the full content of every PowerShell script that executes, even if the attacker tries to obfuscate it.

  • Open Group Policy Editor. Press the Windows key, type gpedit.msc, and press Enter.
  • In the left pane, expand Computer Configuration.
  • Expand Administrative Templates, then expand Windows Components.
  • Click Windows PowerShell.
  • Double-click Turn on PowerShell Script Block Logging.
  • Select Enabled, then click OK.

Why enable Script Block Logging?

Encoded and obfuscated PowerShell commands are a hallmark of modern malware. Script Block Logging captures the decoded content of scripts before they execute. This means even if an attacker uses Base64 encoding, you see the actual malicious code in your SIEM.

Now add the PowerShell log channel to the Wazuh agent configuration, just like you did for Sysmon.

  • Switch back to the Notepad window with ossec.conf open.
  • Find the Sysmon <localfile> block you just added. Below it, add this new block:
<localfile>
  <location>Microsoft-Windows-PowerShell/Operational</location>
  <log_format>eventchannel</log_format>
</localfile>

What does this capture?

The Microsoft-Windows-PowerShell/Operational channel records Script Block Logging events (Event ID 4104). When combined with Sysmon's process creation events, you get full visibility into both what PowerShell ran and what it did on the system.

  • Save the file (Ctrl+S) and close Notepad.
  • Restart the Wazuh agent to apply both configuration changes by running this in your Administrator PowerShell:
NET STOP WazuhSvc && NET START WazuhSvc

What does this do?

This stops and restarts the Wazuh agent service. The agent re-reads ossec.conf on startup, which activates the two new <localfile> entries. From this point forward, Sysmon and PowerShell events flow into your Wazuh server.

  • Return to the Wazuh dashboard. Your Windows agent should still show as Active under Agents management.
  • Click on your agent name to view its details. Within a few minutes, you should start seeing events from the Sysmon and PowerShell log channels appearing.

No Sysmon events appearing in the dashboard?

Make sure Sysmon is running as a service. Open PowerShell and run Get-Service Sysmon64. The status should show Running.

Double-check that the <location> value in ossec.conf is exactly Microsoft-Windows-Sysmon/Operational with no typos or extra spaces.

Confirm you restarted WazuhSvc after editing the config. Changes to ossec.conf only take effect after a service restart.

Help me troubleshoot why Sysmon events are not appearing in my Wazuh dashboard.

✔️ Awesome, I've got everything!

Great. Double check you saved ossec.conf and restarted the Wazuh agent service.

ⓧ I'd like to double check the full config

Your ossec.conf file should now contain these two new <localfile> blocks (in addition to whatever was already in the file):

<localfile>
  <location>Microsoft-Windows-Sysmon/Operational</location>
  <log_format>eventchannel</log_format>
</localfile>

<localfile>
  <location>Microsoft-Windows-PowerShell/Operational</location>
  <log_format>eventchannel</log_format>
</localfile>

Your Windows endpoint is now feeding rich security telemetry into your SIEM. Next up, you will write custom detection rules that fire on specific attack techniques mapped to the MITRE ATT&CK framework.

Write Custom Detection Rules

Your Wazuh server is now receiving rich telemetry from your Windows endpoint. Sysmon process events, PowerShell script logs, and system activity are all flowing into the Wazuh Indexer.

The default Wazuh ruleset catches common threats, but real SOC teams write their own detection rules tailored to specific attack techniques. In this step, you will write three custom rules mapped to the MITRE ATT&CK framework, each targeting a different stage of a typical attack chain.

In this step, get ready to:
  • Write a detection rule for encoded PowerShell execution (T1059.001).
  • Write a detection rule for LSASS credential dumping (T1003.001).
  • Write a detection rule for Office applications spawning shell processes (T1566.001).
Write a rule for encoded PowerShell execution

Attackers frequently obfuscate malicious commands by encoding them in Base64 before passing them to PowerShell. This technique (MITRE T1059.001) is one of the most common indicators of post-exploitation activity.

  • SSH into your Wazuh server (the Ubuntu VM) by running this command from your host machine's terminal:
ssh [[UBUNTU_USER="your Ubuntu username"]]@[[WAZUH_IP="your Ubuntu VM IP address"]]
  • Open the custom rules file in a text editor by running:
sudo nano /var/ossec/etc/rules/local_rules.xml

What is local_rules.xml?

Wazuh stores its built-in rules in /var/ossec/ruleset/rules/. Those files get overwritten during upgrades.

The file /var/ossec/etc/rules/local_rules.xml is where you place custom rules. Anything here is preserved across updates. Wazuh recommends using rule IDs between 100000 and 120000 to avoid conflicts with built-in rules.

  • Add your first custom rule by pasting the following XML into the file:
<group name="custom_sysmon,">
  <rule id="100001" level="12">
    <if_sid>61603</if_sid>
    <field name="win.eventdata.commandLine" type="pcre2">(?i)-enc|-EncodedCommand</field>
    <description>Encoded PowerShell command detected - possible malware execution</description>
    <mitre>
      <id>T1059.001</id>
    </mitre>
  </rule>
</group>

What does this rule do?

  • if_sid 61603 means this rule only fires when the parent Sysmon "Process Creation" rule has already matched. This ensures you only inspect process-creation events from Sysmon.
  • The field element uses a PCRE2 regex to check whether the command line contains -enc or -EncodedCommand. The (?i) flag makes the match case-insensitive.
  • level="12" sets the alert severity to "high." Wazuh levels range from 0 (ignored) to 16 (severe attack).
  • The <mitre> tag maps this alert to MITRE ATT&CK technique T1059.001 (Command and Scripting Interpreter: PowerShell). This mapping appears in the Wazuh dashboard during analyst triage.

You won't see a change yet. The rule takes effect after you restart the Wazuh Manager later in this step.

Write a rule for credential dumping indicators

One of the highest-severity indicators of compromise is an attacker accessing the LSASS process in memory. LSASS (Local Security Authority Subsystem Service) stores credential data. Tools like Mimikatz target this process to steal passwords and hashes.

  • Below the first rule's closing </group> tag, paste the following rule:
<group name="custom_sysmon,">
  <rule id="100002" level="14">
    <if_sid>61644</if_sid>
    <field name="win.eventdata.targetImage" type="pcre2">(?i)lsass\.exe</field>
    <description>Process accessed LSASS memory - possible credential dumping</description>
    <mitre>
      <id>T1003.001</id>
    </mitre>
  </rule>
</group>

What does this rule do?

  • if_sid 61644 hooks into the Sysmon "Process Access" parent rule. This fires when one process opens a handle to another process.
  • The field element checks whether the target process is lsass.exe. Any process reaching into LSASS memory is a critical red flag.
  • level="14" is the highest severity of your three rules because credential theft is an immediate, actionable finding.
  • MITRE T1003.001 maps to "OS Credential Dumping: LSASS Memory."

You won't see a change yet. The next rule completes the set before you restart the manager.

Write a rule for suspicious process creation from Office

Phishing attacks often trick users into opening a document with a malicious macro. When that macro fires, it typically spawns a command shell or scripting engine. Legitimate Office usage almost never does this, so the signal is very high fidelity.

  • Below the second rule's closing </group> tag, paste the following rule:
<group name="custom_sysmon,">
  <rule id="100003" level="12">
    <if_sid>61603</if_sid>
    <field name="win.eventdata.parentImage" type="pcre2">(?i)(WINWORD|EXCEL|POWERPNT)\.EXE</field>
    <field name="win.eventdata.image" type="pcre2">(?i)(cmd|powershell|wscript|cscript)\.exe</field>
    <description>Office application spawned suspicious process - possible macro execution</description>
    <mitre>
      <id>T1566.001</id>
    </mitre>
  </rule>
</group>

What does this rule do?

  • This rule also uses if_sid 61603 (Sysmon Process Creation), but it adds TWO field conditions that must both match.
  • The first field checks whether the parent process is a Microsoft Office application (Word, Excel, or PowerPoint).
  • The second field checks whether the child process is a shell or scripting engine (cmd.exe, powershell.exe, wscript.exe, or cscript.exe).
  • MITRE T1566.001 maps to "Phishing: Spearphishing Attachment." Only when both conditions are true does the alert fire.
  • Save the file by pressing Ctrl+O then Enter, and exit nano with Ctrl+X.
  • Restart the Wazuh Manager to load your new rules by running:
sudo systemctl restart wazuh-manager
  • Verify the manager started without errors by running:
sudo systemctl status wazuh-manager

You should see active (running) in green. This confirms Wazuh loaded your custom rules without encountering XML syntax errors.

Seeing "failed" or a syntax error?

  • Run sudo cat /var/ossec/logs/ossec.log | tail -20 to see the specific error. The log typically names the line number with the problem.
  • Check that every opening <group> tag has a matching </group> and every <rule> has a matching </rule>.
  • Make sure there are no stray characters before the first <group> tag or after the last </group> tag.

Why is my Wazuh Manager failing to restart after I added custom rules?

✔️ Awesome, I've got everything!

Great. Double check you saved local_rules.xml and that wazuh-manager shows active.

ⓧ I'd like to double check the full code

Here is the complete content you should have in /var/ossec/etc/rules/local_rules.xml:

<group name="custom_sysmon,">
  <rule id="100001" level="12">
    <if_sid>61603</if_sid>
    <field name="win.eventdata.commandLine" type="pcre2">(?i)-enc|-EncodedCommand</field>
    <description>Encoded PowerShell command detected - possible malware execution</description>
    <mitre>
      <id>T1059.001</id>
    </mitre>
  </rule>
</group>

<group name="custom_sysmon,">
  <rule id="100002" level="14">
    <if_sid>61644</if_sid>
    <field name="win.eventdata.targetImage" type="pcre2">(?i)lsass\.exe</field>
    <description>Process accessed LSASS memory - possible credential dumping</description>
    <mitre>
      <id>T1003.001</id>
    </mitre>
  </rule>
</group>

<group name="custom_sysmon,">
  <rule id="100003" level="12">
    <if_sid>61603</if_sid>
    <field name="win.eventdata.parentImage" type="pcre2">(?i)(WINWORD|EXCEL|POWERPNT)\.EXE</field>
    <field name="win.eventdata.image" type="pcre2">(?i)(cmd|powershell|wscript|cscript)\.exe</field>
    <description>Office application spawned suspicious process - possible macro execution</description>
    <mitre>
      <id>T1566.001</id>
    </mitre>
  </rule>
</group>

Your detection rules are live. Next up, you will configure File Integrity Monitoring to catch unauthorized changes to sensitive files on your Windows endpoint.

Configure File Integrity Monitoring

Your custom detection rules are ready to catch specific attack techniques. Now you need a way to detect unauthorized changes to critical system files.

Attackers often modify system configuration files to establish persistence or cover their tracks. File Integrity Monitoring (FIM) watches sensitive directories and alerts you the moment a file is created, modified, or deleted.

In this step, get ready to:
  • Configure FIM directories on the Wazuh server for centralized monitoring.
  • Trigger and verify FIM alerts by modifying a monitored file.
  • Confirm real-time detection speed.
Configure FIM on the Wazuh server

Instead of editing the configuration file on every agent individually, Wazuh supports centralized configuration. You edit a single file on the manager and it automatically pushes the settings to all agents in the group.

  • SSH into your Ubuntu VM (the Wazuh server) by running this command from your host terminal:
ssh [[UBUNTU_USER="your-username"]]@[[UBUNTU_VM_IP="your Ubuntu VM IP address"]]
  • Open the centralized agent configuration file for the default group by running:
sudo nano /var/ossec/etc/shared/default/agent.conf
  • Add the following FIM configuration to the file. This tells all agents in the default group to monitor three sensitive Windows directories in real time:
<agent_config>
  <syscheck>
    <directories check_all="yes" realtime="yes">C:\Windows\System32\drivers\etc</directories>
    <directories check_all="yes" realtime="yes">C:\Users\Public</directories>
    <directories check_all="yes" realtime="yes">C:\Windows\System32\config</directories>
  </syscheck>
</agent_config>

What does this configuration do?

The <agent_config> wrapper tells Wazuh this is a centralized configuration block that gets pushed to all agents in the default group.

  • check_all="yes" monitors all file attributes: permissions, owner, size, MD5/SHA1/SHA256 checksums, and timestamps.
  • realtime="yes" enables continuous monitoring instead of periodic scans. Changes trigger alerts within seconds rather than waiting for the next 12-hour scan cycle.
  • C:\Windows\System32\drivers\etc contains the hosts file, which attackers modify to redirect DNS.
  • C:\Users\Public is a shared folder that malware often uses as a staging directory.
  • C:\Windows\System32\config stores the Windows registry hives, which are critical system databases.
  • Save the file by pressing Ctrl+O then Enter, and exit with Ctrl+X.
  • Restart the Wazuh manager to distribute the new configuration more quickly by running:
sudo systemctl restart wazuh-manager
  • The manager automatically pushes the updated configuration to all connected agents. With every agent keepalive (every 10 seconds by default), the agent checks for configuration changes and applies them immediately.

Agent not picking up the new config?

If FIM events do not appear after a couple of minutes, the agent may not have synced yet. You can force a sync by restarting the Windows agent manually. Open a Command Prompt as Administrator on your Windows machine and run:

NET STOP WazuhSvc && NET START WazuhSvc

Also verify that /var/ossec/etc/shared/default/agent.conf has no XML syntax errors. A missing closing tag or mismatched angle bracket will prevent the configuration from being pushed.

Help me troubleshoot why my FIM configuration isn't being applied to my Windows agent

✔️ Awesome, I've got everything!

Great. Make sure you have saved agent.conf and restarted the Wazuh manager.

ⓧ I'd like to double check the full code

Here is the complete /var/ossec/etc/shared/default/agent.conf file:

<agent_config>
  <syscheck>
    <directories check_all="yes" realtime="yes">C:\Windows\System32\drivers\etc</directories>
    <directories check_all="yes" realtime="yes">C:\Users\Public</directories>
    <directories check_all="yes" realtime="yes">C:\Windows\System32\config</directories>
  </syscheck>
</agent_config>
Trigger and verify FIM alerts

Now you will test that FIM is working by creating, modifying, and deleting a file in one of the monitored directories on your Windows machine.

  • On your Windows machine, open a Command Prompt as Administrator.
  • Create a test file in the monitored C:\Users\Public directory by running:
echo "FIM test file" > C:\Users\Public\test.txt
  • Wait about 10 seconds for the agent to report the change.
  • Modify the file by running:
echo "Modified content" >> C:\Users\Public\test.txt
  • Wait another 10 seconds, then delete the file by running:
del C:\Users\Public\test.txt
  • Return to the Wazuh dashboard in your browser.
  • Navigate to the File Integrity Monitoring module for your Windows agent.
  • You should see events showing the file creation, modification, and deletion of C:\Users\Public\test.txt with full details including checksums and timestamps.

What should I see in the dashboard?

Each file operation generates a separate FIM alert. The creation event shows the new file's checksum and attributes. The modification event shows both the old and new checksum values so you can confirm something changed. The deletion event confirms the file was removed.

These are the same types of alerts a SOC analyst would investigate if an attacker modified a system file like the Windows hosts file to redirect DNS traffic.

Not seeing FIM alerts?

Check that the agent shows as Active in the Wazuh dashboard. If it shows Disconnected, the configuration push may have caused a restart issue.

Verify the agent received the FIM config by checking C:\Program Files (x86)\ossec-agent\shared\merged.mg on Windows. This file should contain the syscheck directories you configured.

If FIM events still do not appear, restart the Windows agent with NET STOP WazuhSvc && NET START WazuhSvc and wait 30 seconds before creating the test file.

Help me debug why FIM alerts are not appearing in my Wazuh dashboard

Verify real-time detection

The realtime="yes" attribute uses continuous file system monitoring instead of periodic scans. Without real-time monitoring, the default FIM scan cycle runs every 12 hours. That gap would give an attacker plenty of time to modify files and cover their tracks.

  • Create another test file on your Windows machine and immediately check the Wazuh dashboard:
echo "realtime test" > C:\Users\Public\realtime-check.txt
  • Switch to the Wazuh dashboard and refresh the File Integrity Monitoring module.
  • You should see the new file event appear within seconds, not minutes.
  • Delete the test file to clean up:
del C:\Users\Public\realtime-check.txt

Why does real-time monitoring matter?

In a real intrusion, an attacker might modify C:\Windows\System32\drivers\etc\hosts to redirect internal DNS, or tamper with registry hives in C:\Windows\System32\config to maintain persistence. A 12-hour scan gap means you would not know until long after the damage is done.

Real-time FIM gives you near-instant visibility into file changes on critical paths. This is essential for detecting live intrusions where every second counts.

Your FIM is now actively watching critical Windows directories for unauthorized changes. Next up, you will validate your entire detection pipeline by simulating real attacks with Atomic Red Team.

Validate Detections with Atomic Red Team

In the previous step, you configured File Integrity Monitoring to detect unauthorized changes to sensitive directories in real time. Your detection pipeline now covers process creation, PowerShell activity, and file modifications.

Writing rules is only half the job. How do you know those rules actually fire when a real technique is used? You need a way to simulate attacks in a controlled, repeatable manner. Atomic Red Team is a framework of small, self-contained test scripts, each mapped to a specific MITRE ATT&CK technique. In this step, you will install the framework, execute attack simulations, and confirm your custom rules fire correctly.

In this step, get ready to:
  • Install the Atomic Red Team framework on your Windows machine.
  • Run attack simulations targeting your custom detection rules.
  • Triage the resulting alerts in the Wazuh dashboard to confirm true positive detections.
Install Atomic Red Team

Atomic Red Team provides a library of small test scripts mapped to MITRE ATT&CK techniques. Each test simulates one specific adversary behavior with a minimal, safe payload.

  • On your Windows machine, open PowerShell as Administrator.
  • Windows Defender may quarantine Atomic Red Team files during installation. Temporarily disable real-time protection by opening Windows Security, selecting Virus & threat protection, clicking Manage settings, and turning off Real-time protection.
  • Set the execution policy to allow the install script by running:
Set-ExecutionPolicy Bypass -Scope Process
  • Install the Atomic Red Team framework and its atomics library by running these commands:
IEX (IWR 'https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/install-atomicredteam.ps1' -UseBasicParsing)
Install-AtomicRedTeam -getAtomics

What do these commands do?

The first line downloads the Atomic Red Team installer script from GitHub and runs it in the current session. The second line installs the execution framework and the full atomics folder containing all test definitions to C:\AtomicRedTeam.

The -getAtomics flag tells the installer to download the test definitions alongside the framework. Without it, you would only have the execution engine and no tests to run.

  • Wait for the installation to complete. You should see a message saying the installation is complete and you can now use the Invoke-AtomicTest function.

Seeing an execution policy or script-blocked error?

If you see a message about scripts being disabled on this system, close PowerShell and reopen it using powershell -exec bypass. Then re-run the install commands.

If you see a TLS/SSL error, run the following before the install commands:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

If Windows Defender quarantines files during installation, ensure real-time protection is off, then retry with the -Force flag: Install-AtomicRedTeam -getAtomics -Force.

Help me troubleshoot Atomic Red Team installation errors on Windows

Run attack simulations

Now you will execute atomic tests that match your custom detection rules. Each test simulates one specific MITRE ATT&CK technique with a minimal, safe payload.

  • In the same Administrator PowerShell session, simulate encoded PowerShell execution (T1059.001) by running:
Invoke-AtomicTest T1059.001

What does this test simulate?

T1059.001 covers Command and Scripting Interpreter: PowerShell. The atomic tests for this technique include encoded command execution, fileless script execution, and obfuscated PowerShell payloads. These are the exact behaviors your custom rule 100001 is designed to detect.

Some tests within T1059.001 may prompt for confirmation or attempt to reach external URLs. Allow them to run. They are safe, self-contained simulations.

  • Next, simulate system discovery techniques (T1033) by running:
Invoke-AtomicTest T1033

What does T1033 test?

T1033 is System Owner/User Discovery. Attackers run commands like whoami and query user to identify who is logged in and what accounts have access. Built-in Wazuh rules detect this reconnaissance activity alongside your custom rules.

  • Both tests should execute multiple sub-tests and print output for each. You will see the atomics folder path printed at the top, followed by test execution details for each numbered test.

Tests failing or command not recognized?

If Invoke-AtomicTest is not recognized, the module did not import. Re-import it manually by running:

Import-Module "C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1" -Force

If individual tests fail with prerequisite errors, that is expected for some tests. The key tests that trigger encoded PowerShell commands will still generate the Sysmon and PowerShell telemetry your rules detect.

Help me troubleshoot Invoke-AtomicTest commands not working

Triage alerts in the dashboard

This is the core SOC analyst workflow. An event comes in, you triage it, determine whether it is a true positive, and document your findings.

  • Switch back to your Wazuh dashboard in the browser.
  • Click Security events in the left sidebar to view recent alerts.
  • Look for alerts generated in the last few minutes. You should see alerts from your custom rule 100001 (encoded PowerShell command detected) triggered by the T1059.001 simulation.
  • Check the MITRE ATT&CK column. Your custom rules should display their mapped technique IDs (T1059.001).
  • Look for built-in Wazuh rules that also triggered. The T1033 simulation generates system discovery commands that match Wazuh's default detection rules.
  • Click on any alert to expand its details. Review the full event data including the agent name, the command line that triggered it, the rule description, and the severity level.

What should I look for when triaging?

For each alert, check three things. First, does the rule description match what actually happened? Your rule 100001 should fire on encoded PowerShell commands from the atomic test. Second, is the severity level appropriate? Level 12 and 14 alerts indicate high-confidence detections. Third, does the MITRE ATT&CK mapping help you understand the attacker's goal?

Since you ran these tests yourself, every alert is a confirmed true positive. In a real SOC, this same workflow helps you distinguish between true positives (real attacks), false positives (benign activity triggering rules), and tuning opportunities (rules that need adjustment).

  • Confirm that your custom rule 100001 fired on the T1059.001 simulation by finding at least one alert with rule ID 100001 in the alert list.

Not seeing alerts from your custom rules?

Alerts may take 1-2 minutes to appear in the dashboard after the tests run. Refresh the page and check the time filter is set to the last 15 minutes or last hour.

If built-in rules triggered but your custom rules did not, SSH into your Wazuh server and check for syntax errors in your rules file by running:

sudo /var/ossec/bin/wazuh-logtest

This tool lets you paste a raw log event and see which rules match. Verify that your rules in /var/ossec/etc/rules/local_rules.xml have no XML syntax errors.

Help me figure out why my custom Wazuh rules are not firing

Secret mission

Configure Active Response

Your SIEM can detect threats, but can it fight back? In this secret mission, you will configure Wazuh Active Response to automatically block an IP address after repeated failed SSH login attempts. This is the difference between a passive monitoring tool and an active defense system.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely on local virtual machines, so there are no ongoing financial costs.

Resources you used:

  • Ubuntu 22.04 Server VM running the Wazuh stack (uses approximately 8 GB RAM and 50 GB disk while active).
  • Wazuh agent running as a Windows service.
  • Sysmon v15.2 running as a Windows service.
  • Atomic Red Team files installed at C:\AtomicRedTeam.
  • PowerShell Script Block Logging enabled via Group Policy.

Keep everything running

No action needed. Choose this if you are still actively building on your SOC lab or want to continue monitoring your Windows endpoint.

  • Leave the Ubuntu VM running in VirtualBox for ongoing detection practice.
  • The Wazuh agent and Sysmon continue generating telemetry in the background. They use minimal Windows resources.
  • Your custom detection rules, FIM configuration, and Active Response settings remain active and ready.

Pause - I'll come back to this later

Shut down the Ubuntu VM to free up system resources on your host machine. Your configuration is preserved on disk and will resume when you start the VM again.

  • In VirtualBox, right-click your Ubuntu VM and select Close, then select Save State to preserve memory, or Power Off to shut down completely.
  • On Windows, stop the Wazuh agent service by opening an Administrator Command Prompt and running:
NET STOP WazuhSvc
  • The Wazuh agent reconnects automatically when you restart the Ubuntu VM and run NET START WazuhSvc on Windows.

Delete - I don't want to use this again

Remove all project resources and start fresh. This reclaims all disk space and removes services from your Windows machine.

  • In VirtualBox, right-click your Ubuntu VM, select Remove, then choose Delete all files to reclaim the 50 GB of disk space.
  • On Windows, uninstall the Wazuh agent by opening Settings, selecting Apps, then Apps & features. Find the Wazuh Agent entry and click Uninstall.
  • Uninstall Sysmon by opening an Administrator Command Prompt and running:
sysmon64 -u
  • Remove the Atomic Red Team files by opening an Administrator PowerShell prompt and running:
Remove-Item -Recurse -Force C:\AtomicRedTeam
  • Disable PowerShell Script Block Logging by opening Group Policy Editor (gpedit.msc).
  • Navigate to Computer Configuration, then Administrative Templates, then Windows Components, then Windows PowerShell.
  • Set Turn on PowerShell Script Block Logging to Not Configured.

Nice Work!

Nice Work!

You just built a production-grade home Security Operations Center with custom detection engineering. This goes beyond installing a SIEM. You engineered detections, automated responses, and validated everything with standardized attack simulations.

You learned how to:

  • Deploy a full Wazuh SIEM/XDR stack and connect a Windows endpoint with Sysmon telemetry and PowerShell Script Block Logging flowing into the indexer.
  • Write custom detection rules mapped to specific MITRE ATT&CK techniques (T1059.001, T1003.001, T1566.001) and configure File Integrity Monitoring for real-time change detection on sensitive directories.
  • Validate your detections using Atomic Red Team attack simulations and perform alert triage in the dashboard like a real SOC analyst.
  • Configure Active Response to automatically block brute force attackers using the firewall-drop command with automatic unblocking after a timeout period.

Ready to quiz yourself?