(1) Attack Mechanics: Device Code Flow Abuse vs. AiTM Proxies
The trust chain failure here is fundamentally different from an AiTM attack.
AiTM proxies (like Evilginx or Modlishka) sit between the client and the legitimate IdP, intercepting the legitimate authentication handshake. The user enters credentials on a fake page, the proxy forwards them to the real IdP, captures the session cookie or token in transit, and the attacker inherits that session. The trust boundary breach is at the presentation layer — the user is deceived about which site they're interacting with.
OAuth Device Code Flow abuse (Kali365/EvilTokens) is more insidious. Here's the trust chain:
- Attacker calls
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/devicecode directly — this is a legitimate, cryptographically signed Microsoft API endpoint
- Microsoft responds with a legitimate device code (e.g.,
ABCDE-12345) and verification URL (https://microsoft.com/devicelogin)
- Attacker sends this code to the victim via email/web/phishing lure
- Victim navigates to the genuine Microsoft URL (not a fake site), enters their credentials, and explicitly authorizes "the device" to access their account
- Microsoft issues access and refresh tokens to the attacker's device — because the device code flow was designed for devices without keyboards (smart TVs, IoT), MFA is satisfied during the user's authentication to Microsoft, and the token is bound to the attacker's device context
Why minimal signals? The authentication flow is cryptographically legitimate from the IdP's perspective. The user authenticated correctly. The authorization grant is valid per OAuth 2.0 RFC 8628. There is no "anomalous" redirect, no suspicious IP velocity during credential entry, no user-agent spoofing at the authentication moment. The anomaly only appears in the token consumption patterns — geographic or device context mismatches when the attacker uses the token.
According to the FBI PSA (Alert I-052126-PSA), Kali365 has been "capturing OAuth tokens and gaining persistent access to targeted individuals/entities' Microsoft 365 environments" without triggering "MFA protocols." Microsoft's research confirms this: "the threat actor's server now possesses a live Access Token for the targeted user's account, bypassing MFA by design."
The GBHackers report notes the platform includes "real-time tracking" capabilities delivered via Telegram subscription — lowering the barrier for less sophisticated threat actors.
(2) Entra ID Conditional Access Policies to Block This
Microsoft introduced a preview setting in February 2024 to block specific authentication flows via Conditional Access. Here's the precise configuration:
Policy Name: "Block Device Code Flow" (or your organizational naming convention)
Conditions → Client Apps → Browser and Mobile Apps and Desktop Clients:
Enable and include these client types
Conditions → Authentication Flows:
Enable the "Authentication flows" condition
- Select "Device code flow" → Set to Block
- Optionally also block "Authentication transfer" if your threat model includes code transfer abuse
Grant Controls:
Select Block access
Assignment:
Target your user population. Warning: Some legitimate scenarios (PowerShell scripting with Connect-MgGraph -DeviceCode, CLI tools on headless servers) use device code. You may need:
- Exclude specific service accounts
- Require device compliance for the narrow population that needs this flow
- Use Terms of Use for justification workflows
According to Office365ITPros documentation, "in late February 2024, Microsoft introduced a preview setting for Entra ID conditional access policies to block authentication flows... it's easy to block device code authentications with a conditional access policy."
Storm-2372 guidance from Microsoft also emphasizes "Block legacy authentication protocols" as complementary hardening — though device code isn't legacy auth, the principle applies: tightly control which authentication flows your tenant accepts.
(3) Forensic Trail in Entra ID Logs
The forensic challenge is that the initial authentication looks legitimate. You need to hunt for post-token patterns.
Primary Log Sources:
| Log Type |
Table |
Key Fields |
| Sign-in logs |
SignInLogs |
AuthenticationProtocol, AuthenticationProcessingDetails, DeviceDetail, Location, ClientAppUsed |
| Audit logs |
AuditLogs |
ActivityDisplayName, TargetResources, ModifiedProperties |
Key Hunting Queries:
- Device code authentications in SignInLogs:
SignInLogs
| where AuthenticationProtocol == "deviceCode"
| extend AuthorizationCode = parse_json(AuthenticationProcessingDetails)[?key == "authorization_code"].value
| project TimeGenerated, UserPrincipalName, IPAddress, Location, DeviceDetail, ClientAppUsed, AppDisplayName
The AuthenticationProtocol field will show "deviceCode" — but this requires streamlined logging enabled. Check your log analytics workspace schema.
- Unusual token consumption patterns:
SignInLogs
| where ConditionalAccessStatus == "success"
| where UserPrincipalName in (high_value_users)
| summarize dcount(IPAddress), make_set(IPAddress) by UserPrincipalName, bin(TimeGenerated, 1h)
| where dcount_IPAddress > 1 and set_IPAddress contains "suspicious_region"
- OAuth app consents post-device-code:
AuditLogs
| where ActivityDisplayName == "Consent to application"
| where TargetResources contains "Microsoft Graph" or TargetResources contains "Office 365 Exchange Online"
| extend ConsentData = parse_json(TargetResources)
| project TimeGenerated, InitiatedBy, TargetResources, ConsentData
- Client application mismatches:
DeviceDetail.isCompliant == false AND
DeviceDetail.trustType == "" AND
ClientAppUsed != "Browser" AND
LocationDetails.country != user's typical country
Critical Detection Gap: If streamlined logging is disabled, the AuthenticationProtocol field may not be populated. You may need to infer device code from:
AuthenticationProcessingDetails containing "device_code"
- Absence of normal device compliance/trust attributes
- Rapid token refresh patterns (refresh token rotation evasion)
Note that AuthenticationProtocol is known to be populated inconsistently across licensing tiers — it is more reliably present in premium tenants and may be absent or stripped in lower licensing configurations. The recommended detection pattern in those cases is correlating device code request events from one IP with subsequent token grants from a different IP within the standard 15-minute device code expiration window.
Microsoft's April 2026 research notes the campaign "demonstrated a higher success rate, driven by automation and dynamic code generation that circumvented the standard 15-minute expiration window for device codes." Hunt for device codes with unusually long lifetimes or reused codes.