# Wazuh Detection Rules — Engineering Notes Reference for each custom Wazuh rule defined in `wazuh_brute_force_rules.xml`. Designed to strictly align with interview defensibility requirements. --- ## Architecture Overview **Why Wazuh?** Wazuh natively integrates with Kubernetes (via DaemonSets) and provides out-of-the-box File Integrity Monitoring (FIM), rootkit detection, and log correlation. It's lighter and more cost-effective than deploying a full Splunk forwarder on every node in Ghaymah Containers. **Rule ID Strategy:** Standard Wazuh rules use IDs < 100,000. Custom user rules must be >= 100,000. We reserved `100200-100219` for Ghaymah Authentication Rules to maintain organized namespaces and prevent conflicts with future official updates. --- ## Rule Definitions ### Rule 100200: Base API Auth Failure - **Purpose:** Acts as the foundational baseline rule, triggering on every single failed API login. - **Parent Rule:** N/A (Standalone base rule) - **Decoder:** `json` (Our API logs natively in structured JSON) - **Rule ID selection:** 100200 (Start of our reserved auth block) - **Alert Level:** 3 (Low) - High enough to index in Elastic, low enough to avoid spam. - **MITRE ATT&CK Mapping:** T1110 (Brute Force) - **Conditions:** `field name="event.action"` matches `login_failed` - **False Positives:** Legitimate users mistyping passwords. - **False Negatives:** Attackers exploiting token bypasses instead of password auth. - **Example triggering log:** `{"timestamp":"2026-07-27T10:00:00Z", "event":{"action":"login_failed"}, "source":{"ip":"192.168.1.5"}}` - **Expected alert:** Silent indexing. No active response. - **Testing method:** `curl -X POST /api/login -d '{"user":"test", "pass":"wrong"}'` - **Possible improvements:** Enrich with GeoIP data at the decoder level. ### Rule 100202: Confirmed Brute Force - **Purpose:** Detects sustained, aggressive credential guessing from a single IP. - **Parent Rule:** 100200 - **Decoder:** `json` - **Rule ID selection:** 100202 - **Alert Level:** 10 (High) - **MITRE ATT&CK Mapping:** T1110.001 (Password Guessing) - **Frequency:** 20 occurrences - **Timeframe:** 120 seconds - **Conditions:** `` - **False Positives:** Corporate NAT gateways where 20 different users are legitimately failing logins concurrently. - **False Negatives:** "Low and slow" brute force (e.g., 1 attempt per hour). - **Example triggering log:** (20x of Rule 100200 from the same IP) - **Expected alert:** "Confirmed Brute Force Attack from IP X". Triggers Soft Block via n8n. - **Testing method:** `hydra -l admin -P rockyou.txt https-post-form "/api/login"` - **Possible improvements:** Dynamically adjust the timeframe based on the IP's previous reputation score. ### Rule 100204: Distributed Brute Force (Credential Stuffing) - **Purpose:** Detects botnets using rotating proxies to attack a single account, bypassing per-IP rate limits. - **Parent Rule:** 100200 - **Decoder:** `json` - **Rule ID selection:** 100204 - **Alert Level:** 12 (High) - **MITRE ATT&CK Mapping:** T1110.003 (Password Spraying) - **Frequency:** 10 occurrences - **Timeframe:** 300 seconds - **Conditions:** `data.target_user` AND `` - **False Positives:** Distributed team attempting to log into a shared service account concurrently (bad practice, but happens). - **False Negatives:** Botnets targeting multiple accounts simultaneously (avoids `same_field` correlation). - **Example triggering log:** 10 failures for `admin` from 10 different AWS/Ghaymah Cloud IPs. - **Expected alert:** "Distributed Brute Force against Account X". - **Testing method:** Custom Python script rotating proxies while attacking one account. - **Possible improvements:** Integrate with Threat Intelligence feeds to identify known Tor exit nodes automatically. ### Rule 100206: Successful Login AFTER Brute Force (Compromise) - **Purpose:** Identifies the moment a brute force attack transitions into a successful breach. - **Parent Rule:** N/A (Correlates across auth success rule) - **Decoder:** `json` - **Rule ID selection:** 100206 - **Alert Level:** 14 (Critical) - **MITRE ATT&CK Mapping:** T1078 (Valid Accounts) - **Conditions:** `100202` AND `authentication_success` from the same IP. - **False Positives:** A legitimate user legitimately forgets their password, fails 20 times, resets it, and logs in successfully. - **False Negatives:** The attacker brute-forces the password from IP A, but uses it to log in via VPN from IP B. - **Example triggering log:** Rule 100202 fires, followed immediately by `{"event":{"action":"login_success"}}`. - **Expected alert:** "CRITICAL: Account Compromised following Brute Force". - **Testing method:** Run hydra to trigger 100202, then immediately log in with correct credentials via curl. - **Possible improvements:** Change correlation to track the target account rather than just the source IP to prevent the IP A/B bypass. ### Rule 100208: Service Account Brute Force - **Purpose:** Protects non-MFA enabled machine accounts. - **Parent Rule:** 100200 - **Decoder:** `json` - **Rule ID selection:** 100208 - **Alert Level:** 14 (Critical) - **MITRE ATT&CK Mapping:** T1078.003 (Local Accounts) - **Frequency:** 5 occurrences - **Timeframe:** 60 seconds - **Conditions:** Regex match on `^svc-|^service-|^system-` - **False Positives:** A misconfigured internal cronjob failing to authenticate. - **False Negatives:** Service accounts that don't follow the naming convention. - **Expected alert:** "CRITICAL: Service Account Brute Force Attempt". - **Testing method:** `hydra -l svc-db-backup -P rockyou.txt https-post-form "/api/login"` - **Possible improvements:** Query Active Directory/LDAP directly rather than relying on regex string matching for the username.