Skip to content

OAuth Device Code Flow Abuse & Token Hijacking

Among the diverse initial access techniques targeting Microsoft 365, the abuse of the OAuth 2.0 Device Authorization Grant (RFC 8628)—commonly known as Device Code Flow Phishing—occupies a unique and lethal position. Unlike credential phishing or Adversary-in-the-Middle (AiTM) attacks, Device Code phishing directs the victim to a 100% legitimate Microsoft URL (https://microsoft.com/devicelogin), uses valid first-party Microsoft client IDs, and requires no hostile domain infrastructure.

When an unsuspecting victim enters a threat-actor-generated code into Microsoft’s official device login portal and satisfies Multi-Factor Authentication (MFA), Microsoft’s Security Token Service (STS) mints and delivers high-privilege access and refresh tokens directly to the adversary’s command-line interface.

This guide provides an exhaustive architectural and forensic dissection of Device Code Flow abuse, details the weaponization of first-party Microsoft application IDs, analyzes telemetry across Entra ID logs, and delivers production-grade KQL hunting queries and mitigation architectures.


1. RFC 8628 Architecture vs Adversary Weaponization

Section titled “1. RFC 8628 Architecture vs Adversary Weaponization”

The OAuth 2.0 Device Authorization Grant (RFC 8628) was designed for internet-connected devices with restricted input capabilities (such as smart TVs, IoT appliances, or headless CLI terminals) that cannot host an interactive browser:

sequenceDiagram
autonumber
participant Attacker as Adversary CLI (TokenTactics / AADInternals)
participant Entra as Microsoft Entra ID (STS)
participant Victim as Target Employee (Browser)
Attacker->>Entra: POST /common/oauth2/v2.0/devicecode (Client ID: Azure CLI)
Entra-->>Attacker: Returns user_code (e.g., "ABCD-EFGH") + device_code + verification_uri
Note over Attacker: Attacker initiates polling loop on /token in background
Attacker->>Victim: Phishing Lure (Email/Teams): "Enter code ABCD-EFGH at https://microsoft.com/devicelogin"
Victim->>Entra: Navigates to legitimate https://microsoft.com/devicelogin
Note over Victim: Enters "ABCD-EFGH" + Authenticates with Password & MFA
Entra-->>Victim: Displays prompt: "Are you trying to sign in to Microsoft Azure CLI?"
Victim->>Entra: Clicks "Continue" (MFA Satisfied)
Note over Entra: Handshake Completed!
Entra-->>Attacker: Background polling succeeds! Returns Access Token + Refresh Token
Note over Attacker: Attacker gains immediate programmatic API control of tenant resources!

Why Device Code Flow Phishing is Devastatingly Effective:

Section titled “Why Device Code Flow Phishing is Devastatingly Effective:”
  1. Zero Domain Reputation Risk: The lure directs the user to https://microsoft.com/devicelogin. No Secure Email Gateway (SEG), web proxy, or EDR content filter blocks legitimate Microsoft root domains.
  2. First-Party Client Pre-Consent: Threat actors utilize the client IDs of official Microsoft tools (e.g., Azure CLI, Microsoft Office, PowerShell). Because these are trusted first-party applications, they do not trigger end-user consent warnings or administrator consent blocks.
  3. MFA Claims Encapsulated: The resulting tokens encapsulate full MFA satisfaction claims, bypassing downstream Conditional Access rules requiring MFA.

Adversaries initiate Device Code requests by specifying client IDs corresponding to pre-authorized first-party Microsoft software:

Application NameClient ID (AppId GUID)Default Scopes / Capabilities
Microsoft Azure CLI04b07795-8ddb-461a-bbee-02f9e1bf7b46Full Azure Resource Manager (ARM), Graph API, Azure Key Vault, Azure Storage.
Azure PowerShell1950a258-227b-4e31-a9cf-717495945fc2Full Azure tenant management and subscription administration.
Microsoft Officed3590ed6-52b3-4102-aeff-aad2292ab01cAccess to Exchange Online, SharePoint Online, OneDrive, and Teams.
Microsoft Graph Command Line14d82eec-204b-4c2f-b354-c2419e407076Broad Graph API directory querying and administrative role assignments.
Visual Studio872cd9fa-d31f-45e0-9eab-6e460a02d1f1Azure DevOps, source code repositories, and developer cloud environments.

3. Forensic Footprint in Microsoft Entra ID Telemetry

Section titled “3. Forensic Footprint in Microsoft Entra ID Telemetry”

Device Code Flow abuse produces a distinct, recognizable trace in Entra ID sign-in logs. Forensic investigators must correlate two distinct phases:

graph TD
subgraph "Phase 1: Code Authorization (Victim Egress)"
V_LOG["SigninLogs Record<br/>AppDisplayName: Microsoft Azure CLI<br/>AuthenticationProtocol: deviceCode<br/>IPAddress: Victim Corporate IP<br/>ResultType: 0 (Success)<br/>MFA Satisfied: True"]
end
subgraph "Phase 2: Operational Token Usage (Adversary Egress)"
A_LOG["NonInteractiveUserSignInLogs Record<br/>AppDisplayName: Microsoft Azure CLI<br/>IPAddress: Attacker VPS / Residential Proxy<br/>ResourceDisplayName: Windows Azure Service Management API<br/>Token Issued via Refresh Token"]
end
V_LOG -->|Token Handed to Attacker| A_LOG

When reviewing SigninLogs in Log Analytics or Microsoft Sentinel:

  • AuthenticationProtocol: Must equal deviceCode.
  • AppDisplayName: Indicates the weaponized tool (e.g., "Microsoft Azure CLI", "Azure PowerShell").
  • ClientAppUsed: Set to "Mobile Apps and Desktop clients".
  • DeviceDetail: Often shows empty or inconsistent device properties. The authorization event occurs on the victim’s browser, but the device is not bound as a managed Azure CLI endpoint.
  • Cross-IP Discrepancy: The interactive authentication (SigninLogs) occurs from the victim’s location, while subsequent resource accesses (NonInteractiveUserSignInLogs) emerge from foreign ASNs, cloud hosting providers (DigitalOcean, AWS, Linode), or residential proxies.

4.1 Detecting All Successful Device Code Flow Sign-Ins

Section titled “4.1 Detecting All Successful Device Code Flow Sign-Ins”

Baseline and identify all successful Device Code authentications across the tenant:

SigninLogs
| where TimeGenerated >= ago(14d)
| where ResultType == 0
| where AuthenticationProtocol == "deviceCode"
| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress, Location,
ClientAppUsed, DeviceDetail, UserAgent, CorrelationId
| sort by TimeGenerated desc

4.2 Detecting Cross-IP Device Code Token Replay

Section titled “4.2 Detecting Cross-IP Device Code Token Replay”

Detect instances where a device code authorization occurs from one IP, but subsequent non-interactive token refreshes for the same application occur from a different IP address or country within 2 hours:

let DeviceCodeAuths = SigninLogs
| where TimeGenerated >= ago(7d)
| where ResultType == 0
| where AuthenticationProtocol == "deviceCode"
| project AuthTime=TimeGenerated, UserPrincipalName, AuthIP=IPAddress,
AuthCountry=Location, AppDisplayName, CorrelationId;
let TokenRefreshes = NonInteractiveUserSignInLogs
| where TimeGenerated >= ago(7d)
| where ResultType == 0
| project RefreshTime=TimeGenerated, UserPrincipalName, RefreshIP=IPAddress,
RefreshCountry=Location, AppDisplayName, ResourceDisplayName;
DeviceCodeAuths
| join kind=inner (TokenRefreshes) on UserPrincipalName, AppDisplayName
| where RefreshTime between (AuthTime .. (AuthTime + 2h))
| where AuthIP != RefreshIP and AuthCountry != RefreshCountry
| project UserPrincipalName, AppDisplayName, AuthTime, AuthIP, AuthCountry,
RefreshTime, RefreshIP, RefreshCountry, ResourceDisplayName
| sort by AuthTime desc

4.3 Hunting Non-Technical Users Authorizing Developer CLI Tools

Section titled “4.3 Hunting Non-Technical Users Authorizing Developer CLI Tools”

Flag instances where employees in Finance, Human Resources, Legal, or Executive roles authorize developer-oriented command-line tools:

let DeveloperApps = dynamic([
"04b07795-8ddb-461a-bbee-02f9e1bf7b46", // Azure CLI
"1950a258-227b-4e31-a9cf-717495945fc2", // Azure PowerShell
"14d82eec-204b-4c2f-b354-c2419e407076" // Graph CLI
]);
SigninLogs
| where TimeGenerated >= ago(14d)
| where ResultType == 0
| where AppId in (DeveloperApps)
| where AuthenticationProtocol == "deviceCode"
// Optional: Filter against a watchlist of non-technical user UPNs or departments
| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress, Location, UserAgent
| sort by TimeGenerated desc

To completely eliminate or constrain Device Code Flow abuse, organizations must implement multi-layered Conditional Access controls:

graph TD
DEF[Anti-Device Code Architecture] --> L1[1. Conditional Access Device Compliance<br/>Require Hybrid Entra Join or Intune Compliant Device]
DEF --> L2[2. Conditional Access Authentication Strengths<br/>Enforce Phishing-Resistant MFA for Developer Tools]
DEF --> L3[3. Target Non-Technical User Groups<br/>Explicitly block Azure Management & CLI for standard users]
DEF --> L4[4. Automated Alerting & Immediate Revocation<br/>Sentinel rule triggering automated Revoke-MgUserSignSession]

5.1 Enforcing Device Compliance on Azure Management

Section titled “5.1 Enforcing Device Compliance on Azure Management”

Even if a victim completes Device Code authorization, an adversary cannot utilize the returned token on their own machine if Conditional Access mandates that access to "Microsoft Azure Management" requires a Compliant Device:

  • Target Resource: Microsoft Azure Management
  • Users: All Users (exclude Break-Glass accounts)
  • Grant Control: Require device to be marked as compliant OR Require Microsoft Entra hybrid joined device

If an analyst confirms a victim approved an unauthorized Device Code request:

Terminal window
# Prerequisites: Microsoft.Graph.Users
# Connect-MgGraph -Scopes "User.ReadWrite.All"
$compromisedUPN = "victim@target.com"
Write-Host "[!] TERMINATING SESSIONS FOR DEVICE CODE VICTIM: $compromisedUPN" -ForegroundColor Red
# Revoke all refresh tokens immediately
Revoke-MgUserSignSession -UserId $compromisedUPN
Write-Host "[+] All refresh tokens and sessions invalidated." -ForegroundColor Green

6. Cross-Reference & Investigation Navigation

Section titled “6. Cross-Reference & Investigation Navigation”