What You'll Learn
- Read and interpret Wazuh rule XML definitions — understanding every element from
<rule>to<description> - Trace how a raw log event matches against rule conditions (fields, regex, frequency, timeframe)
- Understand the rule hierarchy: parent rules, child rules, and chained detections
- Analyze 5 rules from the pre-loaded alerts and explain what each detection logic actually checks
- Evaluate rule effectiveness: identify what a rule catches and what it misses
Lab Overview
| Detail | Value |
|---|---|
| Lab Profile | lab-wazuh |
| Containers | Wazuh Manager, Wazuh Indexer, Wazuh Dashboard |
| Estimated Time | 60–75 minutes |
| Difficulty | Intermediate |
| Browser Access | Wazuh Dashboard (Web UI) |
| Pre-Loaded Data | 505 alerts across 10 log sources, 4 agents |
| Deliverable | Rule Analysis Worksheet for 5 Wazuh rules with detection logic explained |
Behind Every Alert Is a Rule. When you see "SSHD brute force" in Wazuh, you're seeing the rule's description — not the detection logic itself. To truly understand what's being detected (and what's being missed), you need to read the rule definition. This is the skill that separates Tier 1 analysts who follow playbooks from Tier 2 analysts who write them.
The Scenario
Your SOC manager notices the team is spending time investigating alerts without understanding the rules behind them. "I need every analyst to be able to open any rule, read the XML, and explain: what log pattern triggered this, what thresholds are set, and what could an attacker do to evade this detection." You're tasked with analyzing 5 key rules from your environment.
Part 1: How Wazuh Rules Work
Rule Structure Overview
Every Wazuh rule is defined in XML and has this structure:
<rule id="5712" level="10" frequency="8" timeframe="120" ignore="60">
<if_matched_sid>5711</if_matched_sid>
<description>SSHD brute force trying to get access</description>
<mitre>
<id>T1110</id>
</mitre>
<group>authentication_failures,</group>
</rule>
Key Elements Explained
| Element | Purpose | Example |
|---|---|---|
| id | Unique rule identifier | 5712 |
| level | Severity (0-15) | 10 = medium-high |
| frequency | How many times the parent rule must fire | 8 (8 failed logins) |
| timeframe | Window for frequency counting (seconds) | 120 (2 minutes) |
| if_matched_sid | Parent rule that must fire first | 5711 (single SSH failure) |
| description | Human-readable alert text | "SSHD brute force trying to get access" |
| mitre > id | ATT&CK technique mapping | T1110 (Brute Force) |
| group | Alert categorization tags | authentication_failures |
The Rule Chain. Rule 5712 doesn't match log data directly. It watches for rule 5711 (single SSH auth failure) to fire 8 times within 120 seconds. This is called a chained rule or correlation rule — it detects patterns across multiple events, not just single events.
Part 2: Analyze Rule 5712 — SSH Brute Force
Step 1: Find the Alert
Search Wazuh for:
rule.id: 5712
You should find SSH brute force alerts on linux-web-01.
Step 2: Read the Rule Chain
The detection chain for SSH brute force has THREE levels:
Level 1 — Rule 5500 (Base Decoder):
<rule id="5500" level="0">
<decoded_as>sshd</decoded_as>
<description>SSHD messages grouped.</description>
</rule>
This catches all SSH daemon messages. Level 0 = no alert, just classification.
Level 2 — Rule 5711 (Single Failure):
<rule id="5711" level="5">
<if_sid>5700</if_sid>
<match>Failed|failed</match>
<description>sshd: authentication failed.</description>
</rule>
This fires once per failed SSH login. Level 5 = low severity.
Level 3 — Rule 5712 (Brute Force Pattern):
<rule id="5712" level="10" frequency="8" timeframe="120" ignore="60">
<if_matched_sid>5711</if_matched_sid>
<description>SSHD brute force trying to get access</description>
</rule>
This fires when rule 5711 fires 8+ times in 120 seconds. Level 10 = significant.
Step 3: Answer the Analysis Questions
RULE ANALYSIS #1: SSH Brute Force (Rule 5712)
──────────────────────────────────────────────
Rule ID: 5712
Level: 10
Detection Type: Chained / Frequency-based
Parent Rule: 5711 (single SSH failure)
Threshold: 8 occurrences in 120 seconds
MITRE Mapping: T1110 (Brute Force)
Q1: What raw log pattern triggers the base rule?
A: Any sshd log containing "Failed" or "failed"
Q2: Could an attacker evade this by slowing down?
A: Yes — if they attempt fewer than 8 logins per 2-minute window
(e.g., 7 attempts every 3 minutes), this rule would never fire
Q3: What does "ignore: 60" mean?
A: After firing, the rule suppresses for 60 seconds to prevent
alert flooding during an ongoing brute force
Q4: Does this rule detect brute force with VALID credentials?
A: No — it only watches for rule 5711 (failed logins). A password
spray using a correct password would trigger a 4624 success,
not a failure, and would be missed entirely.
Part 3: Analyze Rule 60106 — Logon Success After Failures
Step 1: Find the Alert
rule.id: 60106
Step 2: Read the Rule Logic
<rule id="60106" level="12" frequency="3" timeframe="360">
<if_matched_sid>18152</if_matched_sid>
<same_source_ip />
<description>Windows: Logon success after previously failed logon</description>
<mitre>
<id>T1078</id>
</mitre>
</rule>
Step 3: Decode the Logic
| Element | Meaning |
|---|---|
| frequency="3" | The parent rule (18152) must fire 3+ times |
| timeframe="360" | Within a 6-minute window |
| same_source_ip | All events must come from the same IP address |
| if_matched_sid: 18152 | Parent is the Windows brute force rule |
| level="12" | Critical — this means brute force SUCCEEDED |
Step 4: Analysis Worksheet
RULE ANALYSIS #2: Logon Success After Failures (Rule 60106)
───────────────────────────────────────────────────────────
Rule ID: 60106
Level: 12 (Critical)
Detection Type: Correlation (failure pattern → success indicator)
Parent Rule: 18152 (Windows brute force)
Threshold: 3 failures from same IP within 360 seconds, then success
MITRE Mapping: T1078 (Valid Accounts)
Q1: Why is this level 12 (critical) when brute force is level 10?
A: Because this rule means the attacker SUCCEEDED. Failed attempts
are concerning; successful compromise after failures is critical.
Q2: What does <same_source_ip /> add to the detection?
A: It ensures all failures AND the success come from the same IP.
Without this, a legitimate user failing 3 times from one IP
while an attacker succeeds from another would falsely correlate.
Q3: How could an attacker evade this rule?
A: By using a different IP for the successful logon than the one
used for brute force (e.g., through a proxy or VPN). The
<same_source_ip /> check would not correlate them.
Part 4: Analyze Rule 31103 — SQL Injection
Step 1: Find the Alert
rule.id: 31103
Step 2: Read the Rule Logic
<rule id="31103" level="12">
<if_sid>31100</if_sid>
<url>select|union|insert|cast|set|declare|drop|update|delete|exec</url>
<description>SQL injection attempt.</description>
<mitre>
<id>T1190</id>
</mitre>
<group>attack,sql_injection,</group>
</rule>
Step 3: Analysis Worksheet
RULE ANALYSIS #3: SQL Injection (Rule 31103)
────────────────────────────────────────────
Rule ID: 31103
Level: 12 (Critical)
Detection Type: Pattern match on URL field
Parent Rule: 31100 (web server access log decoder)
Pattern: URL contains: select|union|insert|cast|set|declare|drop|update|delete|exec
Q1: What specific SQL keywords trigger this rule?
A: select, union, insert, cast, set, declare, drop, update, delete, exec.
These are the most common SQL injection payload keywords.
Q2: Could an attacker evade this by encoding the payload?
A: Yes — URL encoding (%75nion instead of union), case mixing
(SeLeCt), or comment insertion (sel/**/ect) could bypass this
rule's simple string matching.
Q3: What DOESN'T this rule catch?
A: Blind SQL injection (which uses time-based or boolean-based
techniques without these keywords), NoSQL injection, or SQL
injection in POST body fields not captured in the URL field.
Q4: Why is the parent rule 31100 important?
A: 31100 is the web access log decoder — it parses Apache/Nginx
access logs and extracts the URL field. Without this parent,
rule 31103 wouldn't have a URL field to match against.
Rule Evasion Awareness. Understanding how to evade a rule doesn't make you an attacker — it makes you a better defender. When you know a rule's blind spots, you can write complementary rules that cover those gaps.
Part 5: Analyze Rule 5402 — Sudo to Root
Step 1: Find the Events
rule.id: 5402
Step 2: Read the Rule
<rule id="5402" level="3">
<if_sid>5400</if_sid>
<match>ROOT</match>
<description>Successful sudo to ROOT executed.</description>
<mitre>
<id>T1548.003</id>
</mitre>
</rule>
Step 3: Analysis Worksheet
RULE ANALYSIS #4: Sudo to Root (Rule 5402)
─────────────────────────────────────────
Rule ID: 5402
Level: 3 (Informational)
Detection Type: String match on sudo log
Parent Rule: 5400 (sudo grouping rule)
Pattern: Log contains "ROOT"
Q1: Why is this only level 3? Isn't sudo to root dangerous?
A: In many environments, sudo to root is NORMAL (admins, automated
scripts). Making it level 3 prevents alert fatigue. The risk
isn't sudo itself — it's WHO is using sudo and WHAT they're doing.
Q2: What makes the www-data sudo events in our lab suspicious?
A: www-data is a web service account. It should NEVER run sudo.
The rule doesn't know this — it fires the same way for www-data
as it would for a legitimate admin. The analyst adds the context.
Q3: How could you make this rule smarter?
A: Create a custom child rule that fires at level 12+ when
data.srcuser matches service accounts (www-data, apache, nginx).
This is called "rule tuning" — you'll learn it in Module 12.
Part 6: Analyze Rule 100002 — Custom Base64 Detection
Step 1: Find the Event
rule.id: 100002
Step 2: Read the Rule
<rule id="100002" level="14">
<if_sid>100001</if_sid>
<match>base64</match>
<description>Possible obfuscated command execution detected</description>
<mitre>
<id>T1027</id>
<id>T1059.004</id>
</mitre>
</rule>
Step 3: Analysis Worksheet
RULE ANALYSIS #5: Base64 Command Execution (Rule 100002)
───────────────────────────────────────────────────────
Rule ID: 100002 (Custom — IDs 100000+ are user-defined)
Level: 14 (High Critical)
Detection Type: String match for "base64" in command logs
Parent Rule: 100001 (custom command monitoring rule)
MITRE Mapping: T1027 (Obfuscated Files), T1059.004 (Unix Shell)
Q1: Why does this rule ID start with 100000?
A: Wazuh reserves rule IDs 100000+ for custom rules written by
the organization. Rules 1-99999 are built-in Wazuh rules. This
tells you someone specifically wrote this detection for their env.
Q2: Is matching "base64" in the log sufficient?
A: It's a start but has high false-positive potential — legitimate
scripts use base64 for encoding data. A better rule would
combine "base64" with "bash" or "| sh" to focus on execution.
Q3: What does mapping to BOTH T1027 and T1059.004 indicate?
A: Two ATT&CK techniques: the base64 encoding is the obfuscation
(T1027) and the decoded content is a Unix shell command (T1059.004).
Dual mapping captures both the technique and the execution method.
Part 7: Rule Effectiveness Summary
For each of the 5 rules you analyzed, rate its effectiveness:
| Rule | What It Catches | What It Misses | Evasion Difficulty |
|---|---|---|---|
| 5712 (SSH BF) | Rapid SSH failures from one IP | Slow brute force, distributed attacks | Low — just slow down |
| 60106 (Success after BF) | Same-IP failure→success pattern | Different IP for success | Medium — need proxy |
| 31103 (SQLi) | Common SQL keywords in URLs | Encoded/obfuscated SQL, POST body | Low — URL encode |
| 5402 (Sudo root) | All sudo to root events | Nothing — catches all, but high noise | N/A — detection is complete |
| 100002 (Base64) | Commands containing "base64" | Other encodings (hex, gzip, xxd) | Low — use different encoding |
Deliverable Checklist
Before completing the lab, ensure you have:
- 5 Rule Analysis Worksheets — complete for rules 5712, 60106, 31103, 5402, and 100002
- Rule Hierarchy Documentation — parent→child chain for at least 2 rules
- Evasion Analysis — at least one evasion technique per rule
- Effectiveness Summary Table — catches, misses, and evasion difficulty for all 5
- Key Insight — one rule you'd prioritize for tuning and why
Key Takeaways
- Every Wazuh alert is generated by an XML rule with specific fields, thresholds, and parent dependencies
- Frequency + timeframe rules detect attack PATTERNS across multiple events (brute force, spray)
- The
same_source_ipandif_matched_sidelements create correlation chains that link related events - Understanding rule evasion helps defenders write better, layered detections
- Custom rules (ID 100000+) extend Wazuh beyond built-in detections — this is where detection engineering begins
- Rule level (severity) reflects how dangerous the PATTERN is, not how dangerous one event is
What's Next
In Lab 2.6 — Sysmon Visibility Boost, you'll explore how endpoint telemetry from Sysmon enriches your SIEM data with process creation, network connections, and file changes that standard Windows logging misses entirely.
Lab Challenge: Read the Rule
10 questions · 70% to pass
Look at rule 5712 (SSH brute force). What does the 'frequency="8"' attribute mean in the context of this chained rule?
Rule 60106 uses <same_source_ip />. In the pre-loaded attack scenario, what source IP triggered this correlation?
Rule 31103 (SQL injection) matches against the 'url' field with keywords like 'select|union|insert'. An attacker encodes 'union' as '%75nion' in the URL. Would rule 31103 catch this?
Rule 5402 (sudo to root) is level 3 (informational). In the pre-loaded data, www-data runs sudo to root. Why doesn't the rule's severity match the actual threat?
What does the 'ignore="60"' attribute in rule 5712 do during an active SSH brute force?
Rule 100002 has an ID starting with 100000. What does this indicate about the rule's origin?
An attacker performs SSH brute force at a rate of 6 attempts per 3-minute window. Would rule 5712 (frequency=8, timeframe=120) detect this?
Rule 60106 correlates Windows brute force (rule 18152) with a subsequent successful logon. What element ensures the success came from the SAME attacker as the failures?
Rule 31103 maps to MITRE T1190 (Exploit Public-Facing Application). If you wanted to add a second rule that catches POST-body SQL injection (not in the URL), what would you change?
Based on your analysis of all 5 rules, which rule would benefit MOST from tuning and why?
0/10 answered