Skip to content

Commit 7c4f334

Browse files
[New Hunt] Adding Hunting Queries for Azure Entra Sign-In Anomalies (#4527)
* adding new hunts for Azure entra sign-in anomalies * fixing commented query logic; added hydra user agent
1 parent 4deb6a7 commit 7c4f334

8 files changed

+440
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Azure Entra Unusual Failed Authentication Attempts Behind Rare User Agents
2+
3+
---
4+
5+
## Metadata
6+
7+
- **Author:** Elastic
8+
- **Description:** This hunting query gathers evidence of failed authentication attempts in Azure Entra ID where unusual user agents are used. Adversaries may use tools like FastHTTP to conduct brute force attacks against Azure Entra ID user accounts. FastHTTP is a high-performance HTTP client optimized for speed and efficiency, making it a popular choice for password spraying attacks. By identifying failed authentication attempts behind rare user agents, security teams can detect and respond to unauthorized access attempts in Azure Entra ID.
9+
10+
- **UUID:** `3f26f262-fe14-11ef-9ee5-f661ea17fbcd`
11+
- **Integration:** [azure](https://docs.elastic.co/integrations/azure)
12+
- **Language:** `[ES|QL]`
13+
- **Source File:** [Azure Entra Unusual Failed Authentication Attempts Behind Rare User Agents](../queries/entra_authentication_attempts_behind_rare_user_agents.toml)
14+
15+
## Query
16+
17+
```sql
18+
from logs-azure.signinlogs*
19+
| where @timestamp > now() - 14 day
20+
| keep
21+
@timestamp,
22+
event.dataset,
23+
event.category,
24+
azure.signinlogs.properties.authentication_requirement,
25+
azure.signinlogs.properties.status.error_code,
26+
azure.signinlogs.properties.app_id,
27+
source.as.organization.name,
28+
user_agent.original,
29+
azure.signinlogs.category,
30+
event.outcome,
31+
azure.signinlogs.properties.user_principal_name,
32+
source.ip
33+
| WHERE
34+
event.dataset == "azure.signinlogs"
35+
and event.category == "authentication"
36+
and source.as.organization.name != "MICROSOFT-CORP-MSN-AS-BLOCK"
37+
and event.outcome != "success"
38+
and azure.signinlogs.properties.status.error_code in (50053, 50126, 50055, 50056, 50064, 50144)
39+
and (
40+
to_lower(user_agent.original) LIKE "%go-http-client/1.1%" or
41+
to_lower(user_agent.original) LIKE "%fasthttp%" or
42+
to_lower(user_agent.original) LIKE "%python%" or
43+
to_lower(user_agent.original) LIKE "%curl%" or
44+
to_lower(user_agent.original) LIKE "%wget%" or
45+
to_lower(user_agent.original) LIKE "%httpclient%" or
46+
to_lower(user_agent.original) LIKE "%postmanruntime%" or
47+
to_lower(user_agent.original) LIKE "%headlesschrome%" or
48+
to_lower(user_agent.original) LIKE "%phantomjs%" or
49+
to_lower(user_agent.original) LIKE "%selenium%" or
50+
to_lower(user_agent.original) LIKE "%okhttp%" or
51+
to_lower(user_agent.original) LIKE "%scrapy%" or
52+
to_lower(user_agent.original) LIKE "%hydra%" or
53+
to_lower(user_agent.original) LIKE "%patator%" or
54+
to_lower(user_agent.original) LIKE "%metasploit%" or
55+
to_lower(user_agent.original) LIKE "%curio%" or
56+
to_lower(user_agent.original) LIKE "%hyper%" or
57+
to_lower(user_agent.original) LIKE "%kali%" or
58+
to_lower(user_agent.original) LIKE "%hydra%" or
59+
)
60+
// count the number of unique user login attempts
61+
| stats
62+
unique_user_app_login_count = count(*) by
63+
azure.signinlogs.properties.user_principal_name,
64+
azure.signinlogs.properties.authentication_requirement,
65+
azure.signinlogs.properties.app_id
66+
| sort unique_user_app_login_count asc
67+
```
68+
69+
## Notes
70+
71+
- Review `azure.signinlogs.properties.authentication_protocol` to verify the authentication method used. Non-interactive SFA is typically reserved for automated processes or legacy authentication methods.
72+
- Review `azure.signinlogs.properties.error_code` to identify the specific error codes associated with the failed authentication attempts. Common error codes include `50053` for account lockouts, `50126` for invalid credentials, and `50055` for expired passwords.
73+
- Investigate `azure.signinlogs.properties.user_principal_name` to determine whether the user typically authenticates using SFA. Unusual use by regular accounts may indicate compromise.
74+
- Analyze `source.as.organization.name` to determine if the request originated from a known hosting provider, VPN, or anonymization service that is unexpected in your environment.
75+
- Examine `source.address` to check if the IP address is associated with previous suspicious activity, high-risk geolocations, or known threat infrastructure.
76+
- Pivot on `azure.signinlogs.properties.user_principal_name` to identify any other high-risk activities within the same session.
77+
- Correlate findings with `azure.signinlogs.properties.authentication_processing_details` to identify possible legacy protocol usage, token replay, permission scopes or bypass mechanisms.
78+
- Review `user_agent.original` to identify the user agent used in the authentication request. Determine if this user agent is expected in your environment or if it is associated with known malicious activity.
79+
80+
## MITRE ATT&CK Techniques
81+
82+
- [T1078.004](https://attack.mitre.org/techniques/T1078/004)
83+
- [T1110.003](https://attack.mitre.org/techniques/T1110/003)
84+
85+
## References
86+
87+
- https://securityscorecard.com/wp-content/uploads/2025/02/MassiveBotnet-Report_022125_03.pdf
88+
89+
## License
90+
91+
- `Elastic License v2`
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Azure Entra Excessive Single-Factor Non-Interactive Sign-Ins
2+
3+
---
4+
5+
## Metadata
6+
7+
- **Author:** Elastic
8+
- **Description:** This hunting query gathers evidence of password spraying attempts against Azure Entra ID user accounts by detecting a high number of failed non-interactive single-factor authentication (SFA) login attempts within a 10-minute window. Attackers may attempt to brute force user accounts to gain unauthorized access to Azure Entra ID services or validate compromised credentials. Non-interactive SFA login attempts bypass conditional-access policies (CAP) and multi-factor authentication (MFA) requirements, making them a high-risk vector for unauthorized access. Adversaries may attempt this to identify which accounts are still valid from acquired credentials via phishing, infostealers, or other means.
9+
10+
- **UUID:** `a9281116-fde0-11ef-9ee5-f661ea17fbcd`
11+
- **Integration:** [azure](https://docs.elastic.co/integrations/azure)
12+
- **Language:** `[ES|QL]`
13+
- **Source File:** [Azure Entra Excessive Single-Factor Non-Interactive Sign-Ins](../queries/entra_excessive_non_interactive_sfa_sign_ins_across_users.toml)
14+
15+
## Query
16+
17+
```sql
18+
from logs-azure.signinlogs*
19+
| where @timestamp > now() - 14 day
20+
| keep
21+
@timestamp,
22+
event.dataset,
23+
event.category,
24+
azure.signinlogs.properties.is_interactive,
25+
azure.signinlogs.properties.authentication_requirement,
26+
azure.signinlogs.properties.resource_display_name,
27+
azure.signinlogs.properties.status.error_code,
28+
source.as.organization.name,
29+
azure.signinlogs.category,
30+
event.outcome,
31+
azure.signinlogs.properties.user_principal_name,
32+
source.ip
33+
// truncate the timestamp to a 10-minute window
34+
| eval target_time_window = DATE_TRUNC(10 minutes, @timestamp)
35+
| WHERE
36+
event.dataset == "azure.signinlogs"
37+
and event.category == "authentication"
38+
and azure.signinlogs.properties.is_interactive == false
39+
and azure.signinlogs.properties.authentication_requirement == "singleFactorAuthentication"
40+
and source.as.organization.name != "MICROSOFT-CORP-MSN-AS-BLOCK"
41+
and event.outcome != "success"
42+
and azure.signinlogs.properties.status.error_code in (50053, 50126, 50055, 50056, 50064, 50144)
43+
// count the number of unique user login attempts
44+
| stats
45+
unique_user_login_count = count_distinct(azure.signinlogs.properties.user_principal_name) by target_time_window, azure.signinlogs.properties.status.error_code
46+
// filter for >= 30 failed SFA auth attempts with the same error codes
47+
| where unique_user_login_count >= 30
48+
```
49+
50+
## Notes
51+
52+
- Review `azure.signinlogs.properties.authentication_protocol` to verify the authentication method used. Non-interactive SFA is typically reserved for automated processes or legacy authentication methods.
53+
- Review `azure.signinlogs.properties.error_code` to identify the specific error codes associated with the failed authentication attempts. Common error codes include `50053` for account lockouts, `50126` for invalid credentials, and `50055` for expired passwords.
54+
- Investigate `azure.signinlogs.properties.user_principal_name` to determine whether the user typically authenticates using SFA. Unusual use by regular accounts may indicate compromise.
55+
- Analyze `source.as.organization.name` to determine if the request originated from a known hosting provider, VPN, or anonymization service that is unexpected in your environment.
56+
- Examine `source.address` to check if the IP address is associated with previous suspicious activity, high-risk geolocations, or known threat infrastructure.
57+
- Pivot on `azure.signinlogs.properties.user_principal_name` to identify any other high-risk activities within the same session.
58+
- Correlate findings with `azure.signinlogs.properties.authentication_processing_details` to identify possible legacy protocol usage, token replay, permission scopes or bypass mechanisms.
59+
60+
## MITRE ATT&CK Techniques
61+
62+
- [T1078.004](https://attack.mitre.org/techniques/T1078/004)
63+
- [T1110.003](https://attack.mitre.org/techniques/T1110/003)
64+
65+
## References
66+
67+
- https://securityscorecard.com/wp-content/uploads/2025/02/MassiveBotnet-Report_022125_03.pdf
68+
69+
## License
70+
71+
- `Elastic License v2`
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Azure Entra Unusual Client App Authentication Requests on Behalf of Principal Users
2+
3+
---
4+
5+
## Metadata
6+
7+
- **Author:** Elastic
8+
- **Description:** This hunting query gathers evidence of Azure Entra sign-in attempts on-behalf-of a user with an unusual client app. During brute-forcing attempts, adversaries may use a custom or Azure-managed app ID to authenticate on-behalf-of a user. This is a rare event and may indicate an attempt to bypass conditional access policies (CAP) and multi-factor authentication (MFA) requirements. The app ID specified may not be commonly used by the user based on their historical sign-in activity.
9+
10+
- **UUID:** `ce47ec2c-fe13-11ef-9ee5-f661ea17fbcd`
11+
- **Integration:** [azure](https://docs.elastic.co/integrations/azure)
12+
- **Language:** `[ES|QL]`
13+
- **Source File:** [Azure Entra Unusual Client App Authentication Requests on Behalf of Principal Users](../queries/entra_unusual_client_app_auth_request_on_behalf_of_user.toml)
14+
15+
## Query
16+
17+
```sql
18+
from logs-azure.signinlogs*
19+
| where @timestamp > now() - 14 day
20+
| keep
21+
@timestamp,
22+
event.dataset,
23+
event.category,
24+
azure.signinlogs.properties.app_display_name,
25+
azure.signinlogs.properties.app_id,
26+
azure.signinlogs.properties.user_principal_name,
27+
azure.signinlogs.properties.status.error_code,
28+
azure.signinlogs.category,
29+
source.as.organization.name,
30+
event.outcome,
31+
source.ip
32+
| WHERE
33+
// filter for failed sign-in logs related to invalid username or password
34+
event.dataset == "azure.signinlogs"
35+
and event.category == "authentication"
36+
and event.outcome != "success"
37+
and azure.signinlogs.properties.status.error_code in (50053, 50126, 50055, 50056, 50064, 50144)
38+
and source.as.organization.name != "MICROSOFT-CORP-MSN-AS-BLOCK"
39+
// aggregate the number of failed sign-in attempts by user and app ID reported
40+
| stats
41+
auth_via_app_count = count(*) by
42+
azure.signinlogs.properties.user_principal_name,
43+
azure.signinlogs.properties.app_display_name,
44+
azure.signinlogs.properties.app_id
45+
// filter for users with less than or equal to 3 failed sign-in attempts per app
46+
| where auth_via_app_count <= 3
47+
| sort auth_via_app_count asc
48+
```
49+
50+
## Notes
51+
52+
- Review `azure.signinlogs.properties.authentication_protocol` to verify the authentication method used. Non-interactive SFA is typically reserved for automated processes or legacy authentication methods.
53+
- Review `azure.signinlogs.properties.error_code` to identify the specific error codes associated with the failed authentication attempts. Common error codes include `50053` for account lockouts, `50126` for invalid credentials, and `50055` for expired passwords.
54+
- Investigate `azure.signinlogs.properties.user_principal_name` to determine whether the user typically authenticates using SFA. Unusual use by regular accounts may indicate compromise.
55+
- Analyze `source.as.organization.name` to determine if the request originated from a known hosting provider, VPN, or anonymization service that is unexpected in your environment.
56+
- Examine `source.address` to check if the IP address is associated with previous suspicious activity, high-risk geolocations, or known threat infrastructure.
57+
- Pivot on `azure.signinlogs.properties.user_principal_name` to identify any other high-risk activities within the same session.
58+
- Correlate findings with `azure.signinlogs.properties.authentication_processing_details` to identify possible legacy protocol usage, token replay, permission scopes or bypass mechanisms.
59+
60+
## MITRE ATT&CK Techniques
61+
62+
- [T1078.004](https://attack.mitre.org/techniques/T1078/004)
63+
- [T1110.003](https://attack.mitre.org/techniques/T1110/003)
64+
65+
## References
66+
67+
- https://securityscorecard.com/wp-content/uploads/2025/02/MassiveBotnet-Report_022125_03.pdf
68+
69+
## License
70+
71+
- `Elastic License v2`
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
[hunt]
2+
author = "Elastic"
3+
description = """
4+
This hunting query gathers evidence of failed authentication attempts in Azure Entra ID where unusual user agents are used. Adversaries may use tools like FastHTTP to conduct brute force attacks against Azure Entra ID user accounts. FastHTTP is a high-performance HTTP client optimized for speed and efficiency, making it a popular choice for password spraying attacks. By identifying failed authentication attempts behind rare user agents, security teams can detect and respond to unauthorized access attempts in Azure Entra ID.
5+
"""
6+
integration = ["azure"]
7+
uuid = "3f26f262-fe14-11ef-9ee5-f661ea17fbcd"
8+
name = "Azure Entra Unusual Failed Authentication Attempts Behind Rare User Agents"
9+
language = ["ES|QL"]
10+
license = "Elastic License v2"
11+
notes = [
12+
"Review `azure.signinlogs.properties.authentication_protocol` to verify the authentication method used. Non-interactive SFA is typically reserved for automated processes or legacy authentication methods.",
13+
"Review `azure.signinlogs.properties.error_code` to identify the specific error codes associated with the failed authentication attempts. Common error codes include `50053` for account lockouts, `50126` for invalid credentials, and `50055` for expired passwords.",
14+
"Investigate `azure.signinlogs.properties.user_principal_name` to determine whether the user typically authenticates using SFA. Unusual use by regular accounts may indicate compromise.",
15+
"Analyze `source.as.organization.name` to determine if the request originated from a known hosting provider, VPN, or anonymization service that is unexpected in your environment.",
16+
"Examine `source.address` to check if the IP address is associated with previous suspicious activity, high-risk geolocations, or known threat infrastructure.",
17+
"Pivot on `azure.signinlogs.properties.user_principal_name` to identify any other high-risk activities within the same session.",
18+
"Correlate findings with `azure.signinlogs.properties.authentication_processing_details` to identify possible legacy protocol usage, token replay, permission scopes or bypass mechanisms.",
19+
"Review `user_agent.original` to identify the user agent used in the authentication request. Determine if this user agent is expected in your environment or if it is associated with known malicious activity.",
20+
]
21+
mitre = ['T1078.004','T1110.003']
22+
references = ["https://securityscorecard.com/wp-content/uploads/2025/02/MassiveBotnet-Report_022125_03.pdf"]
23+
query = [
24+
'''
25+
from logs-azure.signinlogs*
26+
| where @timestamp > now() - 14 day
27+
| keep
28+
@timestamp,
29+
event.dataset,
30+
event.category,
31+
azure.signinlogs.properties.authentication_requirement,
32+
azure.signinlogs.properties.status.error_code,
33+
azure.signinlogs.properties.app_id,
34+
source.as.organization.name,
35+
user_agent.original,
36+
azure.signinlogs.category,
37+
event.outcome,
38+
azure.signinlogs.properties.user_principal_name,
39+
source.ip
40+
| WHERE
41+
event.dataset == "azure.signinlogs"
42+
and event.category == "authentication"
43+
and source.as.organization.name != "MICROSOFT-CORP-MSN-AS-BLOCK"
44+
and event.outcome != "success"
45+
and azure.signinlogs.properties.status.error_code in (50053, 50126, 50055, 50056, 50064, 50144)
46+
and (
47+
to_lower(user_agent.original) LIKE "%go-http-client/1.1%" or
48+
to_lower(user_agent.original) LIKE "%fasthttp%" or
49+
to_lower(user_agent.original) LIKE "%python%" or
50+
to_lower(user_agent.original) LIKE "%curl%" or
51+
to_lower(user_agent.original) LIKE "%wget%" or
52+
to_lower(user_agent.original) LIKE "%httpclient%" or
53+
to_lower(user_agent.original) LIKE "%postmanruntime%" or
54+
to_lower(user_agent.original) LIKE "%headlesschrome%" or
55+
to_lower(user_agent.original) LIKE "%phantomjs%" or
56+
to_lower(user_agent.original) LIKE "%selenium%" or
57+
to_lower(user_agent.original) LIKE "%okhttp%" or
58+
to_lower(user_agent.original) LIKE "%scrapy%" or
59+
to_lower(user_agent.original) LIKE "%hydra%" or
60+
to_lower(user_agent.original) LIKE "%patator%" or
61+
to_lower(user_agent.original) LIKE "%metasploit%" or
62+
to_lower(user_agent.original) LIKE "%curio%" or
63+
to_lower(user_agent.original) LIKE "%hyper%" or
64+
to_lower(user_agent.original) LIKE "%kali%" or
65+
to_lower(user_agent.original) LIKE "%hydra%" or
66+
)
67+
// count the number of unique user login attempts
68+
| stats
69+
unique_user_app_login_count = count(*) by
70+
azure.signinlogs.properties.user_principal_name,
71+
azure.signinlogs.properties.authentication_requirement,
72+
azure.signinlogs.properties.app_id
73+
| sort unique_user_app_login_count asc
74+
'''
75+
]

0 commit comments

Comments
 (0)