Building and Validating 28 Wazuh Rule Blocks
28 rule blocks across 24 XML files - authored for SOC triage patterns, bundled for deployment, and validated with reproducible commands from repo root.
Context
The Wazuh rules in this portfolio are not copies of community defaults. They target specific detection gaps identified during lab triage - RDP brute force patterns, PowerShell encoded command execution, suspicious scheduled task creation, and Windows process anomalies. Each rule was authored to generate actionable alerts that map directly to IR playbook decision points.
Problem
Default Wazuh rules produce high-volume, low-context alerts. Analyst fatigue is the predictable result. Without custom tuning, triage time increases because analysts must manually determine whether each alert is worth investigating. The goal was to build a rule set that pre-filters noise and surfaces events with enough context for immediate triage decisions.
Approach
- Identify detection gaps by reviewing alert volume during normal lab operation and noting which attack patterns produced no alerts.
- Author XML rules under
content/detection-rules/wazuh/rules/, each with a descriptivedescriptionfield and amitremapping where applicable. - Build deployment bundles with
scripts/build-wazuh-bundle.ps1to ensure rules are packaged consistently. - Count files and
<rule id=blocks separately - file count and rule block count diverge because some XML files contain multiple rules. - Run representative alert simulations (e.g., encoded PowerShell commands on the primary endpoint) and verify generated alerts appear in Wazuh dashboards.
Validation commands
# Build deployment bundle pwsh -File .\scripts\build-wazuh-bundle.ps1 # Count XML files (Get-ChildItem .\detection-rules\wazuh\rules -Filter *.xml).Count # Count rule blocks (not files) Select-String -Path .\detection-rules\wazuh\rules\*.xml ` -Pattern '<rule\s+id=' | Measure-Object | % Count # Full verification pwsh -NoProfile -File .\scripts\verify\verify-counts.ps1
Evidence
The rule source files, bundle script, and verification outputs are all in the public repo:
- Wazuh rules directory - 24 XML files
- Bundle build script
- VERIFIED_COUNTS.md - locked counts
- verify-counts.ps1 - run to reproduce
Lab screenshots of alert firing are available on request. Dashboard images are withheld to avoid exposing internal Wazuh indexer configuration.
Outcome
- 28 rule blocks active and verified against
VERIFIED_COUNTS.md. - Rule set covers: RDP brute force, encoded PowerShell, suspicious schtasks, process anomalies, and file integrity changes.
- Bundle script produces a deployable archive - no manual assembly required.
- Verification runs in under 10 seconds from repo root.
Lessons and next steps
- Synthetic event generators would enable regression testing without requiring a live lab endpoint.
- Splitting high-noise rules into tuning profiles per environment type (endpoint vs. server) would reduce alert fatigue further.
- A false-positive review matrix per rule family would give reviewers a quick trust signal.
- Adding automated log sample replay (similar to the detection harness) would close the validation loop.