Attempts to Brute Force a Microsoft 365 User Account
Elastic Stack Serverless Security
Identifies potential brute-force attempts against Microsoft 365 user accounts by detecting a high number of failed login attempts or login sources within a 30-minute window. Attackers may attempt to brute force user accounts to gain unauthorized access to Microsoft 365 services.
Rule type: esql
Rule indices: None
Severity: medium
Risk score: 47
Runs every: 5m
Searches indices from: now-9m (https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math[Date Math format], see also Additional look-back time
)
Maximum alerts per execution: 100
References:
- https://blueteamblog.com/7-ways-to-monitor-your-office-365-logs-using-siem
- https://learn.microsoft.com/en-us/purview/audit-log-detailed-properties
Tags:
- Domain: Cloud
- Domain: SaaS
- Data Source: Microsoft 365
- Use Case: Identity and Access Audit
- Use Case: Threat Detection
- Tactic: Credential Access
- Resources: Investigation Guide
Version: 312
Rule authors:
- Elastic
- Willem D’Haese
- Austin Songer
Rule license: Elastic License v2
Triage and analysis
[TBC: QUOTE]
Investigating Attempts to Brute Force a Microsoft 365 User Account
Microsoft 365 is a cloud-based service that provides productivity tools and services. Adversaries may attempt to gain unauthorized access by brute-forcing user accounts, exploiting weak passwords. The detection rule identifies such attempts by analyzing audit logs for numerous failed logins or diverse login sources within a short timeframe, indicating potential brute-force activity.
Possible investigation steps
- Review the audit logs for the specific user identified by o365.audit.UserId to gather additional context on the failed login attempts, including timestamps and source IP addresses.
- Analyze the source.ip field to identify any unusual or suspicious IP addresses, such as those originating from unexpected geographic locations or known malicious sources.
- Check the o365.audit.LogonError field for any patterns or specific errors that might provide insight into the nature of the failed login attempts.
- Investigate the o365.audit.ExtendedProperties.RequestType to determine if the login attempts were consistent with typical user behavior or if they suggest automated or scripted activity.
- Correlate the findings with other security events or alerts in the environment to assess if the brute-force attempts are part of a larger attack campaign or isolated incidents.
- Contact the affected user to verify if they experienced any issues accessing their account and to ensure they are aware of the potential security threat.
False positive analysis
- High volume of legitimate login attempts from a single user can trigger false positives, especially during password resets or account recovery. To mitigate, consider excluding specific users or IP ranges known for such activities.
- Automated scripts or applications performing frequent logins for legitimate purposes may be misidentified as brute-force attempts. Identify and whitelist these scripts or applications by their user IDs or IP addresses.
- Users traveling or using VPNs may log in from multiple locations in a short period, leading to false positives. Implement geolocation-based exceptions for known travel patterns or VPN IP addresses.
- Shared accounts accessed by multiple users from different locations can appear as multiple login sources. Limit monitoring on shared accounts or establish a baseline of expected behavior to differentiate between normal and suspicious activity.
- Temporary spikes in login attempts due to system maintenance or updates can be mistaken for brute-force attacks. Schedule monitoring exclusions during planned maintenance windows to avoid false alerts.
Response and remediation
- Immediately isolate the affected user account by disabling it to prevent further unauthorized access attempts.
- Notify the user and relevant IT security personnel about the potential compromise and provide guidance on secure password creation.
- Conduct a password reset for the affected user account, ensuring the new password adheres to strong password policies.
- Review and analyze the source IP addresses involved in the failed login attempts to identify any patterns or known malicious sources.
- Implement conditional access policies to restrict login attempts from suspicious or untrusted locations and devices.
- Monitor the affected account and related accounts for any unusual activity or further unauthorized access attempts.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional accounts or systems are affected.
from logs-o365.audit-*
// truncate the timestamp to a 30-minute window
| eval target_time_window = DATE_TRUNC(30 minutes, @timestamp)
| mv_expand event.category
| where event.dataset == "o365.audit"
and event.category == "authentication"
// filter only on Entra ID or Exchange audit logs in O365 integration
and event.provider in ("AzureActiveDirectory", "Exchange")
// filter only for UserLoginFailed or partial failures
and event.action in ("UserLoginFailed", "PasswordLogonInitialAuthUsingPassword")
// ignore specific logon errors
and not o365.audit.LogonError in (
"EntitlementGrantsNotFound",
"UserStrongAuthEnrollmentRequired",
"UserStrongAuthClientAuthNRequired",
"InvalidReplyTo",
"SsoArtifactExpiredDueToConditionalAccess",
"PasswordResetRegistrationRequiredInterrupt",
"SsoUserAccountNotFoundInResourceTenant",
"UserStrongAuthExpired",
"CmsiInterrupt"
)
// ignore unavailable
and o365.audit.UserId != "Not Available"
// filters out non user or application logins based on target
and o365.audit.Target.Type in ("0", "2", "3", "5", "6", "10")
// filters only for logins from user or application, ignoring oauth:token
and to_lower(o365.audit.ExtendedProperties.RequestType) rlike "(.*)login(.*)"
// keep only relevant fields
| keep event.provider, event.dataset, event.category, o365.audit.UserId, event.action, source.ip, o365.audit.LogonError, o365.audit.ExtendedProperties.RequestType, o365.audit.Target.Type, target_time_window
// count the number of login sources and failed login attempts
| stats
login_source_count = count(source.ip),
failed_login_count = count(*) by target_time_window, o365.audit.UserId
// filter for users with more than 20 login sources or failed login attempts
| where (login_source_count >= 20 or failed_login_count >= 20)
Framework: MITRE ATT&CKTM
Tactic:
- Name: Credential Access
- ID: TA0006
- Reference URL: https://attack.mitre.org/tactics/TA0006/
Technique:
- Name: Brute Force
- ID: T1110
- Reference URL: https://attack.mitre.org/techniques/T1110/