Steal Application Access Token — Business Email Compromise via OAuth Device Code Flow Phishing
OAuth Device Code Flow phishing is a prevalent Business Email Compromise (BEC) technique actively used by Scattered Spider, Storm-2372, and nation-state actors including Midnight Blizzard. The attacker sends a phishing message containing a Microsoft device code (a short alphanumeric code from https://microsoft.com/devicelogin), social-engineered to appear as an IT helpdesk request, MFA enrollment notification, or remote support session. When the victim enters the code, the attacker receives a valid OAuth access token and refresh token for the victim's Microsoft 365 account — with no password required. The attacker then has full access to email, Teams, SharePoint, OneDrive, and any M365 service the victim is licensed for. Refresh tokens may persist for 90 days, providing long-term access even after password reset. This technique bypasses MFA entirely because the device code flow is a legitimate Microsoft authentication mechanism.
What is THREAT-BEC-OAuthDeviceCode Business Email Compromise via OAuth Device Code Flow Phishing?
Business Email Compromise via OAuth Device Code Flow Phishing (THREAT-BEC-OAuthDeviceCode) is a sub-technique of Steal Application Access Token (T1528) in the MITRE ATT&CK framework. It maps to the Credential Access and Collection tactics — the adversary is trying to steal account names and passwords.
This page provides production-ready detection logic for Business Email Compromise via OAuth Device Code Flow Phishing, covering the data sources and telemetry it touches: Azure AD Sign-In Logs (AADSignInLogs), Office 365 Unified Audit Log (OfficeActivity), Microsoft 365 Defender. The queries below are rated high severity at high confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Credential Access Collection
// THREAT: OAuth Device Code Flow BEC Phishing
// Detects suspicious OAuth token acquisition via device code flow in Microsoft 365
// Primary telemetry: Azure AD Sign-in logs, Office 365 audit logs
// Alert 1: Device code flow sign-ins from anomalous locations or user agents
let KnownMobileApps = dynamic(["Microsoft Office", "Microsoft Teams", "Outlook Mobile", "OneDrive"]);
let SuspiciousUserAgents = dynamic(["python-requests", "curl", "wget", "Go-http-client", "okhttp", "axios"]);
AADSignInLogs
| where TimeGenerated > ago(24h)
| where AuthenticationProtocol =~ "deviceCode" or TokenIssuerType =~ "AzureAD"
| where ResourceDisplayName !in ("Windows Sign In", "Microsoft App Access Panel")
// Flag device code logins from suspicious clients or unexpected locations
| where UserAgent has_any (SuspiciousUserAgents)
or (
// Device code used and then token immediately used from different country than user's typical location
Status.errorCode == 0 and
(
// Inline phishing sequence: initial device code poll + immediate use
AuthenticationDetails has "DeviceCode" and
Location !in ("GB", "US") // Adjust to your expected user country list
)
)
| project TimeGenerated, UserPrincipalName, IPAddress, Location, UserAgent,
AppDisplayName, ResourceDisplayName, AuthenticationProtocol,
ConditionalAccessStatus, RiskDetail, RiskLevelDuringSignIn
| extend ThreatType = "DeviceCode_BEC_Phishing"
| sort by TimeGenerated desc;
// Alert 2: Inbox rules created immediately after device code sign-in (typical BEC follow-on)
OfficeActivity
| where TimeGenerated > ago(24h)
| where Operation in ("New-InboxRule", "Set-InboxRule", "Set-Mailbox")
| where Parameters has_any ("DeleteMessage", "ForwardTo", "RedirectTo",
"ForwardAsAttachmentTo", "MoveToFolder")
| where Parameters !has "Junk Email" // Exclude Junk folder rules which are often legitimate
| project TimeGenerated, UserId, ClientIP, Operation, Parameters, OrganizationId
| extend ThreatType = "BEC_InboxRule_Forwarding" Two-part detection: (1) OAuth device code flow sign-ins with suspicious user agents or unexpected geographic locations — the exact mechanism used by Storm-2372 and Scattered Spider BEC campaigns; (2) Inbox rule creation immediately following sign-in events — the BEC follow-on action to forward victim email to attacker-controlled addresses. Both should be investigated together for maximum fidelity.
Data Sources
Required Tables
False Positives
- Legitimate device code sign-in by users registering a new device (smart TV, printer, IoT device) against corporate M365 tenant
- IT helpdesk staff using device code flow to assist users in enrolling devices
- Developers testing OAuth device code flow against M365 APIs in dev/test tenants
- Users creating legitimate inbox rules to organise their mailbox (exclude forward/delete rules that move to specific business folders)
Sigma rule & cross-platform mapping
The detection logic for Business Email Compromise via OAuth Device Code Flow Phishing (THREAT-BEC-OAuthDeviceCode) above is provided in a vendor-neutral
form so you can deploy it on any SIEM. The same logic is shipped here as native
KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the
following logsource:
logsource:
product: azure Browse the community-maintained Sigma rules for this technique:
Platform-specific guides for THREAT-BEC-OAuthDeviceCode
Testing Methodology
Validate this detection against 2 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1OAuth Device Code Flow Token Request (Simulated Phishing)
Expected signal: Azure AD Sign-in logs record a DeviceCode flow initiation. When user enters the code, AADSignInLogs records a successful authentication with AuthenticationProtocol=deviceCode.
- Test 2Create BEC Inbox Forwarding Rule via Exchange Online PowerShell
Expected signal: O365 Unified Audit Log records New-InboxRule operation with ForwardTo parameter for the authenticated user.
Response Playbook
Triage
- Confirm whether the device code sign-in was legitimate by contacting the affected user directly (NOT via email or Teams if account may be compromised). Ask if they recently used a code at microsoft.com/devicelogin.
- Check the sign-in location and IP address against the user's typical locations (Azure AD Sign-in logs, last 30 days). A sign-in from a country the user has never visited is high confidence.
- Review the OAuth token issued: which application (AppId) received the token? Legitimate apps include Microsoft Office, Outlook, Teams. Suspicious: generic app IDs, unknown application names, or 'first seen' apps.
- Check for inbox rules created within 24 hours of the device code sign-in. Look specifically for: ForwardTo (exfiltration), DeleteMessage (hiding attacker activity), MoveToFolder where the target folder is not Junk.
- Review email access (MailItemsAccessed, MessageRead operations in O365 audit) following the device code sign-in for signs of mail reading or forwarding.
- Determine if the user received a phishing email before the device code sign-in: search incoming mail for messages containing 'microsoft.com/devicelogin' or 8-character alphanumeric codes sent from external senders.
Containment
- Revoke all refresh tokens for the affected user immediately: Azure AD > Users > [User] > Revoke sessions (or via PowerShell: Revoke-AzureADUserAllRefreshToken -ObjectId <userID>).
- Delete or disable any suspicious inbox rules identified during triage.
- Block the attacker IP address(es) in Conditional Access or Named Locations policy.
- Reset the user's password and require re-enrollment of MFA devices.
- Enable Conditional Access policy to block Device Code flow for all users where possible (CA policy: Grant > Require compliant device, block legacy authentication).
- Review and revoke any OAuth application consents granted during the attacker's session (Azure AD > Enterprise Applications > review third-party apps with delegated permissions).
Evidence Collection
- Azure AD Sign-in logs: device code events, token issuances, subsequent application activity
- O365 Unified Audit Log: MailItemsAccessed, MessageRead, SendAs, SendOnBehalf operations in the incident window
- O365 inbox rules export: all rules for the affected user
- Outbound email logs: emails sent by or forwarded from the compromised account
- Conditional Access evaluation logs for the device code sign-in event
- The phishing email itself (if recoverable) for threat actor infrastructure IOCs
Escalation Criteria
- ! Evidence of financial transactions initiated from compromised email (wire transfer requests, invoice changes)
- ! Email access to finance team, HR, or executive mailboxes from compromised account (lateral BEC targeting)
- ! OAuth consent grant to third-party application with mail.read, files.read, or contacts.read permissions
- ! Evidence of email exfiltration (MailItemsAccessed showing bulk message access from attacker IP)
- ! Compromised account used to send internal phishing emails to other employees
Investigation Guide
Forensic Artifacts
- >
Azure AD Sign-In logs: AppId, IPAddress, UserAgent, AuthenticationDetails fields for device code events - >
O365 Unified Audit Log: all operations by the user in the 24 hours post-compromise - >
O365 MailItemsAccessed events: which messages were read and by which client IP - >
O365 message trace: all sent/forwarded messages from the compromised account - >
Azure AD OAuth token activity: which refresh tokens were issued and when they were used - >
Browser or email client forensics on victim device: the phishing message that contained the device code
Tuning Guidance
Device code flow is legitimately used for IoT device enrollment, smart TVs, and printer registration — these are usually one-time events. Tune by creating a baseline of users who have historically used device code authentication (e.g., IT staff enrolling conference room devices) and apply enrichment to distinguish these. The highest-fidelity signal is the sequence: device code auth + inbox rule with ForwardTo. Consider disabling device code flow entirely via Conditional Access policies for users who do not need it (most corporate users). Set up a Conditional Access policy to block the 'Azure AD Device Registration' flow or require compliant devices for this authentication method.
Hunting Queries
Hunt for users with multiple device code sign-ins across multiple locations — indicates ongoing credential theft campaign or compromised user repeatedly being targeted.
AADSignInLogs
| where TimeGenerated > ago(30d)
| where AuthenticationProtocol =~ "deviceCode"
| where Status.errorCode == 0
| summarize
DeviceCodeLogins=count(),
Locations=make_set(Location),
IPs=make_set(IPAddress),
Apps=make_set(AppDisplayName)
by UserPrincipalName
| where DeviceCodeLogins > 3 or array_length(Locations) > 2
| sort by DeviceCodeLogins desc index=azure sourcetype="azure:aad:signin" properties.authentication_protocol="deviceCode" properties.status.error_code=0
| stats count AS LoginCount, dc(properties.ip_address) AS UniqueIPs, values(properties.location) AS Locations
BY properties.user_principal_name
| where LoginCount > 3 OR UniqueIPs > 2
| sort - LoginCount Hunt for inbox forwarding rule creation within 4 hours of a device code sign-in — the high-confidence combined BEC indicator that storm-2372 and Scattered Spider are documented using.
OfficeActivity
| where TimeGenerated > ago(30d)
| where Operation in ("New-InboxRule", "Set-InboxRule")
| where Parameters has_any ("ForwardTo", "DeleteMessage", "RedirectTo", "ForwardAsAttachmentTo")
| join kind=leftouter (
AADSignInLogs
| where TimeGenerated > ago(30d)
| where AuthenticationProtocol =~ "deviceCode"
| project UserId=UserPrincipalName, DeviceCodeTime=TimeGenerated
) on $left.UserId == $right.UserId
| where isnotnull(DeviceCodeTime)
| extend TimeDiff=datetime_diff('minute', TimeGenerated, DeviceCodeTime)
| where TimeDiff >= 0 and TimeDiff <= 240
| project TimeGenerated, UserId, Operation, Parameters, DeviceCodeTime, TimeDiff index=o365 sourcetype="o365:management:activity" Operation IN ("New-InboxRule", "Set-InboxRule") Parameters="*ForwardTo*"
| rename UserId AS user
| join type=inner user [
search index=azure sourcetype="azure:aad:signin" properties.authentication_protocol="deviceCode"
| rename properties.user_principal_name AS user
| eval dc_time=_time
]
| where (_time - dc_time) >= 0 AND (_time - dc_time) <= 14400
| table _time, user, Operation, Parameters, dc_time, ClientIP Atomic Red Team Tests
Simulates an OAuth device code phishing attack by initiating the device code flow against a Microsoft 365 tenant and waiting for a user to authenticate at microsoft.com/devicelogin. This tests detection of device code token acquisition in AADSignInLogs.
Command
curl -s -X POST 'https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/devicecode' -d 'client_id=d3590ed6-52b3-4102-aeff-aad2292ab01c&scope=openid+profile+email+https://graph.microsoft.com/Mail.Read' Expected Telemetry
Azure AD Sign-in logs record a DeviceCode flow initiation. When user enters the code, AADSignInLogs records a successful authentication with AuthenticationProtocol=deviceCode.
Expected Detection
Alert fires on device code authentication event from suspicious user agent or unexpected geographic location.
Simulates the post-compromise BEC inbox rule creation that attackers use to forward victim email to external addresses after OAuth token theft.
Command
Connect-ExchangeOnline; New-InboxRule -Name 'Test_Rule' -ForwardTo '[email protected]' -Enabled $true Cleanup
Remove-InboxRule -Identity 'Test_Rule' -Force Expected Telemetry
O365 Unified Audit Log records New-InboxRule operation with ForwardTo parameter for the authenticated user.
Expected Detection
Alert fires on New-InboxRule with ForwardTo parameter. If preceded by device code sign-in within 4 hours, high confidence BEC alert.