Detect possible AiTM phishing attacks originating from Azure infrastructure such as Azure Functions.
ID: T1539.Entra.AzureAiTMPhishing
Author: Nicola Suter
License: MIT License
References: Link to medium post
Tactic: Credential Access (TA0006) / Phishing (T1566)
Technique: Steal Web Session Cookie (T1539)
Attackers can host AiTM phishing kits directly on Azure and leverage Microsoft provided public ip addresses for internet connectivity. It is also possible to deploy Azure Functions or app services to conduct the attack. During the attack the session cookies will be captured and allow replay.
None.
The detection is based on the Entra Sign-In Logs and the following assumptions:
- Empty Entra Device IDs
- Sign-In originating not from a named or trusted location
- The application name matches OfficeHome
- The Sign-In IP address originates from the Microsoft Azure IP address ranges
Event ID | Event Name | Log Provider | ATT&CK Data Source |
---|---|---|---|
- | SignInLogs | Entra ID | Cloud Service |
FP Rate: Medium
Source: Entra ID
Description: Hunt for interactive sign-in logs that originated from Azure Service Tags / Endpoints.
Query:
let AzureIPInfo = externaldata(changeNumber: int, cloud: string, values: dynamic)[h"https://stsecopsn01.blob.core.windows.net/watchlists/ServiceTags_Public_20240311.json"] with (format = 'multijson')
| project-away changeNumber, cloud
| mv-expand parse_json(values)
| extend Name = values.name
| extend AddressPrefixes = values.properties.addressPrefixes
| extend Platform = values.properties.platform
| summarize make_list(AddressPrefixes);
SigninLogs
| where TimeGenerated > ago(90d)
| where ResultType == 0
| where DeviceDetail.trustType == ''
// Match with Azure IPs
| where ipv4_is_in_any_range(IPAddress, toscalar(AzureIPInfo))
// Assuming the IPs have not been added as named or trusted locations
| extend ConfidenceScoreNetwork = iif(NetworkLocationDetails == '[]', 1.0, 0.1)
// OfficeHome is most often used in phishing kits
| extend ConfidenceScoreApp = iif(AppDisplayName =~ 'OfficeHome', 1.0, 0.75)
| extend ConfidenceScore = ConfidenceScoreApp * ConfidenceScoreNetwork
| where ConfidenceScore > 0.5
| distinct
TimeGenerated,
UserPrincipalName = '{PII Removed}',
UserAgent,
AppDisplayName,
IPAddress,
ConfidenceScore,
RiskDetail
- The Azure IP Address ranges must be available on a storage account or watchlist. Official download link: https://www.microsoft.com/en-gb/download/details.aspx?id=56519
The IP address from Microsoft Azure IP ranges could be legitimate, e.g. from virtual machines that do not have explicit outbound connectivity methods via NAT gateway or firewall.
- Mismatch of assumptions or phishing from a named location