Multiple Microsoft 365 User Account Lockouts in Short Time Window
Detects a burst of Microsoft 365 user account lockouts within a short 5-minute window. A high number of IdsLocked login errors across multiple user accounts may indicate brute-force attempts for the same users resulting in lockouts.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2025/05/10"
3integration = ["o365"]
4maturity = "production"
5min_stack_version = "8.17.0"
6min_stack_comments = "Elastic ES|QL values aggregation is more performant in 8.16.5 and above."
7updated_date = "2025/05/10"
8
9[rule]
10author = ["Elastic"]
11description = """
12Detects a burst of Microsoft 365 user account lockouts within a short 5-minute window. A high number of IdsLocked login
13errors across multiple user accounts may indicate brute-force attempts for the same users resulting in lockouts.
14"""
15from = "now-9m"
16language = "esql"
17license = "Elastic License v2"
18name = "Multiple Microsoft 365 User Account Lockouts in Short Time Window"
19note = """## Triage and Analysis
20
21### Investigating Multiple Microsoft 365 User Account Lockouts in Short Time Window
22
23Detects a burst of Microsoft 365 user account lockouts within a short 5-minute window. A high number of IdsLocked login errors across multiple user accounts may indicate brute-force attempts for the same users resulting in lockouts.
24
25This rule uses ES|QL aggregations and thus has dynamically generated fields. Correlation of the values in the alert document may need to be performed to the original sign-in and Graph events for further context.
26
27### Investigation Steps
28
29- Review the `user_id_list`: Are specific naming patterns targeted (e.g., admin, helpdesk)?
30- Examine `ip_list` and `source_orgs`: Look for suspicious ISPs or hosting providers.
31- Check `duration_seconds`: A very short window with a high lockout rate often indicates automation.
32- Confirm lockout policy thresholds with IAM or Entra ID admins. Did the policy trigger correctly?
33- Use the `first_seen` and `last_seen` values to pivot into related authentication or audit logs.
34- Correlate with any recent detection of password spraying or credential stuffing activity.
35- Review the `request_type` field to identify which authentication methods were used (e.g., OAuth, SAML, etc.).
36- Check for any successful logins from the same IP or ASN after the lockouts.
37
38### False Positive Analysis
39
40- Automated systems with stale credentials may cause repeated failed logins.
41- Legitimate bulk provisioning or scripted tests could unintentionally cause account lockouts.
42- Red team exercises or penetration tests may resemble the same lockout pattern.
43- Some organizations may have a high volume of lockouts due to user behavior or legacy systems.
44
45### Response Recommendations
46
47- Notify affected users and confirm whether activity was expected or suspicious.
48- Lock or reset credentials for impacted accounts.
49- Block the source IP(s) or ASN temporarily using conditional access or firewall rules.
50- Strengthen lockout and retry delay policies if necessary.
51- Review the originating application(s) involved via `request_types`.
52"""
53references = [
54 "https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray",
55 "https://learn.microsoft.com/en-us/purview/audit-log-detailed-properties",
56 "https://securityscorecard.com/research/massive-botnet-targets-m365-with-stealthy-password-spraying-attacks/",
57 "https://github.com/0xZDH/Omnispray",
58 "https://github.com/0xZDH/o365spray",
59]
60risk_score = 47
61rule_id = "de67f85e-2d43-11f0-b8c9-f661ea17fbcc"
62severity = "medium"
63tags = [
64 "Domain: Cloud",
65 "Domain: SaaS",
66 "Data Source: Microsoft 365",
67 "Data Source: Microsoft 365 Audit Logs",
68 "Use Case: Threat Detection",
69 "Use Case: Identity and Access Audit",
70 "Tactic: Credential Access",
71 "Resources: Investigation Guide",
72]
73timestamp_override = "event.ingested"
74type = "esql"
75
76query = '''
77FROM logs-o365.audit-*
78
79| MV_EXPAND event.category
80| EVAL
81 time_window = DATE_TRUNC(5 minutes, @timestamp),
82 user_id = TO_LOWER(o365.audit.UserId),
83 ip = source.ip,
84 login_error = o365.audit.LogonError,
85 request_type = TO_LOWER(o365.audit.ExtendedProperties.RequestType),
86 asn_org = source.`as`.organization.name,
87 country = source.geo.country_name,
88 event_time = @timestamp
89
90| WHERE event.dataset == "o365.audit"
91 AND event.category == "authentication"
92 AND event.provider IN ("AzureActiveDirectory", "Exchange")
93 AND event.action IN ("UserLoginFailed", "PasswordLogonInitialAuthUsingPassword")
94 AND request_type RLIKE "(oauth.*||.*login.*)"
95 AND login_error == "IdsLocked"
96 AND user_id != "not available"
97 AND o365.audit.Target.Type IN ("0", "2", "6", "10")
98 AND asn_org != "MICROSOFT-CORP-MSN-AS-BLOCK"
99
100| STATS
101 unique_users = COUNT_DISTINCT(user_id),
102 user_id_list = VALUES(user_id),
103 ip_list = VALUES(ip),
104 unique_ips = COUNT_DISTINCT(ip),
105 source_orgs = VALUES(asn_org),
106 countries = VALUES(country),
107 unique_country_count = COUNT_DISTINCT(country),
108 unique_asn_orgs = COUNT_DISTINCT(asn_org),
109 request_types = VALUES(request_type),
110 first_seen = MIN(event_time),
111 last_seen = MAX(event_time),
112 total_lockout_responses = COUNT()
113 BY time_window
114
115| EVAL
116 duration_seconds = DATE_DIFF("seconds", first_seen, last_seen)
117
118| KEEP
119 time_window, unique_users, user_id_list, ip_list,
120 unique_ips, source_orgs, countries, unique_country_count,
121 unique_asn_orgs, request_types, first_seen, last_seen,
122 total_lockout_responses, duration_seconds
123
124| WHERE
125 unique_users >= 10 AND
126 total_lockout_responses >= 10 AND
127 duration_seconds <= 300
128'''
129
130
131[[rule.threat]]
132framework = "MITRE ATT&CK"
133[[rule.threat.technique]]
134id = "T1110"
135name = "Brute Force"
136reference = "https://attack.mitre.org/techniques/T1110/"
137
138
139[rule.threat.tactic]
140id = "TA0006"
141name = "Credential Access"
142reference = "https://attack.mitre.org/tactics/TA0006/"
Triage and Analysis
Investigating Multiple Microsoft 365 User Account Lockouts in Short Time Window
Detects a burst of Microsoft 365 user account lockouts within a short 5-minute window. A high number of IdsLocked login errors across multiple user accounts may indicate brute-force attempts for the same users resulting in lockouts.
This rule uses ES|QL aggregations and thus has dynamically generated fields. Correlation of the values in the alert document may need to be performed to the original sign-in and Graph events for further context.
Investigation Steps
- Review the
user_id_list
: Are specific naming patterns targeted (e.g., admin, helpdesk)? - Examine
ip_list
andsource_orgs
: Look for suspicious ISPs or hosting providers. - Check
duration_seconds
: A very short window with a high lockout rate often indicates automation. - Confirm lockout policy thresholds with IAM or Entra ID admins. Did the policy trigger correctly?
- Use the
first_seen
andlast_seen
values to pivot into related authentication or audit logs. - Correlate with any recent detection of password spraying or credential stuffing activity.
- Review the
request_type
field to identify which authentication methods were used (e.g., OAuth, SAML, etc.). - Check for any successful logins from the same IP or ASN after the lockouts.
False Positive Analysis
- Automated systems with stale credentials may cause repeated failed logins.
- Legitimate bulk provisioning or scripted tests could unintentionally cause account lockouts.
- Red team exercises or penetration tests may resemble the same lockout pattern.
- Some organizations may have a high volume of lockouts due to user behavior or legacy systems.
Response Recommendations
- Notify affected users and confirm whether activity was expected or suspicious.
- Lock or reset credentials for impacted accounts.
- Block the source IP(s) or ASN temporarily using conditional access or firewall rules.
- Strengthen lockout and retry delay policies if necessary.
- Review the originating application(s) involved via
request_types
.
References
Related rules
- Microsoft Azure or Mail Sign-in from a Suspicious Source
- Microsoft 365 OAuth Redirect to Device Registration for User Principal
- Microsoft Entra ID Concurrent Sign-Ins with Suspicious Properties
- Microsoft 365 OAuth Phishing via Visual Studio Code Client
- Microsoft 365 Illicit Consent Grant via Registered Application