Potential Password Spraying Attack via SSH
This rule detects potential password spraying attacks via SSH by identifying multiple failed login attempts from a single source IP address targeting various user accounts within a short time frame. Password spraying is a technique where an attacker attempts to gain unauthorized access by trying a few commonly used passwords against many different accounts, rather than targeting a single account with multiple password attempts.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2025/12/24"
3integration = ["system"]
4maturity = "production"
5updated_date = "2026/01/12"
6
7[rule]
8author = ["Elastic"]
9description = """
10This rule detects potential password spraying attacks via SSH by identifying multiple failed login
11attempts from a single source IP address targeting various user accounts within a short time frame.
12Password spraying is a technique where an attacker attempts to gain unauthorized access by trying a
13few commonly used passwords against many different accounts, rather than targeting a single account
14with multiple password attempts.
15"""
16from = "now-9m"
17language = "esql"
18license = "Elastic License v2"
19name = "Potential Password Spraying Attack via SSH"
20note = """ ## Triage and analysis
21
22> **Disclaimer**:
23> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
24
25### Investigating Potential Password Spraying Attack via SSH
26
27This rule flags bursts of failed SSH logins coming from the same network origin against many different Linux accounts within a short window, indicating password spraying that can precede account compromise. It matters because attackers try a small set of common passwords across broad user lists to evade lockouts and find one weak credential. A typical pattern is an external VPS rapidly trying passwords like “Welcome123” or “Spring2024!” against 30+ usernames (e.g., admin, test, ubuntu, devops) over five minutes via SSH on a single server.
28
29### Possible investigation steps
30
31- Check for any successful SSH authentications from the same source IP within a short window around the failures and, if found, pivot to session details such as interactive TTY use, sudo activity, and modifications like authorized_keys updates.
32- Enrich the source IP with geolocation, ASN, reputation, and cloud-provider attribution and verify whether it is observed attempting SSH across multiple hosts to confirm a broad spray pattern.
33- Compare the attempted usernames against your directory to identify valid and privileged or service accounts and confirm whether lockouts, password resets, or MFA challenges were triggered.
34- Determine if the affected host is internet-exposed and which port SSH is reachable on, then review current SSH authentication settings (password vs key-based, PAM/MFA) to assess risk of compromise.
35- Correlate the source IP with approved scanners, bastion hosts, or change tickets and maintenance windows to quickly rule out sanctioned testing or misconfigured monitoring.
36
37### False positive analysis
38
39- A misconfigured internal automation or admin script on a management or jump host sequentially attempts SSH to many accounts with an outdated password, producing more than 10 distinct usernames and at least 30 failures from a single source IP within five minutes.
40- Legitimate users behind a shared NAT or bastion host concurrently attempt SSH with expired credentials during a password rotation or temporary authentication issue, making failures across many distinct usernames appear to come from one IP.
41
42### Response and remediation
43
44- Immediately block the spraying source IP(s) at host firewalls (iptables/nftables) and edge controls, and temporarily restrict SSH (port 22) to approved bastion/jump host CIDRs only.
45- If any login succeeded or an sshd session from the same IP is active, terminate it, remove any newly added ~/.ssh/authorized_keys entries, and force password resets with MFA for the targeted users.
46- Before restoring normal access, verify no persistence by checking for changes to /etc/ssh/sshd_config, sudoers, or cron jobs and reviewing /var/log/auth.log and lastlog for anomalies, then re-enable only required accounts.
47- Escalate to incident response if privileged or service accounts were targeted, the spray spanned multiple servers, or there is evidence of sudo activity, file changes under /root or /etc, or a successful login, and preserve auth logs, bash histories, and firewall block artifacts.
48- Harden SSH by disabling PasswordAuthentication, enforcing key-based auth with PAM MFA, setting conservative MaxAuthTries and LoginGraceTime, enabling fail2ban or equivalent bans, and restricting access via AllowUsers/AllowGroups and security group rules.
49"""
50risk_score = 21
51rule_id = "9e81b1fd-e9fb-49a7-8ebe-0d1a14090142"
52severity = "low"
53tags = [
54 "Domain: Endpoint",
55 "OS: Linux",
56 "Use Case: Threat Detection",
57 "Tactic: Credential Access",
58 "Resources: Investigation Guide",
59]
60timestamp_override = "event.ingested"
61type = "esql"
62query = '''
63from logs-system.auth-* metadata _id, _index, _version
64
65// Create 5-minute time buckets
66| eval Esql.time_window_date_trunc = date_trunc(5 minutes, @timestamp)
67
68// Ensure event.action values in a list are expanded
69| mv_expand event.action
70
71| where
72 event.category == "authentication" and event.action in ("ssh_login", "user_login") and event.outcome == "failure" and
73 source.ip is not null
74
75// Keep relevant fields
76| keep
77 @timestamp,
78 _id,
79 _index,
80 _version,
81 event.category,
82 event.action,
83 event.outcome,
84 source.ip,
85 process.name,
86 user.name,
87 event.dataset,
88 data_stream.namespace,
89 agent.id,
90 user.id,
91 Esql.time_window_date_trunc
92
93| stats
94 Esql.event_count = count(*),
95 Esql.user_name_count_distinct = count_distinct(user.name),
96 Esql.user_name_values = values(user.name),
97 Esql.process_name_values = values(process.name),
98 Esql.event_dataset_values = values(event.dataset),
99 Esql.data_stream_namespace_values = values(data_stream.namespace)
100
101 by Esql.time_window_date_trunc, source.ip
102
103| where Esql.user_name_count_distinct > 10 and Esql.event_count >= 30
104'''
105
106[[rule.threat]]
107framework = "MITRE ATT&CK"
108
109[[rule.threat.technique]]
110id = "T1110"
111name = "Brute Force"
112reference = "https://attack.mitre.org/techniques/T1110/"
113
114[[rule.threat.technique.subtechnique]]
115id = "T1110.001"
116name = "Password Guessing"
117reference = "https://attack.mitre.org/techniques/T1110/001/"
118
119[[rule.threat.technique.subtechnique]]
120id = "T1110.003"
121name = "Password Spraying"
122reference = "https://attack.mitre.org/techniques/T1110/003/"
123
124[rule.threat.tactic]
125id = "TA0006"
126name = "Credential Access"
127reference = "https://attack.mitre.org/tactics/TA0006/"
Triage and analysis
Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
Investigating Potential Password Spraying Attack via SSH
This rule flags bursts of failed SSH logins coming from the same network origin against many different Linux accounts within a short window, indicating password spraying that can precede account compromise. It matters because attackers try a small set of common passwords across broad user lists to evade lockouts and find one weak credential. A typical pattern is an external VPS rapidly trying passwords like “Welcome123” or “Spring2024!” against 30+ usernames (e.g., admin, test, ubuntu, devops) over five minutes via SSH on a single server.
Possible investigation steps
- Check for any successful SSH authentications from the same source IP within a short window around the failures and, if found, pivot to session details such as interactive TTY use, sudo activity, and modifications like authorized_keys updates.
- Enrich the source IP with geolocation, ASN, reputation, and cloud-provider attribution and verify whether it is observed attempting SSH across multiple hosts to confirm a broad spray pattern.
- Compare the attempted usernames against your directory to identify valid and privileged or service accounts and confirm whether lockouts, password resets, or MFA challenges were triggered.
- Determine if the affected host is internet-exposed and which port SSH is reachable on, then review current SSH authentication settings (password vs key-based, PAM/MFA) to assess risk of compromise.
- Correlate the source IP with approved scanners, bastion hosts, or change tickets and maintenance windows to quickly rule out sanctioned testing or misconfigured monitoring.
False positive analysis
- A misconfigured internal automation or admin script on a management or jump host sequentially attempts SSH to many accounts with an outdated password, producing more than 10 distinct usernames and at least 30 failures from a single source IP within five minutes.
- Legitimate users behind a shared NAT or bastion host concurrently attempt SSH with expired credentials during a password rotation or temporary authentication issue, making failures across many distinct usernames appear to come from one IP.
Response and remediation
- Immediately block the spraying source IP(s) at host firewalls (iptables/nftables) and edge controls, and temporarily restrict SSH (port 22) to approved bastion/jump host CIDRs only.
- If any login succeeded or an sshd session from the same IP is active, terminate it, remove any newly added ~/.ssh/authorized_keys entries, and force password resets with MFA for the targeted users.
- Before restoring normal access, verify no persistence by checking for changes to /etc/ssh/sshd_config, sudoers, or cron jobs and reviewing /var/log/auth.log and lastlog for anomalies, then re-enable only required accounts.
- Escalate to incident response if privileged or service accounts were targeted, the spray spanned multiple servers, or there is evidence of sudo activity, file changes under /root or /etc, or a successful login, and preserve auth logs, bash histories, and firewall block artifacts.
- Harden SSH by disabling PasswordAuthentication, enforcing key-based auth with PAM MFA, setting conservative MaxAuthTries and LoginGraceTime, enabling fail2ban or equivalent bans, and restricting access via AllowUsers/AllowGroups and security group rules.
Related rules
- GitHub Authentication Token Access via Node.js
- Kubernetes Service Account Secret Access
- Linux init (PID 1) Secret Dump via GDB
- Manual Memory Dumping via Proc Filesystem
- Potential External Linux SSH Brute Force Detected