Entra ID Excessive Account Lockouts Detected

Identifies a high count of failed Microsoft Entra ID sign-in attempts as the result of the target user account being locked out. Adversaries may attempt to brute-force user accounts by repeatedly trying to authenticate with incorrect credentials, leading to account lockouts by Entra ID Smart Lockout policies.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2025/07/01"
  3integration = ["azure"]
  4maturity = "production"
  5min_stack_comments = "Changing min stack to 9.1.0, the latest minimum supported version for 9.X releases."
  6min_stack_version = "9.1.0"
  7updated_date = "2026/01/12"
  8
  9[rule]
 10author = ["Elastic"]
 11description = """
 12Identifies a high count of failed Microsoft Entra ID sign-in attempts as the result of the target user account being
 13locked out. Adversaries may attempt to brute-force user accounts by repeatedly trying to authenticate with incorrect
 14credentials, leading to account lockouts by Entra ID Smart Lockout policies.
 15"""
 16false_positives = [
 17    """
 18    Automated processes that attempt to authenticate using expired credentials or have misconfigured authentication
 19    settings may lead to false positives.
 20    """,
 21]
 22from = "now-30m"
 23index = ["filebeat-*", "logs-azure.signinlogs-*"]
 24interval = "15m"
 25language = "kuery"
 26license = "Elastic License v2"
 27name = "Entra ID Excessive Account Lockouts Detected"
 28note = """## Triage and analysis
 29
 30### Investigating Entra ID Excessive Account Lockouts Detected
 31
 32This rule detects a high number of sign-in failures due to account lockouts (error code `50053`) in Microsoft Entra ID sign-in logs. These lockouts are typically caused by repeated authentication failures, often as a result of brute-force tactics such as password spraying, credential stuffing, or automated guessing. This detection is time-bucketed and aggregates attempts to identify bursts or coordinated campaigns targeting multiple users. Error code `50053` indicates Entra ID Smart Lockout, which is IP-based and tracks "unfamiliar" vs "familiar" locations. Familiar IPs have a higher threshold before lockout, so if lockouts are occurring, the source IP was unfamiliar to those accounts.
 33
 34### Possible investigation steps
 35
 36- This is a threshold rule that aggregates events, so the alert document won't contain individual sign-in attempts. Pivot to the raw logs in Discover or Timeline using: `event.dataset: "azure.signinlogs" and azure.signinlogs.properties.status.error_code: 50053`. Match the time range to the alert window (rule lookback is 30 minutes).
 37- Add relevant columns: `@timestamp`, `user.name`, `source.ip`, `user_agent.original`, `azure.signinlogs.properties.app_display_name`, `azure.signinlogs.properties.client_app_used`, `source.as.organization.name`, `geo.country_iso_code`, `azure.signinlogs.properties.authentication_details`.
 38- Aggregate by `source.ip` and `user.name` to identify the attack pattern: password spray (single/small set of IPs targeting many accounts), credential stuffing (many source IPs, may target specific users with leaked credentials), targeted brute force (focused on single high-value account), or misconfigured service (single source IP with consistent user-agent matching legitimate application).
 39- Analyze `user_agent.original` for indicators of automation. Values like `curl/*`, `python-requests/*`, `Go-http-client/*`, `axios/*` indicate scripted attacks. `BAV2ROPC` indicates Resource Owner Password Credential flow (legacy auth), commonly abused by spray tools like o365spray and MSOLSpray.
 40- Review `azure.signinlogs.properties.client_app_used`. `Other clients` indicates legacy auth (IMAP, SMTP, POP) which is high-risk. `Exchange ActiveSync` is legacy auth often targeted.
 41- Check `azure.signinlogs.properties.authentication_protocol` for `ropc` (Resource Owner Password Credential), a legacy flow where credentials are sent directly with no MFA interruption possible.
 42- Review `source.as.organization.name`. Cloud hosting providers (DigitalOcean, Vultr, Linode, AWS, Azure, GCP) or VPN providers (NordVPN, ExpressVPN, Mullvad) are high-risk as attackers use this infrastructure.
 43- Check `azure.signinlogs.properties.conditional_access_status`. `notApplied` means no CA policy evaluated, indicating a coverage gap. `failure` means CA policy blocked the sign-in.
 44- Determine if any accounts were compromised. Query for successful sign-ins from attacking infrastructure: `event.dataset: "azure.signinlogs" and event.outcome: "success" and source.ip: "<attacker_ip>"`. Also query for successful sign-ins for affected users from any source during the attack window.
 45- Check for MFA bypass: `event.dataset: "azure.signinlogs" and event.outcome: "success" and azure.signinlogs.properties.authentication_requirement: "singleFactorAuthentication" and source.ip: "<attacker_ip>"`
 46- Review Entra ID Protection risk events for affected users by checking `risk_level_during_signin`, `risk_level_aggregated`, and `risk_state` for values other than `none`.
 47- Check for username enumeration preceding the spray. Error code `50034` (user not found) indicates enumeration: `event.dataset: "azure.signinlogs" and azure.signinlogs.properties.status.error_code: 50034 and source.ip: "<attacker_ip>"`
 48- Query for other error codes from the same source: `50126` (invalid password), `50034` (user not found), `50057` (account disabled), `50055` (password expired), `53003` (blocked by CA), `50158` (MFA challenge not satisfied). A mix of `50126` and `50053` confirms password guessing.
 49
 50### False positive analysis
 51
 52- Misconfigured clients, scripts, or services with outdated credentials may inadvertently cause lockouts.
 53- Lockouts during credential rotation windows could be benign.
 54- Legacy applications without modern auth support may repeatedly fail and trigger Smart Lockout.
 55- Specific known user agents from corporate service accounts.
 56- Cloud-hosted automation with expected failure behavior.
 57- This rule can be customized. Adjust the threshold and/or interval/lookback window based on baselining efforts. Specific UPNs can be excluded if they generate known false positives.
 58
 59### Response and remediation
 60
 61- Confirm no successful authentications from attacking source.
 62- Query for successful sign-ins to affected users from any source during the attack window.
 63- If compromise confirmed: disable account, revoke refresh tokens (`Revoke-AzureADUserAllRefreshToken` or via portal), reset password, require MFA re-registration.
 64- Block source IP/ASN via Conditional Access named locations.
 65- If legacy auth was used: create CA policy blocking legacy authentication.
 66- If MFA wasn't required: review CA policy coverage for gaps.
 67- Document affected users for credential reset and monitoring.
 68"""
 69references = [
 70    "https://www.microsoft.com/en-us/security/blog/2025/05/27/new-russia-affiliated-actor-void-blizzard-targets-critical-sectors-for-espionage/",
 71    "https://cloud.hacktricks.xyz/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-password-spraying",
 72    "https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray",
 73    "https://www.sprocketsecurity.com/blog/exploring-modern-password-spraying",
 74    "https://learn.microsoft.com/en-us/purview/audit-log-detailed-properties",
 75    "https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes",
 76    "https://github.com/0xZDH/Omnispray",
 77    "https://github.com/0xZDH/o365spray",
 78]
 79risk_score = 73
 80rule_id = "2d6f5332-42ea-11f0-b09a-f661ea17fbcd"
 81severity = "high"
 82tags = [
 83    "Domain: Cloud",
 84    "Domain: Identity",
 85    "Data Source: Azure",
 86    "Data Source: Entra ID",
 87    "Data Source: Entra ID Sign-in Logs",
 88    "Use Case: Identity and Access Audit",
 89    "Use Case: Threat Detection",
 90    "Tactic: Credential Access",
 91    "Resources: Investigation Guide",
 92]
 93timestamp_override = "event.ingested"
 94type = "threshold"
 95
 96query = '''
 97event.dataset: "azure.signinlogs" and event.category: "authentication"
 98    and azure.signinlogs.category: ("NonInteractiveUserSignInLogs" or "SignInLogs")
 99    and event.outcome: "failure"
100    and azure.signinlogs.properties.authentication_requirement: "singleFactorAuthentication"
101    and azure.signinlogs.properties.status.error_code: 50053
102    and azure.signinlogs.properties.user_principal_name: (* and not "")
103    and not source.as.organization.name: "MICROSOFT-CORP-MSN-as-BLOCK"
104    and not source.ip: ("10.0.0.0/8" or "172.16.0.0/12" or "192.168.0.0/16" or "127.0.0.0/8" or "::1/128" or "fd00::/8")
105'''
106
107
108[[rule.threat]]
109framework = "MITRE ATT&CK"
110[[rule.threat.technique]]
111id = "T1110"
112name = "Brute Force"
113reference = "https://attack.mitre.org/techniques/T1110/"
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.technique.subtechnique]]
125id = "T1110.004"
126name = "Credential Stuffing"
127reference = "https://attack.mitre.org/techniques/T1110/004/"
128
129
130
131[rule.threat.tactic]
132id = "TA0006"
133name = "Credential Access"
134reference = "https://attack.mitre.org/tactics/TA0006/"
135
136[rule.threshold]
137field = []
138value = 30
139[[rule.threshold.cardinality]]
140field = "user.name"
141value = 25

