Skip to content

Device-code phishing, then an AI reads the inbox

EvilTokens did not steal passwords and did not defeat MFA. It asked victims to type a legitimate Microsoft code into a legitimate Microsoft page, which authorized the attacker's session — and the access survived every password reset that followed.

eviltokens phishing servicedevice code phishing detectionphishing as a service takedown

EvilTokens launched in February 2026 and sold on Telegram for a $1,500 initiation fee and $500 a month. Microsoft's Digital Crimes Unit took it offline in October 2026 under court authorization, working with Cloudflare, and the Metropolitan Police arrested two men in the UK. Microsoft linked the platform to more than 12,000 compromised inboxes across over 10,000 organizations.

Two parts are worth understanding separately: how it got in, and what it did once inside. The first defeats MFA without attacking it. The second is the part that turns a compromised mailbox into money.

The mechanism

Device-code authorization exists for devices that cannot show a sign-in form — smart TVs, printers, conferencing hardware. The device displays a short code, the user types it into a real Microsoft page on their phone, and the device gets a token. Every part of that flow is legitimate.

EvilTokens initiated the flow itself and delivered the code to the victim with a plausible lure. The victim typed it into the genuine Microsoft page, signed in, and completed MFA correctly — and in doing so authorized the attacker's session. No password was handed over. The phishing page does not need to look like Microsoft, because the page the victim uses is Microsoft. And because the result is a token, the access persisted even when passwords were changed afterwards.

EvilTokens — access to monetisationFeb–Oct 2026 · 12,000+ inboxes · 10,000+ organizations
StageWhat happenedWhat it defeats
LureVictim is sent a device code to enteremail filtering — the link is Microsoft's
GrantVictim signs in and completes MFAMFA, by using it rather than bypassing it
TokenAttacker's session is authorizedpassword resets — the token survives them
TriageAI reads the inbox in minutesthe time it used to take to find value
FraudImpersonate a 'money mover' on a real threadrecipient suspicion — the thread is genuine

The second half is what the subscription actually bought. Going through a breached inbox to find something worth stealing used to take days or weeks of an operator's time. EvilTokens shipped preset prompts that did it in minutes: find the wire-transfer discussions, identify the organization's money movers, locate vendor invoices, and determine the best people to impersonate. It came with dozens of pre-built templates and landing pages and an assistant for writing target-specific messages. Microsoft's examination noted that the platform itself was largely built with language models.

What we would have seen, and what we would not

This is the weakest column in Hanu's coverage map, and it is worth being precise about where the line falls. Hanu reads directory and audit logs from Entra, M365, GitHub, Okta and Google Workspace, through five audit-log engines that run behavioural rules over the events. It does not ingest Entra sign-in logs.

That boundary matters here. The device-code grant itself appears in the sign-in log, with the authentication protocol recorded — so Hanu would not have caught the grant. Detection starts at what the token does next.

  • RULE-BEH-IDP-ENTRA-003 catches Consent to application with high-privilege mail, files or directory scopes — the related consent-phishing path, and the one GhostAction's follow-on wave used against GitHub.
  • RULE-BEH-IDP-M365-002 catches bulk mailbox export, which is the sanctioned way to do what EvilTokens automated.
  • RULE-BEH-IDP-M365-001 catches an external forwarding rule — the persistence step that keeps the mail flowing after the token is revoked, and a reliable precursor to invoice fraud.
  • RULE-BEH-IDP-ENTRA-002 catches a new credential added to a service principal, and RULE-BEH-IDP-ENTRA-001 catches a conditional access policy being weakened. Both are post-access moves that make the intrusion durable.
  • RULE-BEH-IDP-ENTRA-005 catches anomalous PIM role activation, and impossible-travel rules catch a session appearing somewhere its owner cannot be.

What to do

  1. 01

    Turn the device-code flow off for people

    Almost nobody needs it. A Conditional Access policy blocking device-code authentication, scoped to allow the specific hardware that genuinely requires it, removes the attack rather than detecting it. This is the single highest-value change on this page.

  2. 02

    Revoke sessions, not just passwords

    A password reset does nothing to a token. Incident response for this class has to revoke refresh tokens and sign-in sessions explicitly, or the attacker keeps the access they already have while the user picks a new password.

  3. 03

    Review OAuth consent as an access-control surface

    Restrict user consent to applications, require admin approval for the high-privilege Graph scopes, and review existing grants. The grant is what outlives everything else, so it is the thing to govern.

  4. 04

    Alert on the fraud mechanics, not the phish

    External forwarding rules, mailbox exports, mailbox permission changes, and new payment-detail changes on an existing vendor thread. These are the observable steps between access and loss, and they are observable even when the access itself was invisible.

Our MFA is phishing-resistant. Does that help?
Against a reverse-proxy page, yes — hardware-bound credentials do not relay. Against device-code phishing, not on its own: the victim completes a genuine, fully compliant sign-in, and what they authorize is a separate session. The control that stops it is Conditional Access blocking the device-code flow for users who do not need it, not a stronger authenticator.
The platform was taken down. Is this over?
The service is, and two people were arrested. The technique is not, and it is cheap to rebuild — this was a $500-a-month subscription whose code was largely written by a language model. Treat the takedown as the removal of one supplier in a market, and the device-code flow as the thing to configure.
Would Hanu have alerted on the 12,000 inboxes?
Not at the moment of the grant, no — that evidence is in the Entra sign-in log, which Hanu does not read. It would have alerted on what came next in the accounts where the attacker acted: an external forwarding rule, a bulk mailbox export, a risky OAuth consent, a new service principal credential, a weakened conditional access policy. That is detection of the intrusion's effects rather than its entry, and we would rather say so than imply otherwise.
Why is the AI part a detection problem rather than a content problem?
Because the output is not detectably synthetic in any way that helps. The fraudulent message arrives on a real thread, from a real colleague's real mailbox, referring to a real invoice, because the model read the thread to write it. Filtering cannot distinguish it. What remains detectable are the mechanical steps around it — how the access was kept, what was exported, what was forwarded, which payment detail changed on an existing thread.

Run it in your own account

One Docker Compose stack, your datastores, read-only credentials into your clouds. The Community edition is free to run in production.