Microsoft Entra ID MFA TOTP Brute Force Attempts

Identifies brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password (TOTP) verification codes. This rule detects high frequency failed TOTP code attempts for a single user in a short time-span with a high number of distinct session IDs. Adversaries may programmatically attemopt to brute-force TOTP codes by generating several sessions and attempt to guess the correct code.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2024/12/11"
  3integration = ["azure"]
  4maturity = "production"
  5updated_date = "2025/07/31"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Identifies brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password
 11(TOTP) verification codes. This rule detects high frequency failed TOTP code attempts for a single user in a short
 12time-span with a high number of distinct session IDs. Adversaries may programmatically attemopt to brute-force TOTP
 13codes by generating several sessions and attempt to guess the correct code.
 14"""
 15false_positives = [
 16    """
 17    Based on the high-frequency threshold, it would be unlikely for a legitimate user to exceed the threshold for failed
 18    TOTP code attempts in a short time-span over multiple sessions.
 19    """,
 20]
 21from = "now-9m"
 22language = "esql"
 23license = "Elastic License v2"
 24name = "Microsoft Entra ID MFA TOTP Brute Force Attempts"
 25note = """## Triage and analysis
 26
 27### Investigating Microsoft Entra ID MFA TOTP Brute Force Attempts
 28
 29This rule detects brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password (TOTP) verification codes. It identifies high-frequency failed TOTP code attempts for a single user in a short time-span with a high number of distinct session IDs. Adversaries may programmatically attempt to brute-force TOTP codes by generating several sessions and attempting to guess the correct code.
 30
 31#### Possible Investigation Steps:
 32
 33    - Check the source addresses associated with the failed TOTP attempts.
 34    - Determine if the source IP address is consistent with the user’s typical login locations.
 35    - Look for unusual geographic patterns or anomalous IP addresses (e.g., proxies, VPNs, or locations outside the user’s normal activity).
 36    - Review the error code associated with the failed attempts. This can help identify if the failures are due to incorrect TOTP codes or other issues.
 37    - Verify that that auth metho reported is `OAth` as it indicates the use of TOTP codes.
 38    - Pivot into signin logs for the target user and check if auth via TOTP was successful which would indicate a successful brute force attempt.
 39    - Review conditional access policies applied to the user or group as reported by the sign-in logs.
 40    - Analyze the client application ID and display name to determine if the attempts are coming from a legitimate application or a potentially malicious script.
 41        - Adversaries may use legitimate FOCI applications to bypass security controls or make login attempts appear legitimate.
 42    - Review the resource ID access is being attempted against such as MyApps, Microsoft Graph, or other resources. This can help identify if the attempts are targeting specific applications or services.
 43    - The correlation IDs or session IDs can be used to trace the authentication attempts across different logs or systems. Note that for this specific behavior, unique session ID count is high and could be challenging to correlate.
 44
 45#### False Positive Analysis:
 46
 47    - Verify if the failed attempts could result from the user’s unfamiliarity with TOTP codes or issues with device synchronization.
 48    - Check if the user recently switched MFA methods or devices, which could explain multiple failures.
 49    - Determine if this is whitebox testing or a developer testing MFA integration.
 50
 51#### Response and Remediation:
 52
 53    - If proven malicious, lock the affected account temporarily to prevent further unauthorized attempts.
 54    - Notify the user of suspicious activity and validate their access to the account.
 55    - Reset passwords and MFA settings for the affected user to prevent unauthorized access while communicating with the user.
 56    - Ensure conditional access policies are configured to monitor and restrict anomalous login behavior.
 57    - Consider a different MFA method or additional security controls to prevent future bypass attempts.
 58    - Implement additional monitoring to track high-frequency authentication failures across the environment.
 59    - Audit historical logs for similar patterns involving other accounts to identify broader threats.
 60    - Provide guidance on the secure use of MFA and the importance of recognizing and reporting suspicious activity.
 61"""
 62references = [
 63    "https://www.oasis.security/resources/blog/oasis-security-research-team-discovers-microsoft-azure-mfa-bypass",
 64    "https://learn.microsoft.com/en-us/entra/identity/",
 65    "https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-ins",
 66]
 67risk_score = 47
 68rule_id = "3fac01b2-b811-11ef-b25b-f661ea17fbce"
 69setup = """#### Required Entra ID Sign-In Logs
 70This rule requires the Entra ID sign-in logs via the Azure integration be enabled. In Entra ID, sign-in logs must be enabled and streaming to the Event Hub used for the Entra ID logs integration.
 71"""
 72severity = "medium"
 73tags = [
 74    "Domain: Cloud",
 75    "Domain: Identity",
 76    "Data Source: Azure",
 77    "Data Source: Entra ID",
 78    "Data Source: Entra ID Sign-in logs",
 79    "Use Case: Identity and Access Audit",
 80    "Use Case: Threat Detection",
 81    "Tactic: Credential Access",
 82    "Resources: Investigation Guide",
 83]
 84timestamp_override = "event.ingested"
 85type = "esql"
 86
 87query = '''
 88from logs-azure.signinlogs* metadata _id, _version, _index
 89
 90| where
 91    // filter for Entra Sign-in Logs
 92    event.dataset == "azure.signinlogs"
 93    and azure.signinlogs.operation_name == "Sign-in activity"
 94    and azure.signinlogs.properties.user_type == "Member"
 95
 96    // filter for MFA attempts with OATH conditional access attempts or TOTP
 97    and azure.signinlogs.properties.mfa_detail.auth_method == "OATH verification code"
 98
 99    // filter on failures only from brute-force attempts
100    and (
101            (
102                azure.signinlogs.result_signature == "FAILURE" and
103                azure.signinlogs.result_description == "Authentication failed during strong authentication request."
104            ) or azure.signinlogs.properties.status.error_code == 500121
105        )
106
107| stats
108    Esql.event_count = count(*),
109    Esql.azure_signinlogs_properties_session_id_count_distinct = count_distinct(azure.signinlogs.properties.session_id),
110    Esql.source_address_values = values(source.address),
111    Esql.azure_tenant_id_valuues = values(azure.tenant_id),
112    Esql_priv.azure_identity_values = values(azure.signinlogs.identity),
113    Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name),
114    Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id),
115    Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
116    Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement),
117    Esql.azure_signinlogs_properties_authentication_protocol_values = values(azure.signinlogs.properties.authentication_protocol),
118    Esql.azure_signinlogs_properties_client_app_used_values = values(azure.signinlogs.properties.client_app_used),
119    Esql.azure_signinlogs_properties_client_credential_type_values = values(azure.signinlogs.properties.client_credential_type),
120    Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status),
121    Esql.azure_signinlogs_properties_correlation_id_values = values(azure.signinlogs.properties.correlation_id),
122    Esql.azure_signinlogs_properties_is_interactive_values = values(azure.signinlogs.properties.is_interactive),
123    Esql.azure_signinlogs_properties_mfa_detail_auth_method_values = values(azure.signinlogs.properties.mfa_detail.auth_method),
124    Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
125    Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id),
126    Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state),
127    Esql.azure_signinlogs_properties_risk_detail_values = values(azure.signinlogs.properties.risk_detail),
128    Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code),
129    Esql.azure_signinlogs_properties_original_request_id_values = values(azure.signinlogs.properties.original_request_id),
130    Esql.user_id_values = values(user.id)
131    by user.id
132
133| where Esql.event_count >= 20 and Esql.azure_signinlogs_properties_session_id_count_distinct >= 10
134
135| keep
136    Esql.event_count,
137    Esql.azure_signinlogs_properties_session_id_count_distinct,
138    Esql.source_address_values,
139    Esql.azure_tenant_id_valuues,
140    Esql_priv.azure_identity_values,
141    Esql_priv.azure_signinlogs_properties_user_principal_name_values,
142    Esql.azure_signinlogs_properties_app_id_values,
143    Esql.azure_signinlogs_properties_app_display_name_values,
144    Esql.azure_signinlogs_properties_authentication_requirement_values,
145    Esql.azure_signinlogs_properties_authentication_protocol_values,
146    Esql.azure_signinlogs_properties_client_app_used_values,
147    Esql.azure_signinlogs_properties_client_credential_type_values,
148    Esql.azure_signinlogs_properties_conditional_access_status_values,
149    Esql.azure_signinlogs_properties_correlation_id_values,
150    Esql.azure_signinlogs_properties_is_interactive_values,
151    Esql.azure_signinlogs_properties_mfa_detail_auth_method_values,
152    Esql.azure_signinlogs_properties_resource_display_name_values,
153    Esql.azure_signinlogs_properties_resource_id_values,
154    Esql.azure_signinlogs_properties_risk_state_values,
155    Esql.azure_signinlogs_properties_risk_detail_values,
156    Esql.azure_signinlogs_properties_status_error_code_values,
157    Esql.azure_signinlogs_properties_original_request_id_values,
158    Esql.user_id_values
159'''
160
161
162[[rule.threat]]
163framework = "MITRE ATT&CK"
164[[rule.threat.technique]]
165id = "T1110"
166name = "Brute Force"
167reference = "https://attack.mitre.org/techniques/T1110/"
168[[rule.threat.technique.subtechnique]]
169id = "T1110.001"
170name = "Password Guessing"
171reference = "https://attack.mitre.org/techniques/T1110/001/"
172
173
174
175[rule.threat.tactic]
176id = "TA0006"
177name = "Credential Access"
178reference = "https://attack.mitre.org/tactics/TA0006/"

Triage and analysis

Investigating Microsoft Entra ID MFA TOTP Brute Force Attempts

This rule detects brute force attempts against Azure Entra multi-factor authentication (MFA) Time-based One-Time Password (TOTP) verification codes. It identifies high-frequency failed TOTP code attempts for a single user in a short time-span with a high number of distinct session IDs. Adversaries may programmatically attempt to brute-force TOTP codes by generating several sessions and attempting to guess the correct code.

Possible Investigation Steps:

- Check the source addresses associated with the failed TOTP attempts.
- Determine if the source IP address is consistent with the user’s typical login locations.
- Look for unusual geographic patterns or anomalous IP addresses (e.g., proxies, VPNs, or locations outside the user’s normal activity).
- Review the error code associated with the failed attempts. This can help identify if the failures are due to incorrect TOTP codes or other issues.
- Verify that that auth metho reported is `OAth` as it indicates the use of TOTP codes.
- Pivot into signin logs for the target user and check if auth via TOTP was successful which would indicate a successful brute force attempt.
- Review conditional access policies applied to the user or group as reported by the sign-in logs.
- Analyze the client application ID and display name to determine if the attempts are coming from a legitimate application or a potentially malicious script.
    - Adversaries may use legitimate FOCI applications to bypass security controls or make login attempts appear legitimate.
- Review the resource ID access is being attempted against such as MyApps, Microsoft Graph, or other resources. This can help identify if the attempts are targeting specific applications or services.
- The correlation IDs or session IDs can be used to trace the authentication attempts across different logs or systems. Note that for this specific behavior, unique session ID count is high and could be challenging to correlate.

False Positive Analysis:

- Verify if the failed attempts could result from the user’s unfamiliarity with TOTP codes or issues with device synchronization.
- Check if the user recently switched MFA methods or devices, which could explain multiple failures.
- Determine if this is whitebox testing or a developer testing MFA integration.

Response and Remediation:

- If proven malicious, lock the affected account temporarily to prevent further unauthorized attempts.
- Notify the user of suspicious activity and validate their access to the account.
- Reset passwords and MFA settings for the affected user to prevent unauthorized access while communicating with the user.
- Ensure conditional access policies are configured to monitor and restrict anomalous login behavior.
- Consider a different MFA method or additional security controls to prevent future bypass attempts.
- Implement additional monitoring to track high-frequency authentication failures across the environment.
- Audit historical logs for similar patterns involving other accounts to identify broader threats.
- Provide guidance on the secure use of MFA and the importance of recognizing and reporting suspicious activity.

References

Related rules

to-top