Triage and analysis

Investigating Entra ID Excessive Account Lockouts Detected

This rule detects a high number of sign-in failures due to account lockouts (error code 50053) in Microsoft Entra ID sign-in logs. These lockouts are typically caused by repeated authentication failures, often as a result of brute-force tactics such as password spraying, credential stuffing, or automated guessing. This detection is time-bucketed and aggregates attempts to identify bursts or coordinated campaigns targeting multiple users. Error code 50053 indicates Entra ID Smart Lockout, which is IP-based and tracks "unfamiliar" vs "familiar" locations. Familiar IPs have a higher threshold before lockout, so if lockouts are occurring, the source IP was unfamiliar to those accounts.

Possible investigation steps

  • This is a threshold rule that aggregates events, so the alert document won't contain individual sign-in attempts. Pivot to the raw logs in Discover or Timeline using: event.dataset: "azure.signinlogs" and azure.signinlogs.properties.status.error_code: 50053. Match the time range to the alert window (rule lookback is 30 minutes).
  • Add relevant columns: @timestamp, user.name, source.ip, user_agent.original, azure.signinlogs.properties.app_display_name, azure.signinlogs.properties.client_app_used, source.as.organization.name, geo.country_iso_code, azure.signinlogs.properties.authentication_details.
  • Aggregate by source.ip and user.name to identify the attack pattern: password spray (single/small set of IPs targeting many accounts), credential stuffing (many source IPs, may target specific users with leaked credentials), targeted brute force (focused on single high-value account), or misconfigured service (single source IP with consistent user-agent matching legitimate application).
  • Analyze user_agent.original for indicators of automation. Values like curl/*, python-requests/*, Go-http-client/*, axios/* indicate scripted attacks. BAV2ROPC indicates Resource Owner Password Credential flow (legacy auth), commonly abused by spray tools like o365spray and MSOLSpray.
  • Review azure.signinlogs.properties.client_app_used. Other clients indicates legacy auth (IMAP, SMTP, POP) which is high-risk. Exchange ActiveSync is legacy auth often targeted.
  • Check azure.signinlogs.properties.authentication_protocol for ropc (Resource Owner Password Credential), a legacy flow where credentials are sent directly with no MFA interruption possible.
  • Review source.as.organization.name. Cloud hosting providers (DigitalOcean, Vultr, Linode, AWS, Azure, GCP) or VPN providers (NordVPN, ExpressVPN, Mullvad) are high-risk as attackers use this infrastructure.
  • Check azure.signinlogs.properties.conditional_access_status. notApplied means no CA policy evaluated, indicating a coverage gap. failure means CA policy blocked the sign-in.
  • Determine if any accounts were compromised. Query for successful sign-ins from attacking infrastructure: event.dataset: "azure.signinlogs" and event.outcome: "success" and source.ip: "<attacker_ip>". Also query for successful sign-ins for affected users from any source during the attack window.
  • Check for MFA bypass: event.dataset: "azure.signinlogs" and event.outcome: "success" and azure.signinlogs.properties.authentication_requirement: "singleFactorAuthentication" and source.ip: "<attacker_ip>"
  • Review Entra ID Protection risk events for affected users by checking risk_level_during_signin, risk_level_aggregated, and risk_state for values other than none.
  • Check for username enumeration preceding the spray. Error code 50034 (user not found) indicates enumeration: event.dataset: "azure.signinlogs" and azure.signinlogs.properties.status.error_code: 50034 and source.ip: "<attacker_ip>"
  • Query for other error codes from the same source: 50126 (invalid password), 50034 (user not found), 50057 (account disabled), 50055 (password expired), 53003 (blocked by CA), 50158 (MFA challenge not satisfied). A mix of 50126 and 50053 confirms password guessing.

False positive analysis

  • Misconfigured clients, scripts, or services with outdated credentials may inadvertently cause lockouts.
  • Lockouts during credential rotation windows could be benign.
  • Legacy applications without modern auth support may repeatedly fail and trigger Smart Lockout.
  • Specific known user agents from corporate service accounts.
  • Cloud-hosted automation with expected failure behavior.
  • This rule can be customized. Adjust the threshold and/or interval/lookback window based on baselining efforts. Specific UPNs can be excluded if they generate known false positives.

Response and remediation

  • Confirm no successful authentications from attacking source.
  • Query for successful sign-ins to affected users from any source during the attack window.
  • If compromise confirmed: disable account, revoke refresh tokens (Revoke-AzureADUserAllRefreshToken or via portal), reset password, require MFA re-registration.
  • Block source IP/ASN via Conditional Access named locations.
  • If legacy auth was used: create CA policy blocking legacy authentication.
  • If MFA wasn't required: review CA policy coverage for gaps.
  • Document affected users for credential reset and monitoring.

References

Related rules

to-top