Skip to content

Commit 1851ab9

Browse files
new hunting queries for Azure device code (#4468)
1 parent 4b7aa67 commit 1851ab9

6 files changed

+332
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Azure Entra Authentication Attempts from Abused Hosting Service Providers
2+
3+
---
4+
5+
## Metadata
6+
7+
- **Author:** Elastic
8+
- **Description:** This hunting query gathers evidence of Azure Entra authentication attempts from hosting service providers that are often abused by adversaries. By identifying authentication attempts from these sources, security teams can detect potential unauthorized access or malicious activities within their Azure environment.
9+
10+
- **UUID:** `d27f1da8-eec6-11ef-983a-f661ea17fbce`
11+
- **Integration:** [azure](https://docs.elastic.co/integrations/azure)
12+
- **Language:** `[ES|QL]`
13+
- **Source File:** [Azure Entra Authentication Attempts from Abused Hosting Service Providers](../queries/entra_authentication_attempts_from_abused_hosting_service_providers.toml)
14+
15+
## Query
16+
17+
```sql
18+
FROM logs-azure.signinlogs-*
19+
20+
// query Azure Entra Sign-in logs
21+
| WHERE @timestamp > now() - 14 day
22+
| WHERE
23+
event.dataset in ("azure.signinlogs") and
24+
25+
// filter for authentication events
26+
event.category == "authentication" and
27+
28+
// filter for specific ASN organizations that are often abused
29+
source.as.organization.name in (
30+
"DigitalOcean", "Linode", "Vultr", "Hetzner", "OVH",
31+
"Contabo", "Leaseweb", "G-Core Labs", "Scaleway", "Kamatera",
32+
"Shinjiru", "M247", "Packet Host", "InterServer", "DataPacket",
33+
"Choopa", "Path Network", "DediPath", "Maxided", "Quasi Networks",
34+
"FlokiNET", "Njalla", "AbeloHost", "Inferno Solutions", "Hostinger",
35+
"Hostwinds", "1&1 IONOS", "DreamHost", "A2 Hosting", "Bluehost",
36+
"Namecheap Hosting", "FastComet", "InMotion Hosting", "SiteGround", "GreenGeeks",
37+
"Liquid Web", "Hurricane Electric", "Ubiquity Hosting", "Snel.com", "Coresite",
38+
"Eonix", "WebNX", "SharkTech", "Hivelocity", "Zenlayer",
39+
"RapidSeedbox", "SeFlow", "Nexeon Technologies", "NextArray", "Zare",
40+
"Clouvider", "TimeWeb", "YISP", "StackPath", "LuxVPS",
41+
"Terrahost", "IP Volume", "RackNerd", "ServerMania", "HostEurope",
42+
"HostHatch", "HostUS", "Cloudsigma", "QuadraNet", "CIV Host",
43+
"Swiftway", "King Servers", "BeeHost", "Webzilla", "Flokinet",
44+
"Alexhost", "DDoS-Guard", "StormWall", "Yokohama Networks", "DataGroup",
45+
"GSL Networks", "MyLoc", "Hostlife", "Reprise Hosting", "GTT Communications",
46+
"Telia", "Cogent Communications", "NForce", "Ecatel", "Novogara",
47+
"CyberBunker", "DarkFiber", "Exoscale", "QHoster", "ServDiscount",
48+
"Krypt", "Wowrack", "XLHost", "OVHCloud", "Privex",
49+
"GreencloudVPS", "RamNode", "BuyVM", "LiteServer", "Host1Plus",
50+
"EdgeUno", "CloudSouth", "IOFlood", "Hostry", "MivoCloud",
51+
"CloudCone", "SwiftNode", "Flaunt7", "Infinitie Networks", "ServerHub",
52+
"Verpex Hosting", "W3Space", "HostPapa", "Storm Internet", "WP Engine",
53+
"Kinsta", "Fly.io", "Edgecast", "RocketNode", "CloudAtCost",
54+
"Gullo's Hosting", "Serverion", "XHostFire", "Interserver", "DediServe",
55+
"HostRound", "VPSServer", "HostMantis", "RapidSwitch", "Tiggee LLC",
56+
"LogicWeb", "VPSCheap", "Versaweb", "SecureDragon", "ServerAstra",
57+
"HostNeverDie", "CloudSigma", "IONOS Cloud", "StackClash", "ProtonVPN",
58+
"NordVPN", "Mullvad VPN", "ExpressVPN", "Surfshark", "Private Internet Access",
59+
"TorGuard", "VyprVPN", "Windscribe VPN", "iVPN", "Perfect Privacy",
60+
"Astrill VPN", "TunnelBear", "CyberGhost VPN", "PureVPN", "Hotspot Shield",
61+
"StrongVPN", "F-Secure VPN", "IVPN", "ZoogVPN", "SwitchVPN",
62+
"AirVPN", "Buffered VPN", "SecureVPN", "RiseupVPN", "Betternet",
63+
"Trust.Zone VPN", "OneVPN", "VeePN", "Speedify VPN", "VPN Unlimited",
64+
"Anonine VPN", "X-VPN", "Hidemyass VPN", "ProXPN", "VPNArea",
65+
"AceVPN", "IPVanish", "Bitmask VPN", "BolehVPN", "AnonVPN",
66+
"Librem One VPN", "BlackVPN", "Cloudflare Warp VPN", "Torguard VPN", "VPN.ht"
67+
)
68+
69+
// aggregate authentication attempts by tenant, user principal name, authentication protocol, category, ASN organization name, and source address
70+
| STATS asn_count = count(*) by
71+
azure.tenant_id,
72+
azure.signinlogs.properties.user_principal_name,
73+
azure.signinlogs.properties.authentication_protocol,
74+
azure.signinlogs.category,
75+
source.as.organization.name,
76+
source.address
77+
```
78+
79+
## Notes
80+
81+
- Review `azure.signinlogs.properties.authentication_protocol` to determine the authentication method used.
82+
- Device Code Flow authentication is particularly suspicious for non-kiosk, non-IoT devices.
83+
- Analyze `source.as.organization.name` to identify if the authentication originated from a known hosting provider, VPN, or anonymization service you are not expecting
84+
- Investigate `source.address` to determine if the IP address has been previously flagged for suspicious activity.
85+
- Pivot on `azure.signinlogs.properties.user_principal_name` to check for additional authentication attempts from different IPs, ASNs, or unusual geolocations.
86+
- Correlate findings with `azure.signinlogs.properties.authentication_processing_details` to check if legacy protocols, token replay, or bypass mechanisms were involved.
87+
- Look for associated Conditional Access policy decisions in `azure.signinlogs.properties.applied_conditional_access_policies` to determine if the authentication attempt was blocked or allowed.
88+
- Check `azure.signinlogs.properties.device_detail.browser` to see if the user agent is consistent with expected authentication patterns.
89+
- If authentication was successful, investigate any subsequent suspicious activity linked to the same user session.
90+
91+
## MITRE ATT&CK Techniques
92+
93+
- [T1078.004](https://attack.mitre.org/techniques/T1078/004)
94+
95+
## References
96+
97+
- https://www.volexity.com/blog/2025/02/13/multiple-russian-threat-actors-targeting-microsoft-device-code-authentication/
98+
- https://www.blackhillsinfosec.com/dynamic-device-code-phishing/
99+
100+
## License
101+
102+
- `Elastic License v2`
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Azure Entra Device Code Authentication from Unusual Principal
2+
3+
---
4+
5+
## Metadata
6+
7+
- **Author:** Elastic
8+
- **Description:** This hunting query identifies Azure Entra sign-in logs where the authentication method used was Device Code Flow, which is often used for kiosk or IoT devices. If this authentication method is observed from a user or device that does not typically use it, it may indicate a potential compromise. This technique is common by adversaries conducting phishing campaigns with pre-registered device codes sent to targeted users whom are then redirected to Microsoft's device code authentication endpoint to initiation the workflow. The query filters for unusual authentication attempts based on the user principal name and the source address.
9+
10+
- **UUID:** `b54528ca-eec8-11ef-b314-f661ea17fbce`
11+
- **Integration:** [azure](https://docs.elastic.co/integrations/azure)
12+
- **Language:** `[ES|QL]`
13+
- **Source File:** [Azure Entra Device Code Authentication from Unusual Principal](../queries/entra_device_code_authentication_from_unusual_principal.toml)
14+
15+
## Query
16+
17+
```sql
18+
FROM logs-azure.signinlogs-*
19+
20+
// query Azure Entra Sign-in logs
21+
| WHERE @timestamp > now() - 14 day
22+
| WHERE event.dataset in ("azure.signinlogs")
23+
and event.category == "authentication"
24+
25+
// filter for device code workflows
26+
// original transfer method indicates refresh tokens where device code was originally used
27+
and (
28+
azure.signinlogs.properties.authentication_protocol == "deviceCode" or
29+
azure.signinlogs.properties.original_transfer_method == "Device code flow"
30+
)
31+
32+
// bucket authentication attempts by each day
33+
| EVAL target_time_window = DATE_TRUNC(1 days, @timestamp)
34+
35+
// aggregate authentication attempts by user principal name, source address, and message
36+
| STATS
37+
auth_count = count(*) by
38+
target_time_window,
39+
azure.signinlogs.properties.user_principal_name,
40+
source.address,
41+
message
42+
43+
// filter further for low auth counts by a particular principal name
44+
// indicating device code auth workflows are unusual for this user
45+
| WHERE auth_count < 5
46+
```
47+
48+
## Notes
49+
50+
- Review `azure.signinlogs.properties.authentication_protocol` to verify the authentication method used. Device Code Flow is typically reserved for IoT, kiosk, or embedded devices.
51+
- Investigate `azure.signinlogs.properties.user_principal_name` to determine whether the user typically authenticates using Device Code Flow. Unusual use by regular accounts may indicate compromise.
52+
- 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.
53+
- Examine `source.address` to check if the IP address is associated with previous suspicious activity, high-risk geolocations, or known threat infrastructure.
54+
- Pivot on `azure.signinlogs.properties.original_transfer_method` to identify if the Device Code Flow was used in combination with refresh tokens, which may indicate session hijacking.
55+
- Correlate findings with `azure.signinlogs.properties.authentication_processing_details` to identify possible legacy protocol usage, token replay, or bypass mechanisms.
56+
- Review `azure.signinlogs.properties.applied_conditional_access_policies` to determine if Conditional Access rules were applied, bypassed, or enforced during authentication.
57+
- Check `azure.signinlogs.properties.device_detail.browser` and `user_agent.original` to verify if the user agent aligns with expected authentication behavior for this user or device type.
58+
- If authentication was successful, pivot on `azure.signinlogs.properties.user_principal_name` to check for additional high-risk activities within the same session.
59+
- Monitor for multiple authentication attempts within a short period from different IPs or ASNs, which may indicate adversarial testing or phishing-based compromise.
60+
61+
## MITRE ATT&CK Techniques
62+
63+
- [T1078.004](https://attack.mitre.org/techniques/T1078/004)
64+
- [T1528](https://attack.mitre.org/techniques/T1528)
65+
66+
## License
67+
68+
- `Elastic License v2`
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
[hunt]
2+
author = "Elastic"
3+
description = """
4+
This hunting query gathers evidence of Azure Entra authentication attempts from hosting service providers that are often abused by adversaries. By identifying authentication attempts from these sources, security teams can detect potential unauthorized access or malicious activities within their Azure environment.
5+
"""
6+
integration = ["azure"]
7+
uuid = "d27f1da8-eec6-11ef-983a-f661ea17fbce"
8+
name = "Azure Entra Authentication Attempts from Abused Hosting Service Providers"
9+
language = ["ES|QL"]
10+
license = "Elastic License v2"
11+
notes = [
12+
"Review `azure.signinlogs.properties.authentication_protocol` to determine the authentication method used.",
13+
"Device Code Flow authentication is particularly suspicious for non-kiosk, non-IoT devices.",
14+
"Analyze `source.as.organization.name` to identify if the authentication originated from a known hosting provider, VPN, or anonymization service you are not expecting",
15+
"Investigate `source.address` to determine if the IP address has been previously flagged for suspicious activity.",
16+
"Pivot on `azure.signinlogs.properties.user_principal_name` to check for additional authentication attempts from different IPs, ASNs, or unusual geolocations.",
17+
"Correlate findings with `azure.signinlogs.properties.authentication_processing_details` to check if legacy protocols, token replay, or bypass mechanisms were involved.",
18+
"Look for associated Conditional Access policy decisions in `azure.signinlogs.properties.applied_conditional_access_policies` to determine if the authentication attempt was blocked or allowed.",
19+
"Check `azure.signinlogs.properties.device_detail.browser` to see if the user agent is consistent with expected authentication patterns.",
20+
"If authentication was successful, investigate any subsequent suspicious activity linked to the same user session."
21+
]
22+
23+
mitre = ['T1078.004']
24+
query = [
25+
'''
26+
FROM logs-azure.signinlogs-*
27+
28+
// query Azure Entra Sign-in logs
29+
| WHERE @timestamp > now() - 14 day
30+
| WHERE
31+
event.dataset in ("azure.signinlogs") and
32+
33+
// filter for authentication events
34+
event.category == "authentication" and
35+
36+
// filter for specific ASN organizations that are often abused
37+
source.as.organization.name in (
38+
"DigitalOcean", "Linode", "Vultr", "Hetzner", "OVH",
39+
"Contabo", "Leaseweb", "G-Core Labs", "Scaleway", "Kamatera",
40+
"Shinjiru", "M247", "Packet Host", "InterServer", "DataPacket",
41+
"Choopa", "Path Network", "DediPath", "Maxided", "Quasi Networks",
42+
"FlokiNET", "Njalla", "AbeloHost", "Inferno Solutions", "Hostinger",
43+
"Hostwinds", "1&1 IONOS", "DreamHost", "A2 Hosting", "Bluehost",
44+
"Namecheap Hosting", "FastComet", "InMotion Hosting", "SiteGround", "GreenGeeks",
45+
"Liquid Web", "Hurricane Electric", "Ubiquity Hosting", "Snel.com", "Coresite",
46+
"Eonix", "WebNX", "SharkTech", "Hivelocity", "Zenlayer",
47+
"RapidSeedbox", "SeFlow", "Nexeon Technologies", "NextArray", "Zare",
48+
"Clouvider", "TimeWeb", "YISP", "StackPath", "LuxVPS",
49+
"Terrahost", "IP Volume", "RackNerd", "ServerMania", "HostEurope",
50+
"HostHatch", "HostUS", "Cloudsigma", "QuadraNet", "CIV Host",
51+
"Swiftway", "King Servers", "BeeHost", "Webzilla", "Flokinet",
52+
"Alexhost", "DDoS-Guard", "StormWall", "Yokohama Networks", "DataGroup",
53+
"GSL Networks", "MyLoc", "Hostlife", "Reprise Hosting", "GTT Communications",
54+
"Telia", "Cogent Communications", "NForce", "Ecatel", "Novogara",
55+
"CyberBunker", "DarkFiber", "Exoscale", "QHoster", "ServDiscount",
56+
"Krypt", "Wowrack", "XLHost", "OVHCloud", "Privex",
57+
"GreencloudVPS", "RamNode", "BuyVM", "LiteServer", "Host1Plus",
58+
"EdgeUno", "CloudSouth", "IOFlood", "Hostry", "MivoCloud",
59+
"CloudCone", "SwiftNode", "Flaunt7", "Infinitie Networks", "ServerHub",
60+
"Verpex Hosting", "W3Space", "HostPapa", "Storm Internet", "WP Engine",
61+
"Kinsta", "Fly.io", "Edgecast", "RocketNode", "CloudAtCost",
62+
"Gullo's Hosting", "Serverion", "XHostFire", "Interserver", "DediServe",
63+
"HostRound", "VPSServer", "HostMantis", "RapidSwitch", "Tiggee LLC",
64+
"LogicWeb", "VPSCheap", "Versaweb", "SecureDragon", "ServerAstra",
65+
"HostNeverDie", "CloudSigma", "IONOS Cloud", "StackClash", "ProtonVPN",
66+
"NordVPN", "Mullvad VPN", "ExpressVPN", "Surfshark", "Private Internet Access",
67+
"TorGuard", "VyprVPN", "Windscribe VPN", "iVPN", "Perfect Privacy",
68+
"Astrill VPN", "TunnelBear", "CyberGhost VPN", "PureVPN", "Hotspot Shield",
69+
"StrongVPN", "F-Secure VPN", "IVPN", "ZoogVPN", "SwitchVPN",
70+
"AirVPN", "Buffered VPN", "SecureVPN", "RiseupVPN", "Betternet",
71+
"Trust.Zone VPN", "OneVPN", "VeePN", "Speedify VPN", "VPN Unlimited",
72+
"Anonine VPN", "X-VPN", "Hidemyass VPN", "ProXPN", "VPNArea",
73+
"AceVPN", "IPVanish", "Bitmask VPN", "BolehVPN", "AnonVPN",
74+
"Librem One VPN", "BlackVPN", "Cloudflare Warp VPN", "Torguard VPN", "VPN.ht"
75+
)
76+
77+
// aggregate authentication attempts by tenant, user principal name, authentication protocol, category, ASN organization name, and source address
78+
| STATS asn_count = count(*) by
79+
azure.tenant_id,
80+
azure.signinlogs.properties.user_principal_name,
81+
azure.signinlogs.properties.authentication_protocol,
82+
azure.signinlogs.category,
83+
source.as.organization.name,
84+
source.address
85+
'''
86+
]
87+
references = [
88+
"https://www.volexity.com/blog/2025/02/13/multiple-russian-threat-actors-targeting-microsoft-device-code-authentication/",
89+
"https://www.blackhillsinfosec.com/dynamic-device-code-phishing/"
90+
]
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
[hunt]
2+
author = "Elastic"
3+
description = """
4+
This hunting query identifies Azure Entra sign-in logs where the authentication method used was Device Code Flow, which is often used for kiosk or IoT devices. If this authentication method is observed from a user or device that does not typically use it, it may indicate a potential compromise. This technique is common by adversaries conducting phishing campaigns with pre-registered device codes sent to targeted users whom are then redirected to Microsoft's device code authentication endpoint to initiation the workflow. The query filters for unusual authentication attempts based on the user principal name and the source address.
5+
"""
6+
integration = ["azure"]
7+
uuid = "b54528ca-eec8-11ef-b314-f661ea17fbce"
8+
name = "Azure Entra Device Code Authentication from Unusual Principal"
9+
language = ["ES|QL"]
10+
license = "Elastic License v2"
11+
notes = [
12+
"Review `azure.signinlogs.properties.authentication_protocol` to verify the authentication method used. Device Code Flow is typically reserved for IoT, kiosk, or embedded devices.",
13+
"Investigate `azure.signinlogs.properties.user_principal_name` to determine whether the user typically authenticates using Device Code Flow. Unusual use by regular accounts may indicate compromise.",
14+
"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.",
15+
"Examine `source.address` to check if the IP address is associated with previous suspicious activity, high-risk geolocations, or known threat infrastructure.",
16+
"Pivot on `azure.signinlogs.properties.original_transfer_method` to identify if the Device Code Flow was used in combination with refresh tokens, which may indicate session hijacking.",
17+
"Correlate findings with `azure.signinlogs.properties.authentication_processing_details` to identify possible legacy protocol usage, token replay, or bypass mechanisms.",
18+
"Review `azure.signinlogs.properties.applied_conditional_access_policies` to determine if Conditional Access rules were applied, bypassed, or enforced during authentication.",
19+
"Check `azure.signinlogs.properties.device_detail.browser` and `user_agent.original` to verify if the user agent aligns with expected authentication behavior for this user or device type.",
20+
"If authentication was successful, pivot on `azure.signinlogs.properties.user_principal_name` to check for additional high-risk activities within the same session.",
21+
"Monitor for multiple authentication attempts within a short period from different IPs or ASNs, which may indicate adversarial testing or phishing-based compromise."
22+
]
23+
mitre = ['T1078.004','T1528']
24+
query = [
25+
'''
26+
FROM logs-azure.signinlogs-*
27+
28+
// query Azure Entra Sign-in logs
29+
| WHERE @timestamp > now() - 14 day
30+
| WHERE event.dataset in ("azure.signinlogs")
31+
and event.category == "authentication"
32+
33+
// filter for device code workflows
34+
// original transfer method indicates refresh tokens where device code was originally used
35+
and (
36+
azure.signinlogs.properties.authentication_protocol == "deviceCode" or
37+
azure.signinlogs.properties.original_transfer_method == "Device code flow"
38+
)
39+
40+
// bucket authentication attempts by each day
41+
| EVAL target_time_window = DATE_TRUNC(1 days, @timestamp)
42+
43+
// aggregate authentication attempts by user principal name, source address, and message
44+
| STATS
45+
auth_count = count(*) by
46+
target_time_window,
47+
azure.signinlogs.properties.user_principal_name,
48+
source.address,
49+
message
50+
51+
// filter further for low auth counts by a particular principal name
52+
// indicating device code auth workflows are unusual for this user
53+
| WHERE auth_count < 5
54+
'''
55+
]

0 commit comments

Comments
 (0)