Adversaries may use OAuth phishing emails to deliver malicious URLs that could compromise user credentials and gain unauthorized access to Azure resources. SOC teams should proactively hunt for this behavior to identify and mitigate potential credential theft and lateral movement attempts in their environment.
KQL Query
let ConsentUrls = pack_array("://login.microsoftonline.com/common/oauth2", "://login.microsoftonline.com/consumers/oauth2", "://login.microsoftonline.com/organizations/oauth2", "://login.microsoftonline.us/common/oauth2", "://login.microsoftonline.us/consumers/oauth2", "://login.microsoftonline.us/organizations/oauth2");
EmailUrlInfo
| where Url has_any (ConsentUrls)
| join EmailEvents on NetworkMessageId
| where EmailDirection == "Inbound" and LatestDeliveryAction == "Delivered"
id: 7dca78d0-5354-4e20-80c0-4f770450feb6
name: Potential OAuth phishing email delivered into Inbox
description: |
This query can be used as a Custom Detection Rule (CDR) to trigger when a potentially malicious OAuth app URL has been delivered into an Inbox.
description-detailed: |
This query can be used as a Custom Detection Rule (CDR) to trigger when a potentially malicious OAuth app URL has been delivered into an Inbox. The URLs contained are not directly malicious but could be an attempt to delegate permissions to an attacker-controlled App. https://learn.microsoft.com/en-us/defender-xdr/custom-detection-rules
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- EmailEvents
tactics:
- InitialAccess
relevantTechniques:
- T1566
query: |
let ConsentUrls = pack_array("://login.microsoftonline.com/common/oauth2", "://login.microsoftonline.com/consumers/oauth2", "://login.microsoftonline.com/organizations/oauth2", "://login.microsoftonline.us/common/oauth2", "://login.microsoftonline.us/consumers/oauth2", "://login.microsoftonline.us/organizations/oauth2");
EmailUrlInfo
| where Url has_any (ConsentUrls)
| join EmailEvents on NetworkMessageId
| where EmailDirection == "Inbound" and LatestDeliveryAction == "Delivered"
version: 1.0.0
| Sentinel Table | Notes |
|---|---|
EmailEvents | Ensure this data connector is enabled |
EmailUrlInfo | Ensure this data connector is enabled |
Scenario: Legitimate OAuth App Configuration via Admin Console
Description: An admin manually configures a new OAuth app in the company’s identity provider (e.g., Okta, Azure AD) and receives a confirmation email with a URL that matches the detection pattern.
Filter/Exclusion: Exclude emails sent to admin users with the sender domain matching the identity provider’s domain (e.g., [email protected] or [email protected]).
Scenario: Scheduled Job for OAuth Token Refresh
Description: A scheduled job (e.g., via Jenkins, Airflow, or a custom script) runs to refresh OAuth tokens and sends a notification email containing a URL that matches the detection logic.
Filter/Exclusion: Exclude emails sent from known automation accounts (e.g., [email protected], [email protected]) or with a subject line containing “Token Refresh” or “OAuth Renewal”.
Scenario: User-Initiated OAuth Consent Prompt
Description: A user clicks on a link in an email from a trusted service (e.g., Google, Microsoft) to grant OAuth consent, which includes a URL that matches the detection rule.
Filter/Exclusion: Exclude emails where the sender domain is a known trusted OAuth provider (e.g., accounts.google.com, login.microsoftonline.com) and the user has previously authorized the app.
Scenario: Internal Tool for OAuth Debugging
Description: A developer uses an internal tool (e.g., Postman, curl, or a custom debug script) to test OAuth endpoints and receives a confirmation email with a test URL that triggers the rule.
Filter/Exclusion: Exclude emails sent to developers with the sender domain matching the internal tool’s domain or containing “debug”, “test”, or “dev” in the subject line.
**Scenario: Email Notification