Build a MITRE ATT&CK Rule Library
Engineer custom Wazuh detection rules mapped to MITRE ATT&CK techniques.
Introduction
30 Second Summary
Every major breach shares a pattern. The attacker was inside the network for days or weeks before anyone noticed, because default security tools leave blind spots that sophisticated techniques exploit.
In this project, you will write a custom detection rule library that catches four distinct attack techniques across the MITRE ATT&CK framework. You'll simulate each attack safely on your own machine and validate that your rules fire correctly in the Wazuh dashboard.
What You'll Build
A detection rule library file deployed inside your Wazuh manager that identifies credential dumping, registry persistence, lateral movement, and data exfiltration staging.
By the end of this project, you'll have:
- A detection_library.xml file containing 4 custom detection rules mapped to specific MITRE ATT&CK technique IDs.
- Validated alerts for each technique, confirmed end-to-end by simulating attacks and checking the Wazuh dashboard.
- Understanding of which Sysmon Event IDs power each detection and where built-in rules leave blind spots that your custom rules fill.
- Secret Mission: a critical-severity rule detecting event log clearing as a defense evasion indicator.
Are there any prerequisites?
This is Project 2 in the SOC lab series. You need a running Wazuh stack from Project 1 (Build a Home SOC Lab with Wazuh SIEM) with Docker containers active, Sysmon installed, and a Wazuh agent enrolled and reporting.
Before We Start
Your Wazuh lab from Project 1 is the foundation for this entire project. Before writing any detection rules, you need to confirm the stack is healthy and your agent is actively reporting events.
You will also download a tool called PsExec for simulating lateral movement, and create the rule file where your entire detection library will live.
In this step, get ready to:
- Confirm your Wazuh stack and agent are running and receiving Sysmon events.
- Download and set up PsExec for lateral movement simulation.
- Create the detection library file inside the Wazuh manager container.
Start your Docker containers and verify the stack
If you paused your containers after Project 1, you need to bring them back up. If they are already running, the start command safely does nothing.
- Open PowerShell by pressing the Windows key, typing PowerShell, and pressing Enter.
- Navigate to your Wazuh Docker directory and start the containers by running these commands:
cd ~/Desktop/wazuh-docker/single-node
docker compose start
- Verify all three containers are running by running:
docker ps
You should see three containers listed with status Up: the Wazuh manager, indexer, and dashboard.
What if I see fewer than three containers?
If containers are missing, run docker compose up -d instead. This recreates any containers that were removed since Project 1.
- Open the Wazuh dashboard in your browser at https://localhost:443.
- Log in with your admin credentials from Project 1.
- Click Agents in the left sidebar.
- Confirm your Windows agent shows Active status (green dot).
Agent showing Disconnected?
Open Services on your Windows host (press the Windows key and type Services). Find Wazuh in the list, right-click it, and select Start. Wait 30 seconds and refresh the dashboard.
help me troubleshoot why my Wazuh agent is disconnected after restarting Docker containers
- Verify Sysmon events are flowing by clicking Threat Hunting in the left sidebar.
- You should see recent events listed with sysmon in the data source column.
Give events a minute to flow
If Threat Hunting shows no events immediately after starting containers, wait 60 seconds and refresh. The agent needs time to reconnect and push buffered events.
Download and set up PsExec
PsExec is a legitimate Microsoft tool for remote process execution. Attackers frequently abuse it for lateral movement, which makes it a perfect candidate for detection.
- Open your browser and navigate to the PsExec download page.
- Click Download PsTools to download the ZIP file containing the full PsTools suite.
- Create the C:\Tools directory and extract PsExec64.exe from the ZIP into it.
Why C:\Tools?
Placing security tools in a dedicated folder like C:\Tools keeps your lab organized and makes cleanup straightforward. You only need PsExec64.exe from the ZIP. You can ignore the other utilities.
- Accept the PsExec EULA by running this command in your admin PowerShell:
C:\Tools\psexec64.exe -accepteula
What does this command do?
The -accepteula flag suppresses the Sysinternals license dialog that appears on first run. Without it, PsExec would pause and wait for you to click through the EULA window, which would break scripted usage later.
You should see the PsExec version banner followed by its usage syntax. This confirms the tool is working.
Seeing 'not recognized' or 'cannot find path'?
Double-check that PsExec64.exe is actually inside C:\Tools. Run dir C:\Tools to confirm. If the file is in a subfolder (like C:\Tools\PSTools\), move it up one level.
help me fix PsExec64.exe not being found at C:\Tools
Create the detection library file
Wazuh supports custom rules in any .xml file under /var/ossec/etc/rules/ on the manager. You will create a dedicated file called detection_library.xml to house all your rules, separate from the local_rules.xml you used in Project 1.
Why a separate file?
In production environments, detection engineers organize rules into purpose-specific files. This keeps your Project 1 rules intact and makes your detection library portable.
- Open a shell inside the Wazuh manager container by running:
docker exec -it single-node-wazuh.manager-1 bash
Your prompt changes to a root shell inside the container.
- Create the detection library file with the group wrapper by running:
cat > /var/ossec/etc/rules/detection_library.xml << 'EOF'
<group name="detection_library,windows,">
</group>
EOF
What does this code do?
The <group> wrapper tells Wazuh that all rules inside this file belong to the detection_library and windows categories. Every rule you write in the upcoming steps goes between these opening and closing tags.
- Verify the file was created correctly by running:
cat /var/ossec/etc/rules/detection_library.xml
You should see the group wrapper with nothing inside it yet.
Seeing 'No such file or directory'?
Make sure you are inside the manager container (your prompt should show root@ followed by the container ID). If you are still in your Windows PowerShell, run the docker exec command from the previous bullet first.
help me create detection_library.xml inside the Wazuh manager container
✔️ Awesome, I've got everything!
Great. Make sure you stay inside the manager container shell. You will use it again in the next step to write your first detection rule.
ⓧ I'd like to double check the full code
Here is what detection_library.xml should look like at this point:
<group name="detection_library,windows,">
</group>
Your lab is verified and your rule file is ready. Next up, you will write your first detection rule to catch credential dumping attempts.
Detect Credential Dumping via comsvcs.dll
Your lab is verified and your empty detection library file is in place inside the Wazuh manager container.
Time to write your first real detection rule. Credential dumping is one of the first things an attacker does after gaining initial access. They want passwords and hashes stored in memory so they can move laterally across your network.
In this step, get ready to:
- Write a detection rule targeting credential dumping via comsvcs.dll MiniDump (T1003.001).
- Simulate the attack safely on your Windows host.
- Validate the alert fires with correct MITRE ATT&CK mapping in the Wazuh dashboard.
Write the credential dumping detection rule
Attackers frequently use a technique called a LOLBin (Living Off the Land Binary) to steal credentials without downloading any malware.
The Windows DLL comsvcs.dll is legitimately signed by Microsoft, but it contains a MiniDump function that can dump process memory. Attackers abuse this to dump LSASS (the process that stores login credentials in memory).
- In the manager container shell from earlier, update detection_library.xml with your first detection rule by running this command:
cat > /var/ossec/etc/rules/detection_library.xml << 'EOF'
<group name="detection_library,windows,">
<!-- Rule: Credential Dumping via comsvcs.dll MiniDump (T1003.001) -->
<rule id="100200" level="12">
<if_sid>92000</if_sid>
<field name="win.eventdata.commandLine" type="pcre2">(?i)comsvcs.*MiniDump</field>
<description>Credential dumping attempt via comsvcs.dll MiniDump on $(win.system.computer).</description>
<mitre>
<id>T1003.001</id>
</mitre>
</rule>
</group>
EOF
What does this rule do?
- <if_sid>92000</if_sid> chains this rule off the parent Sysmon EID 1 (Process Creation) rule. Your rule only evaluates when a process creation event arrives.
- The pcre2 field match uses (?i) for case-insensitive matching, catching variations like COMSVCS or Minidump.
- Level 12 means high severity, demanding immediate attention from a SOC analyst.
- The <mitre> block maps the alert to MITRE ATT&CK technique T1003.001 (OS Credential Dumping: LSASS Memory), making it searchable in the framework view.
- Restart the Wazuh manager to load the new rule by running:
systemctl restart wazuh-manager
- If the command completes with no error output, the rule loaded successfully.
Seeing a configuration error?
If you see an error about invalid XML or a duplicate rule ID, check that your XML tags are properly closed and that rule ID 100200 does not conflict with any existing rule.
Make sure the <group> opening and closing tags wrap the entire rule.
Help me fix a Wazuh rule XML configuration error.
✔️ Awesome, I've got everything!
Great. Double check you see no errors after the restart, then move on to simulating the attack.
ⓧ I'd like to double check the full code
<group name="detection_library,windows,">
<!-- Rule: Credential Dumping via comsvcs.dll MiniDump (T1003.001) -->
<rule id="100200" level="12">
<if_sid>92000</if_sid>
<field name="win.eventdata.commandLine" type="pcre2">(?i)comsvcs.*MiniDump</field>
<description>Credential dumping attempt via comsvcs.dll MiniDump on $(win.system.computer).</description>
<mitre>
<id>T1003.001</id>
</mitre>
</rule>
</group>
Simulate the credential dumping attempt
Now you need to trigger the rule by simulating what an attacker would actually do. You will use the same rundll32.exe command that real attackers use to call comsvcs.dll's MiniDump function against the LSASS process.
On modern Windows with Protected Process Light (PPL) enabled, the dump will fail. Sysmon captures the process creation and full command line before the access attempt fails. Your rule detects the attempt, not just successful execution.
- Switch to an Administrator PowerShell window on your Windows host.
- Get the LSASS process ID and run the credential dumping simulation by running:
# Get the LSASS process ID
$lsass_pid = (Get-Process lsass).Id
# Simulate credential dump using comsvcs.dll MiniDump
# This will likely fail due to PPL, but Sysmon captures the command line
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump $lsass_pid $env:TEMP\lsass.dmp full
What happens here?
The first line retrieves the process ID of lsass.exe (Local Security Authority Subsystem Service). The second line calls rundll32.exe to invoke the MiniDump export function inside comsvcs.dll.
Even though the dump fails on protected systems, Sysmon logs the process creation event (EID 1) with the full command line. Your Wazuh rule then matches on that command line pattern and fires the alert.
- You will likely see an access denied error or no output file created. This is expected and correct.
Getting an access denied error?
Make sure you are running PowerShell as Administrator. The Get-Process lsass command requires elevated privileges to access system process details.
If the command runs but you see no dump file, that is the expected behavior on modern Windows. The important thing is that the command executed and Sysmon logged it.
Help me troubleshoot the credential dumping simulation in PowerShell.
Validate the alert in the Wazuh dashboard
The simulation fired a Sysmon process creation event that your Wazuh agent forwarded to the manager. Your new rule should have matched and generated an alert.
- Switch to the Wazuh dashboard in your browser.
- Navigate to the Threat Hunting module.
- In the search bar, filter for rule ID 100200 by entering rule.id:100200 and pressing Enter.
- Click on the alert entry to expand the full event data.
What should I see?
The alert should display rule ID 100200 with severity level 12. The MITRE ATT&CK technique field should show T1003.001.
In the expanded event data, look at the win.eventdata.commandLine field. You should see the full rundll32.exe command with comsvcs.dll and MiniDump captured exactly as you typed it.
Alert not showing up?
Alerts can take 30-60 seconds to appear. Refresh the Threat Hunting page and try the filter again.
If the alert still does not appear, switch back to the manager container shell and verify the manager restarted cleanly. Also confirm your agent still shows Active in the dashboard.
Help me figure out why my credential dumping alert is not appearing in Wazuh.
Your first detection rule is live and validated. Next up, you will write a rule that catches one of the most common persistence mechanisms attackers use to survive reboots.
Detect Registry Persistence via Run Keys
Your credential dumping rule is live and validated. Now you will tackle one of the most common persistence techniques attackers use to survive a reboot.
Windows Registry Run keys tell the operating system which programs to launch automatically when a user logs in. Attackers abuse these keys to maintain access to a compromised machine. In this step, you will write a detection rule that catches this behavior and fills a real gap in Wazuh's built-in coverage.
In this step, get ready to:
- Write a detection rule for registry Run key modifications (T1547.001).
- Simulate registry persistence using a safe test entry.
- Validate the alert in your Wazuh dashboard with MITRE mapping.
Write the registry persistence detection rule
Attackers add entries to HKCU\Software\Microsoft\Windows\CurrentVersion\Run so their malware launches every time the user logs in. This path does not require administrator privileges, making it a low-effort persistence mechanism.
Why write a custom rule for this?
Wazuh's built-in rule 92012 is tagged for MITRE ATT&CK technique T1547.001, but it only monitors service registry paths under HKLM\System\CurrentControlSet\Services\*. It does NOT watch the CurrentVersion\Run keys where most user-level persistence actually lives.
Your custom rule fills this blind spot by triggering on any value written to a Run key path.
- Return to your shell inside the Wazuh manager container. If you closed it, reopen it by running:
- Open detection_library.xml for editing. Find the closing </group> tag at the bottom of the file.
- Add rule 100201 directly above the </group> closing tag by pasting the following code:
docker exec -it single-node-wazuh.manager-1 bash
<!-- Rule: Registry Persistence via Run Key (T1547.001) -->
<rule id="100201" level="10">
<if_sid>61615</if_sid>
<field name="win.eventdata.targetObject" type="pcre2">(?i)CurrentVersion\\\\Run</field>
<field name="win.eventdata.eventType" type="pcre2">^SetValue$</field>
<description>Registry Run key persistence detected on $(win.system.computer).</description>
<mitre>
<id>T1547.001</id>
</mitre>
</rule>
What does this rule do?
- if_sid 61615 chains off the parent rule for Sysmon Event ID 13 (Registry Value Set). The rule only evaluates events that Sysmon reports as registry writes.
- The targetObject field uses a case-insensitive regex (?i) to match any registry path containing CurrentVersion\Run. This catches both HKLM and HKCU variants.
- The eventType match ensures only SetValue operations (writes) trigger the rule, not reads or deletes.
- Level 10 is a medium-high severity. Legitimate software sometimes writes to Run keys, so this is lower than the credential dumping rule.
- The four backslashes \\\\ in the XML represent a single literal backslash in the matched path. XML removes one escape level, then pcre2 removes another.
- Save the file and restart the Wazuh manager to load the new rule by running:
systemctl restart wazuh-manager
- Wait a few seconds, then confirm the manager restarted without errors. If the command completes silently, the rules loaded successfully.
Seeing a configuration error on restart?
- Check that your rule XML is well-formed. A missing closing tag like </rule> or </field> will cause a parse failure.
- Verify the backslashes in the targetObject field. You need exactly four backslashes (\\\\) between CurrentVersion and Run.
- Make sure the new rule sits inside the <group> wrapper, above </group>.
Help me debug a Wazuh rule configuration error after adding my registry persistence rule.
✔️ Awesome, I've got everything!
Great. Double check you saved the file before restarting the manager.
ⓧ I'd like to double check the full code
<group name="detection_library,windows,">
<!-- Rule: Credential Dumping via comsvcs.dll MiniDump (T1003.001) -->
<rule id="100200" level="12">
<if_sid>92000</if_sid>
<field name="win.eventdata.commandLine" type="pcre2">(?i)comsvcs.*MiniDump</field>
<description>Credential dumping attempt via comsvcs.dll MiniDump on $(win.system.computer).</description>
<mitre>
<id>T1003.001</id>
</mitre>
</rule>
<!-- Rule: Registry Persistence via Run Key (T1547.001) -->
<rule id="100201" level="10">
<if_sid>61615</if_sid>
<field name="win.eventdata.targetObject" type="pcre2">(?i)CurrentVersion\\\\Run</field>
<field name="win.eventdata.eventType" type="pcre2">^SetValue$</field>
<description>Registry Run key persistence detected on $(win.system.computer).</description>
<mitre>
<id>T1547.001</id>
</mitre>
</rule>
</group>
Simulate registry persistence on your Windows host
To trigger the rule, you will create a fake Run key entry pointing to a non-existent executable. This simulates exactly what an attacker would do to persist on a compromised machine.
- Switch to PowerShell on your Windows host.
- Create a fake persistence entry in the Run key by running:
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v TestPersistence /t REG_SZ /d "C:\Temp\fake_malware.exe" /f
What does this command do?
- reg add writes a new value to the Windows Registry.
- /v TestPersistence sets the value name. In real attacks, this would be disguised as a legitimate program name.
- /d "C:\Temp\fake_malware.exe" is the executable path. This file does not exist, so nothing actually runs at login.
- /f forces the write without a confirmation prompt.
Sysmon captures this registry write as Event ID 13, which flows to Wazuh and triggers your rule.
- Immediately clean up the test entry by running:
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v TestPersistence /f
- Confirm the cleanup succeeded. The command should output The operation completed successfully. indicating the value was removed.
Getting an access denied error?
The HKCU Run key does not require administrator privileges. If you see access denied, make sure you are writing to HKCU (current user) and not HKLM (local machine, which requires elevation).
Help me troubleshoot a registry access denied error when simulating Run key persistence.
Validate the alert in your Wazuh dashboard
Your simulation created a registry write that Sysmon captured and forwarded to Wazuh. Now you will confirm the alert fired correctly.
- Switch to your browser and open the Wazuh dashboard.
- Navigate to the Threat Hunting module.
- In the search bar, filter for rule.id: 100201 to find your alert.
- Click on the alert to expand the full event data.
You should see an alert showing MITRE technique T1547.001 and severity level 10. The event data contains the full registry path and the value that was written.
Why does the registry path look different?
Sysmon logs registry paths using kernel-level hive names. Instead of the familiar HKCU abbreviation, you will see something like HKU\S-1-5-21-...\Software\Microsoft\Windows\CurrentVersion\Run. This is the same key, just referenced by the user's SID instead of the shorthand.
Your rule's regex pattern CurrentVersion\\Run catches both formats because it matches on the path segment, not the hive prefix.
Not seeing rule 100201 in the dashboard?
- Allow 1-2 minutes for the event to flow from Sysmon through the Wazuh agent to the manager and into the indexer.
- Verify you restarted the Wazuh manager after adding the rule. Without a restart, new rules are not loaded.
- Check your time filter in the dashboard. Set it to the last 15 minutes to avoid missing recent events.
Help me troubleshoot why my registry persistence rule 100201 is not producing alerts in the Wazuh dashboard.
Your detection library now covers two distinct attack techniques. Next up, you will detect lateral movement by catching PsExec service creation on the local machine.
Detect Lateral Movement via PsExec Service Creation
Your detection library now catches credential theft and persistence. The next link in the attack chain is lateral movement. Once an attacker has credentials and a foothold, they move sideways to other machines on the network.
PsExec is one of the most popular tools for lateral movement. When PsExec runs against a target, it installs a temporary Windows service named PSEXESVC via the Service Control Manager. This service creation leaves a registry trace that Sysmon Event ID 13 captures.
In this step, get ready to:
- Write a detection rule for PsExec service creation mapped to MITRE T1543.003.
- Simulate lateral movement by running PsExec against localhost.
- Validate the alert fires with the correct MITRE mapping and severity.
Write the PsExec service detection rule
PsExec creates a registry key under Services\PSEXESVC when it installs its temporary service. Your rule will watch for this specific registry path being written by the SYSTEM account.
- Switch back to your shell inside the Wazuh manager container.
- Open detection_library.xml for editing by running:
nano /var/ossec/etc/rules/detection_library.xml
- Find the closing </group> tag at the bottom of the file.
- Add the following rule directly above </group>:
<!-- Rule: PsExec Service Creation - Lateral Movement (T1543.003) -->
<rule id="100202" level="12">
<if_sid>61615</if_sid>
<field name="win.eventdata.targetObject" type="pcre2">(?i)Services\\\\PSEXESVC</field>
<field name="win.eventdata.eventType" type="pcre2">^SetValue$</field>
<field name="win.eventdata.user" type="pcre2">(?i)NT AUTHORITY\\SYSTEM</field>
<description>PsExec service creation detected on $(win.system.computer). Possible lateral movement.</description>
<mitre>
<id>T1543.003</id>
</mitre>
</rule>
What does this rule do?
This rule chains off parent SID 61615 (Sysmon Event ID 13, Registry Value Set). It fires when three conditions are all true simultaneously.
- targetObject contains Services\\PSEXESVC. This catches the specific registry key PsExec creates for its temporary service.
- eventType matches SetValue. This confirms a value is being written, not just a key being opened.
- user matches NT AUTHORITY\SYSTEM. The Windows Service Control Manager runs as SYSTEM when creating service entries.
Severity level 12 reflects the high risk of lateral movement. The MITRE ATT&CK mapping to T1543.003 (Create or Modify System Process: Windows Service) tags this alert correctly in the framework.
- Save the file and exit nano (Ctrl+O, Enter, Ctrl+X).
- Restart the Wazuh manager to load the new rule by running:
systemctl restart wazuh-manager
- Wait about 10 seconds for the manager to reload. You should see no error output.
Seeing a configuration error?
If the restart fails, check for XML syntax issues. The most common mistake is incorrect backslash escaping. The pattern needs four literal backslash characters (\\\\) in the XML because both the XML parser and the pcre2 engine each consume one level of escaping.
Also verify the rule sits inside the <group> wrapper and before the closing </group> tag.
Help me fix my Wazuh rule XML syntax error.
Simulate PsExec lateral movement
Running PsExec against localhost creates the same PSEXESVC service registration that a real remote execution would. This is a safe way to trigger the detection without needing a second machine.
- Switch to your administrator PowerShell window on the Windows host.
- Run PsExec against localhost to trigger the service creation:
C:\Tools\psexec64.exe \\localhost cmd /c "echo Lateral Movement Test"
What happens when you run this?
PsExec connects to your own machine via SMB, pushes the PSEXESVC executable, and registers it as a Windows service through the Service Control Manager. The service runs your command (echo Lateral Movement Test), then PsExec removes the service.
The entire lifecycle happens in seconds. Sysmon captures the registry write (Event ID 13) the moment the service key is created. Your rule fires on that registry event, not on the command output.
- You should see output ending with Lateral Movement Test followed by a success message from PsExec.
PsExec showing an access denied error?
Make sure you are running PowerShell as Administrator. PsExec needs admin privileges to create services.
If you see a EULA prompt instead of execution, run C:\Tools\psexec64.exe -accepteula first, then retry the command above.
Help me troubleshoot PsExec access denied errors on localhost.
Validate the alert in the Wazuh dashboard
- Return to the Wazuh dashboard in your browser.
- Navigate to the Threat Hunting module.
- In the search bar, filter for rule.id: 100202 and press Enter.
- Click on the alert entry to expand its details.
You should see an alert showing MITRE technique T1543.003, severity level 12, and the PSEXESVC registry path in the event data.
- Examine the win.eventdata.targetObject field. You will see the full registry path to the PSEXESVC service key.
- Check the win.eventdata.user field. It should show NT AUTHORITY\SYSTEM because services.exe (the Windows Service Control Manager) creates service registry entries under the SYSTEM account.
Why does services.exe appear in the event data?
Even though PsExec initiated the action, the actual registry write is performed by services.exe. This is the Windows Service Control Manager process. When PsExec asks Windows to install a service, services.exe handles the registry key creation.
This is why the user field shows SYSTEM rather than your admin account. The detection rule accounts for this by explicitly matching NT AUTHORITY\SYSTEM.
No alert showing for rule 100202?
Wait 30-60 seconds after running the PsExec command. Sysmon events take a moment to reach the Wazuh manager through the agent.
If the alert still does not appear, verify the manager restarted successfully by running systemctl status wazuh-manager inside the container. Look for "active (running)" in the output.
Help me figure out why my PsExec detection rule is not firing.
✔️ Awesome, I've got everything!
Great. Double check you see rule ID 100202 with MITRE T1543.003 and the PSEXESVC path in the event data.
ⓧ I'd like to double check the full code
Here is the complete detection_library.xml at this point:
<group name="detection_library,windows,">
<!-- Rule: Credential Dumping via comsvcs.dll MiniDump (T1003.001) -->
<rule id="100200" level="12">
<if_sid>92000</if_sid>
<field name="win.eventdata.commandLine" type="pcre2">(?i)comsvcs.*MiniDump</field>
<description>Credential dumping attempt via comsvcs.dll MiniDump on $(win.system.computer).</description>
<mitre>
<id>T1003.001</id>
</mitre>
</rule>
<!-- Rule: Registry Persistence via Run Key (T1547.001) -->
<rule id="100201" level="10">
<if_sid>61615</if_sid>
<field name="win.eventdata.targetObject" type="pcre2">(?i)CurrentVersion\\\\Run</field>
<field name="win.eventdata.eventType" type="pcre2">^SetValue$</field>
<description>Registry Run key persistence detected on $(win.system.computer).</description>
<mitre>
<id>T1547.001</id>
</mitre>
</rule>
<!-- Rule: PsExec Service Creation - Lateral Movement (T1543.003) -->
<rule id="100202" level="12">
<if_sid>61615</if_sid>
<field name="win.eventdata.targetObject" type="pcre2">(?i)Services\\\\PSEXESVC</field>
<field name="win.eventdata.eventType" type="pcre2">^SetValue$</field>
<field name="win.eventdata.user" type="pcre2">(?i)NT AUTHORITY\\\\SYSTEM</field>
<description>PsExec service creation detected on $(win.system.computer). Possible lateral movement.</description>
<mitre>
<id>T1543.003</id>
</mitre>
</rule>
</group>
Your detection library now covers three attack techniques across credential access, persistence, and lateral movement. Next up, you will write a rule that catches attackers staging data for exfiltration.
Detect Data Exfiltration Staging
Your detection library now catches credential theft, persistence, and lateral movement. The last technique in a real attack chain is exfiltration. Before an attacker transfers stolen data out of a network, they need to stage it by bundling files into an archive.
Attackers commonly use PowerShell's Compress-Archive cmdlet to package sensitive files into a ZIP before transferring them out. This is detectable via Sysmon EID 1 (process creation) because the full command line is captured.
In this step, get ready to:
- Write a detection rule for data staging via Compress-Archive (T1560).
- Simulate data staging by archiving dummy test files with PowerShell.
- Validate the alert fires with MITRE T1560 mapping in the Wazuh dashboard.
Write rule 100203 for data staging detection
MITRE ATT&CK technique T1560 covers "Archive Collected Data." Your rule watches for the Compress-Archive cmdlet appearing in process creation command lines.
- Switch back to your shell inside the Wazuh manager container.
- Open detection_library.xml for editing by running:
nano /var/ossec/etc/rules/detection_library.xml
- Find the closing </group> tag at the bottom of the file.
- Add the following rule ABOVE the closing </group> tag:
<!-- Rule: Data Staging via Compress-Archive (T1560) -->
<rule id="100203" level="10">
<if_sid>92000</if_sid>
<field name="win.eventdata.commandLine" type="pcre2">(?i)Compress-Archive</field>
<description>Suspicious data archiving detected on $(win.system.computer). Possible exfiltration staging.</description>
<mitre>
<id>T1560</id>
</mitre>
</rule>
What does this rule do?
This rule chains off parent SID 92000 (Sysmon EID 1 process creation events). It fires whenever a process command line contains Compress-Archive in any capitalization, thanks to the (?i) case-insensitive flag.
Level 10 is appropriate here because archiving files is sometimes legitimate. In a production environment, you would add path-based exclusions for known backup scripts. In this lab, the rule demonstrates the detection principle clearly.
- Save the file in nano by pressing Ctrl+O, then Enter, then Ctrl+X to exit.
- Restart the Wazuh manager to load the new rule by running:
systemctl restart wazuh-manager
- You should see no error output. The manager restarts within a few seconds.
Seeing an error on restart?
If the manager fails to start, you likely have a syntax error in the XML. Check that your new rule sits inside the <group> tags, not after the closing </group>. Verify the rule ID is 100203 and all XML tags are properly closed.
help me debug my Wazuh detection rule XML syntax error
✔️ Awesome, I've got everything!
Great. Double check you saved the file and the manager restarted without errors.
ⓧ I'd like to double check the full code
Here is the complete detection_library.xml with all four rules:
<group name="detection_library,windows,">
<!-- Rule: Credential Dumping via comsvcs.dll MiniDump (T1003.001) -->
<rule id="100200" level="12">
<if_sid>92000</if_sid>
<field name="win.eventdata.commandLine" type="pcre2">(?i)comsvcs.*MiniDump</field>
<description>Credential dumping attempt via comsvcs.dll MiniDump on $(win.system.computer).</description>
<mitre>
<id>T1003.001</id>
</mitre>
</rule>
<!-- Rule: Registry Persistence via Run Key (T1547.001) -->
<rule id="100201" level="10">
<if_sid>61615</if_sid>
<field name="win.eventdata.targetObject" type="pcre2">(?i)CurrentVersion\\\\Run</field>
<field name="win.eventdata.eventType" type="pcre2">^SetValue$</field>
<description>Registry Run key persistence detected on $(win.system.computer).</description>
<mitre>
<id>T1547.001</id>
</mitre>
</rule>
<!-- Rule: PsExec Service Creation - Lateral Movement (T1543.003) -->
<rule id="100202" level="12">
<if_sid>61615</if_sid>
<field name="win.eventdata.targetObject" type="pcre2">(?i)Services\\\\PSEXESVC</field>
<field name="win.eventdata.eventType" type="pcre2">^SetValue$</field>
<field name="win.eventdata.user" type="pcre2">(?i)NT AUTHORITY\\\\SYSTEM</field>
<description>PsExec service creation detected on $(win.system.computer). Possible lateral movement.</description>
<mitre>
<id>T1543.003</id>
</mitre>
</rule>
<!-- Rule: Data Staging via Compress-Archive (T1560) -->
<rule id="100203" level="10">
<if_sid>92000</if_sid>
<field name="win.eventdata.commandLine" type="pcre2">(?i)Compress-Archive</field>
<description>Suspicious data archiving detected on $(win.system.computer). Possible exfiltration staging.</description>
<mitre>
<id>T1560</id>
</mitre>
</rule>
</group>
Simulate data staging on the Windows host
Real attackers collect sensitive documents and compress them before exfiltrating. You will simulate this by creating dummy files and archiving them with Compress-Archive.
- Switch to your Windows PowerShell (running as Administrator).
- Create a test directory with dummy files, compress them into a ZIP, then clean up by running these commands:
# Create test directory with dummy sensitive files
New-Item -ItemType Directory -Path C:\Temp\StagingTest -Force
"Confidential data file 1" | Out-File C:\Temp\StagingTest\secrets1.txt
"Confidential data file 2" | Out-File C:\Temp\StagingTest\secrets2.txt
"Confidential data file 3" | Out-File C:\Temp\StagingTest\secrets3.txt
# Stage the data into a ZIP archive (this triggers the detection)
Compress-Archive -Path C:\Temp\StagingTest\* -DestinationPath C:\Temp\exfil-staging.zip -Force
# Clean up test artifacts
Remove-Item -Recurse -Force C:\Temp\StagingTest
Remove-Item -Force C:\Temp\exfil-staging.zip
What does this simulation do?
This simulates an attacker who has collected sensitive files into a staging directory and then compresses them into a single ZIP for easy exfiltration. Sysmon captures the full Compress-Archive command line in the process creation event (EID 1), which triggers your rule.
The cleanup at the end removes the test files. The detection fires based on the process creation event, so the files do not need to persist for the alert to work.
- You should see no errors in the output. The directory and ZIP are created then immediately removed.
Getting an access denied error?
Make sure your PowerShell session is running as Administrator. Right-click the PowerShell icon and select Run as administrator if needed.
help me troubleshoot PowerShell access denied errors when creating test files
Validate the alert in the Wazuh dashboard
Your rule should have fired when the Compress-Archive command executed. Time to confirm it in the Wazuh dashboard.
- Return to the Wazuh dashboard in your browser.
- Navigate to Threat Hunting in the left sidebar.
- In the search bar, filter for rule ID 100203 by typing rule.id:100203 and pressing Enter.
- Confirm the alert appears with MITRE T1560 mapping displayed.
- Expand the event to examine the full event data. You should see the complete Compress-Archive command line, showing exactly what data was being staged.
Why is command line visibility so important?
When this alert fires in a real environment, the captured command line tells the analyst exactly which files the attacker was bundling. This transforms a generic "something was archived" alert into actionable intelligence about what data may be leaving the network.
Alert not showing up?
Wait 1-2 minutes for the event to flow from your Windows host through the Wazuh agent to the manager. Adjust the time range in the dashboard to the last 15 minutes using the time picker in the top right.
If the alert still does not appear, verify the manager restarted successfully. Run systemctl status wazuh-manager inside the container to confirm it shows active.
help me troubleshoot why my Wazuh rule 100203 alert is not appearing
Your detection library now covers the full attack lifecycle. You have rules for credential access, persistence, lateral movement, and exfiltration staging. Each one is mapped to a specific MITRE ATT&CK technique and validated end-to-end.
Secret mission
Detect Event Log Clearing (T1070.001)
Attackers frequently clear Windows event logs after completing their objectives to destroy forensic evidence. The wevtutil cl command is the most common method. Can you write a critical-severity detection rule that catches this defense evasion technique before the evidence disappears?
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 locally with no cloud services, so there are no ongoing costs. The Docker containers do consume approximately 4GB of RAM while running.
Resources you used:
- Docker containers (Wazuh manager, indexer, dashboard) consuming approximately 4GB RAM while running.
- PsExec64.exe downloaded to C:\Tools.
Keep everything running
No action needed. Choose this if you're still actively experimenting with your detection library or planning to add more rules.
- Your Docker containers will continue running and consuming RAM until you stop them.
- Your detection_library.xml file with all five rules lives inside the Wazuh manager container volume.
- PsExec64.exe remains at C:\Tools for future lateral movement testing.
Pause - I'll come back to this later
Shut down running containers to free up RAM. Your data and rules are preserved in the Docker volumes.
- Open a terminal and navigate to your wazuh-docker/single-node/ directory.
- Stop the containers by running:
docker compose stop
- When you're ready to resume, start them again by running:
docker compose start
- Your detection rules and all Wazuh data will be exactly where you left them.
Delete - I don't want to use this again
Remove all project resources completely. This destroys your detection library, all indexed alerts, and the Wazuh stack.
- Open a terminal and navigate to your wazuh-docker/single-node/ directory.
- Remove the containers and their volumes by running:
docker compose down -v
- Uninstall the Wazuh agent from Windows. Open Settings, select Apps, then Apps & features. Find Wazuh Agent and click Uninstall.
- Uninstall Sysmon by running this command in an admin PowerShell:
sysmon -u
- Delete PsExec by running:
Remove-Item C:\Tools\PsExec64.exe
- If the C:\Tools folder is now empty, remove it as well:
Remove-Item C:\Tools
Nice Work!
Nice Work!
Nice work. You just built a custom detection rule library that covers four distinct attack categories across the MITRE ATT&CK kill chain, deployed inside your own Wazuh SIEM.
Here's what you accomplished:
- Engineered 4 custom detection rules covering credential access (T1003.001), persistence (T1547.001), lateral movement (T1543.003), and exfiltration staging (T1560).
- Identified and filled a real blind spot in Wazuh's built-in ruleset where Run key persistence was undetected.
- Simulated each attack technique safely on your own Windows host and validated end-to-end detection in the Wazuh dashboard.
- Secret Mission: Detected defense evasion via event log clearing (T1070.001) with a critical-severity rule.
Ready to quiz yourself?