Skip to main content

Wazuh: SSH Brute Force

Table of Contents

Objective
#

Simulate an SSH brute force attack from a Kali Linux machine against an Ubuntu 22.04 agent, observe Wazuh detection capabilities, identify gaps in the default ruleset, and configure automated response.

Environment
#

RoleOSIP
AttackerKali Linux192.168.248.129
AgentUbuntu 22.04 Server192.168.248.140
WazuhUbuntu 24.04 Server192.168.248.50

Attack Simulation
#

The attack was simulated using Hydra from the Kali Linux machine targeting the Ubuntu 22.04 agent over SSH. Two brute force attempts were executed against different usernames:

1# Attempt 1 — targeting root
2hydra -l root -P /usr/share/wordlists/fasttrack.txt ssh://192.168.248.140
3
4# Attempt 2 — targeting user 'w'
5hydra -l w -P /usr/share/wordlists/fasttrack.txt ssh://192.168.248.140

Each run tried 262 passwords at ~220 attempts/min. Both attempts failed — no valid credentials were found. Total duration: ~1 min 17 sec per run.

What Wazuh Detected
#

Dashboard overview

Wazuh generated 1,010 authentication failure alerts across both runs. 0 successful logins were recorded. Two distinct spikes are visible on the timeline (~07:08 and ~07:15), corresponding to each Hydra run. MITRE ATT&CK: T1110.001 - Brute Force: Password Guessing via SSH.

Alert list

Seven rule IDs were triggered during the attack:

Rule IDLevelDescription
57605sshd: authentication failed
55515sshd: Invalid user
55035sshd: Connection closed
57685sshd: Maximum authentication attempts exceeded
25015User missed the password
250210User missed the password more than once
4011110Multiple authentication failures

Rules 5760, 5551, 5503, 5768, and 2501 fire per individual event (level 5). Rules 2502 and 40111 are correlation rules that aggregate multiple failures into a higher severity alert (level 10). Notable: 0 alerts reached level 12 or above — addressed in Tuning section.

Expanded view of a single Rule 5760 alert:

- Source IP: 192.168.248.129
- Target user: w
- Source port: 41772
- Full log: Failed password for w from 192.168.248.129 port 41772 ssh2
- MITRE: T1110.001 - Password Guessing / T1021.004 - SSH
- Fired times: 533

 1{
 2  "agent": { "ip": "192.168.248.140", "name": "agent1", "id": "001" },
 3  "data": { "srcip": "192.168.248.129", "dstuser": "w", "srcport": "41772" },
 4  "rule": {
 5    "id": "5760",
 6    "level": 5,
 7    "description": "sshd: authentication failed.",
 8    "firedtimes": 533,
 9    "mitre": {
10      "technique": ["Password Guessing", "SSH"],
11      "id": ["T1110.001", "T1021.004"],
12      "tactic": ["Credential Access", "Lateral Movement"]
13    }
14  },
15  "full_log": "Feb 20 12:15:46 w sshd[7202]: Failed password for w from 192.168.248.129 port 41772 ssh2",
16  "timestamp": "2026-02-20T12:15:48.177+0000"
17}

What Was Missed & Why
#

No Level 12 or above alerts were triggered during the initial simulation. Wazuh’s built-in ruleset caps brute force detection at Level 10, meaning the attack would not trigger a critical notification by default — a potential blind spot in a real SOC environment.

Tuning & Custom Rules
#

To address the detection gap, a custom rule was created in /var/ossec/etc/rules/local_rules.xml:

1<group name="sshd,authentication_failed,">
2  <rule id="100001" level="12">
3    <if_matched_sid>40111</if_matched_sid>
4    <description>SSH Brute Force: High volume of authentication failures from same source</description>
5    <mitre>
6      <id>T1110.001</id>
7    </mitre>
8  </rule>
9</group>

Response
#

After the custom rule 100001 triggered, Wazuh executed the built-in firewall-drop active response on agent1, automatically blocking the attacker’s IP via iptables. The active response was configured in /var/ossec/etc/ossec.conf:

1<active-response>
2  <command>firewall-drop</command>
3  <location>local</location>
4  <rules_id>100001</rules_id>
5  <timeout>180</timeout>
6</active-response>

The effect was immediately visible in Hydra’s output — attempt rate dropped from 107 tries/min to 44 tries/min as connections began failing, and eventually all tasks were disabled:

1[ERROR] all children were disabled due too many connection errors
2[ERROR] 1 targets did not complete

Dashboard after active response

Level 12 alerts: 2 — rule 100001 fired successfully.

Expanded view of Rule 100001 alert:

- Rule ID: 100001 (custom)
- Level: 12
- Source IP: 192.168.248.129
- Target user: w
- Fired times: 2
- mail: true — level 12 triggers email notification if configured
- Full log: maximum authentication attempts exceeded for w from 192.168.248.129
- MITRE: T1110.001 - Credential Access: Password Guessing

The block was automatically lifted after the configured timeout of 180 seconds. To make a permanent block, the timeout value can be set to 0.

Conclusion
#

Wazuh successfully detected the SSH brute force attack out of the box, generating 1,010 alerts across 7 rule IDs. However, the default ruleset did not escalate the alert to critical severity (level 12), which would be a gap in a real SOC environment where level 12 triggers priority notifications.

Adding a single custom rule resolved this gap and enabled automated IP blocking via active response — stopping the attack mid-execution without any manual intervention.

Key takeaways:
- Default Wazuh rules detect brute force but cap at level 10
- Custom rules can bridge the gap with minimal configuration
- Active response provides automated containment within seconds of detection
- Timeout-based blocks are suitable for automated response; permanent blocks require manual review to avoid blocking legitimate users