Arctic Wolf tracked 126 phishing hosts running the same kit between May 6 and May 27, 2026, and every one of them was built around a single move: get a user to type a short code into the genuine Microsoft or Okta sign-in page. The victim authenticates, satisfies multifactor authentication, and the OAuth access and refresh tokens are issued to the attacker's application instead of the victim's browser. The sign-in record shows a clean, MFA-satisfied login from the right person at a plausible time. That is the Kali365 phishing-as-a-service operation, and in early June it stopped being only a Microsoft 365 problem: the same operator expanded the kit to Okta SSO, Xerox DocuShare, AWS-style targets, and a set of consumer platforms.
The belief that quietly fails here is the one most small teams are leaning on: we turned on MFA, so credential phishing does not really work against us anymore. Device-code phishing does not try to beat your MFA. It waits for the user to pass it, then leaves with the session token. The attacker never sees the password, never sees the one-time code, and never trips the "impossible travel" or "unfamiliar sign-in" signals the way a replayed credential would, because the human really did log in from their own machine.
Who needs to act on this: anyone whose staff sign in to Microsoft 365, Entra ID, or Okta, which for most companies is the entire workforce. The device code flow is available by default in both platforms. If your identity lives entirely on-premises with no cloud single sign-on and no Entra-joined devices, this particular token theft sits lower on your list, but that describes almost no business in 2026. If you run Entra ID or Okta, this one is yours, and the fix is a half-day of configuration you already own the license for.
How the device code flow turns a real login into a stolen session
The OAuth 2.0 device authorization grant exists for a good reason. It lets you sign in on a device that has no keyboard or browser, like a conference-room display, a smart TV, or a CLI tool, by showing a short code and asking you to finish the login on your phone or laptop. Microsoft documents the full handshake in its device code flow reference. The weakness is not in the protocol math. It is that the device requesting the code and the human approving it are never required to be the same person.
Kali365 turns that gap into a workflow. According to Arctic Wolf's analysis, the operator starts a device-code request against its own malicious app registration, receives a valid user code from Microsoft or Okta, and drops that code into a lure page that impersonates a OneDrive or SharePoint document with the loader text "Preparing your secure document." The victim is told to confirm at the real verification page. They open microsoft.com/devicelogin, type the code, log in, and approve. Tokens are issued to the attacker's app. Arctic Wolf observed JavaScript on the lure polling the operator panel every three seconds, waiting for the approval to land so the affiliate knows a fresh session is live.
Because the user authenticated at the genuine endpoint, the refresh token the attacker receives is fully valid and long-lived. It grants access to Outlook, Teams, and OneDrive with no password prompt and no further MFA challenge. The operation runs as a subscription business with a live command-and-control panel, affiliate recruitment over Telegram, and per-tenant session identifiers, so this is not one researcher's proof of concept. It is rented infrastructure aimed at whoever pays.
Why MFA, and even most phishing-resistant setups, miss this
The token is the prize, not the password. Standard MFA proves that a human stood at the device-code prompt and approved it; it does nothing to bind the resulting token to the device that originally asked for the code. That is the whole trick. A user with a strong authenticator, even a passkey, can still complete an attacker-initiated device-code request, because from the platform's point of view the sign-in is legitimate. Adding a stronger factor at the moment of login raises the bar for ordinary credential phishing, but it does not close this path on its own.
The control that actually matters is restricting the flow itself rather than stacking another factor on top of it. That is exactly what the FBI's Internet Crime Complaint Center recommended when it issued an alert on May 21, 2026 naming Kali365, as covered by Infosecurity Magazine: implement conditional access policies that block the device code flow, block authentication transfer, and exclude your emergency access accounts so you do not lock yourself out. The defensive question is not "do we have MFA," it is "can an attacker complete a device-code login in our tenant at all." For most organizations the honest answer today is yes.
Block the flow in Entra ID before you touch anything else
Microsoft now exposes the device code flow as a condition inside Conditional Access, and its authentication flows guidance is blunt: device code flow is a high-risk method that can be part of a phishing attack, and you should block it wherever possible. Work in this order.
1. Find out where you actually use it
Before you block anything, learn whether anything legitimate depends on it. Filter your sign-in logs by the device-code authentication protocol, or stand up the policy in report-only mode first. In Microsoft Sentinel or the Log Analytics workspace behind your tenant, this query surfaces the last two weeks of device-code sign-ins so you can see which users and apps rely on it.
// Entra ID sign-ins that used the OAuth device code flow, last 14 days
SigninLogs
| where TimeGenerated > ago(14d)
| where AuthenticationProtocol == "deviceCode"
| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress,
ClientAppUsed, ResultType, ConditionalAccessStatus
| sort by TimeGenerated desc
2. Create the blocking policy
Build a Conditional Access policy with Grant set to Block, and under Conditions choose Authentication flows and check Device code flow (block Authentication transfer in the same policy unless you have a reason to keep the desktop-to-mobile QR handoff). Exclude your break-glass accounts. If you genuinely use device code for Android conference-room devices, scope the block to everywhere except that network location rather than abandoning it.
3. Mind the protocol-tracking caveats
Two details bite people. First, if your policy targets all resources and you use device code for device registration, exclude the Device Registration Service (client ID 01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9) or you will break enrollment. Second, Entra now tracks the flow across token refreshes: a refresh token minted through device code stays subject to the policy, and a blocked one returns AADSTS530036 with a new "Original transfer method" property in the sign-in details set to Device code flow. That tracking is what makes the block stick rather than expiring with the first access token.
Okta is the same flow under a different name
If you front your apps with Okta, you have the identical exposure. Okta implements this as the Device Authorization grant type, identified by the parameter urn:ietf:params:oauth:grant-type:device_code, and per its developer documentation it must be enabled at two layers: on the app integration's allowed grant types, and on the authorization server's policy rule. That two-layer design is also your lever. Remove the Device Authorization grant from any native app integration that does not specifically need it, and drop it from the allowed grant types on custom authorization-server policy rules.
First, inventory what currently allows it. Run this against the Okta management API with a read-only token to list every app integration that still permits the device-code grant, then work the list down to the handful that have a real reason.
# Inventory Okta app integrations that allow the device authorization grant
curl -s -H "Authorization: SSWS ${OKTA_API_TOKEN}" \
"https://your-org.okta.com/api/v1/apps?limit=200" \
| jq -r '.[] | select(.settings.oauthClient.grant_types[]?
== "urn:ietf:params:oauth:grant-type:device_code")
| "\(.label)\t\(.id)"'
Hunt for the tokens already issued, then revoke them
Blocking the flow stops new thefts. It does nothing for sessions an attacker already holds, so assume some users completed a lure before you read this and go looking. Arctic Wolf published durable indicators worth turning into detections: the operator panel at panel.securehubcloud.com, the cluster of *.attachedfile.com subdomains (39 observed, all serving the same kit), and the template string "Preparing your secure document." Outbound traffic to those is a high-confidence sign of an active compromise. On the identity side, hunt for device-code sign-ins to unfamiliar applications, new OAuth app-consent grants, and inbox rules created shortly after one.
When you find a user who was phished, revoking the session is what actually evicts the attacker, because their access survives a password reset alone. The Microsoft Graph PowerShell module invalidates the refresh tokens and forces re-authentication; pair it with a review of recently granted app consents so you remove the attacker's application, not just its current token.
# Evict a session for a user suspected of completing a device-code lure
Connect-MgGraph -Scopes "User.ReadWrite.All","Directory.ReadWrite.All"
Revoke-MgUserSignInSession -UserId "user@contoso.com"
# Review recently granted OAuth app consents for an unfamiliar attacker app
Get-MgOauth2PermissionGrant -All |
Where-Object { $_.ConsentType -eq "Principal" } |
Select-Object ClientId, PrincipalId, Scope
Reset the password too, but understand the order of operations: revoke the session first, then rotate the credential, then remove any illicit consent grant. A password reset on its own leaves the stolen refresh token working until it expires on its own schedule, which can be weeks.
Block the flow, then revoke what it already minted
This week, run the sign-in-log filter to see who uses device code, stand up the Conditional Access policy in report-only mode, confirm nothing legitimate breaks, then flip it to block with your break-glass accounts excluded. Do the same audit on Okta, trimming the device-authorization grant off every app that does not need it. Finally, sweep for tokens already issued and revoke the sessions you cannot explain. For a small team without a dedicated identity engineer, this is a half-day of work against one of the cheapest, quietest ways an attacker gets into a cloud tenant, and it costs nothing beyond the licenses you already pay for.
Need help hardening your identity infrastructure?
We assess Active Directory, Entra ID, and Okta environments for the misconfigurations attackers actually exploit, including the authentication flows most teams never knew were on. Book a session to walk through your tenant with us.
