More than 12,000 Microsoft accounts lost mailbox control after users typed an attacker-supplied device code on the real microsoft.com device-login page and finished normal sign-in, including MFA. According to the Microsoft Security Blog, EvilTokens PhaaS (tracked to Storm-2992) then received OAuth access and refresh tokens on the attacker’s polling client, unlocking persistent mail, Graph reconnaissance, malicious inbox rules, and AI-assisted BEC targeting across over 10,000 organizations. Preventing Microsoft 365 device code flow phishing is Conditional Access denial of the grant, fast token revocation, and locked-down device enrollment. Login MFA, including phishing-resistant factors, does not retract tokens the user already authorized to someone else’s client.
What EvilTokens took after a finished Microsoft sign-in
EvilTokens did not scrape passwords from a fake form. From February 2026 until disruption on 22 September 2026, the kit socially engineered workforce users to enter a live device code, complete authentication on Microsoft’s legitimate endpoint, and unknowingly authorize the operator’s session. Microsoft’s disclosure states the outcome cleanly: "When the user enters the code, they unknowingly authorize the threat actor’s session, granting access to the account without exposing credentials."
The commercial package mattered. The kit sold on Telegram for about $1,500 up front plus $500 per month, with 44 phishing themes and short-lived Node.js polling nodes watching the roughly 15-minute approval window. Roughly 97% of victim domains were enterprise. Highest observed activity concentrations sat in the United States, Canada, the United Kingdom, Australia, India, and France, spanning wholesale distribution, construction, financial services, real estate, higher education, and healthcare. Stolen tokens refreshed automatically. Operators mapped Graph, hid mail with malicious inbox rules, and in some cases registered new devices for longer persistence. Public reporting does not establish per-organization victim counts, total financial loss, or named primary victim organizations.
If you want more detailed information about this attack, read the related post on legacymfa.sucks: how EvilTokens industrialized device-code OAuth token theft.
Why finishing tenant MFA still left the mailbox open
Initial access stole bearer tokens after authentication, not a password or OTP seed from a proxied page. The user completed whatever MFA the tenant already required (push, TOTP, or another enforced method) on the real identity provider. Tokens issued to the client that had requested the device code. That client belonged to Storm-2992.
Legacy MFA failed here for a structural reason, not because a prompt was ignored on a fake origin. The OAuth 2.0 device authorization grant is built so a limited-input device can obtain tokens once a user approves a code on a full browser. EvilTokens pointed ordinary Microsoft 365 users at that grant. When MFA succeeded, issuance was the intended protocol outcome. There was no second challenge left at a login form for OTP or push to catch. Calling this an MFA bypass misstates the timeline. Authentication had already succeeded before the transferable prize existed.
Persistence made the same point louder. Refresh tokens auto-renewed access long after the ceremony. Malicious inbox rules concealed exfiltration. Some operators registered additional devices while they still held a valid session. Long-lived cloud sessions and post-auth device registration outlived the original MFA event. Shortening token lifetime alone does not prevent the first successful grant. It only forces re-use or re-theft sooner. If the operator enrolls their own authenticator during the window, lifetime limits stop mattering for the new factor they now hold.
Data access sat entirely after authentication. With valid Microsoft 365 tokens, attackers read mail and called Graph without another interactive login. SSO and federation amplified the blast radius: one cloud identity plane opened mail, files, and APIs that trust the same session material. Classic SSO auto-sign-on collides with zero-trust language here. One proof unlocked many doors, and the proof already sat with the wrong party.
| Phase | What was abused | What login MFA could still do |
|---|---|---|
| Initial access | Device-code grant to attacker client | Nothing after willing real MFA success |
| Persistence | Refresh tokens, inbox rules, new devices | No revoke of already-issued material |
| Mail and Graph use | Bearer tokens post-auth | No further prompt on API calls |
Phishing-resistant login factors do not change that table when the user willingly finishes the real device-code approval. The control gap is the still-enabled grant shape and slow cleanup after issuance, not a missing second digit on a spoofed password field.
What phishing-proof MFA changes, and what it cannot retract
Device-bound, phishing-proof authentication removes transferable secrets at registration, onboarding, authorization, authentication, and decommissioning. That matters for many workforce phishing paths. It does not undo OAuth access and refresh tokens already issued after a user completes a legitimate Microsoft device-login ceremony and approves an attacker-generated code. MFA 2.0 does not retract mailbox or Graph rights granted by those tokens. Stronger cryptography at a prompt the user already finished cannot rewind issuance.
The useful identity work sits beside the login factor, not instead of Microsoft’s own guidance. Microsoft recommends blocking device code flow wherever possible through Conditional Access, with tight exceptions only where the business truly needs it (for example certain Teams device resource accounts). Revoke sessions and tokens on suspicion. Prefer phishing-resistant MFA as layered hygiene at interactive sign-in, paired with monitoring. Those controls address what EvilTokens sold: a coached approval against a still-enabled grant.
Where phishing-proof MFA still changes the residual story is enrollment policy after the first token lands. Some EvilTokens cases registered new devices for longer-lived access. If adding a device requires an already-enrolled device and never hands IT or the user a transferable enrollment code, the operator cannot casually mint a durable second factor from a stolen refresh window alone. Credit the enrollment gate, not a fantasy that login MFA erases tokens already in attacker hands. The enrollment model that refuses phishable recovery secrets is the lifecycle piece that narrows that persistence move.
SSO blast radius remains a separate design problem. A single stolen cloud token that every integrated app trusts fails never-trust, always-verify. MFA 2.0 does not recommend classic SSO. Secure Explicit Sign-On keeps one-tap user experience while each application receives its own fresh, device-bound signature. No shared, reusable federation cookie exists to replay across mail, files, and CRM after one bad grant. That shrinks what a stolen Microsoft 365 session can open even when revoke races the attacker.
Prevention framing for this kit stays precise. Closing the phishable path in other campaigns means stopping a fake or proxied login before a session exists. EvilTokens completed a real login. Closing this path means refusing device code flow for users who do not need it, killing tokens fast, and refusing phishable device onboarding. Fooling a user into approving a real device code is social engineering against an enabled grant. Planting malware on an already-logged-in PC to scrape memory is a harder, separate problem. EvilTokens scaled the first path. Prevention, not detection, still owns the design goal: remove the grant and the transferable enrollment secrets so the kit has nothing useful to harvest or extend.
| Control | Against device-code approval | Against tokens already issued |
|---|---|---|
| Push or TOTP at real login | User can still approve | Cannot revoke tokens |
| Passkeys at interactive login | User can still approve device code | Cannot bind foreign refresh tokens |
| CA block on device code flow | Stops the grant shape | N/A if never issued |
| Fast session and token revoke | Hygiene after suspicion | Primary containment |
| Phishing-proof enrollment | Limits attacker device add | Shrinks durable persistence |
| Secure Explicit Sign-On | Limits multi-app replay | Shrinks SSO blast radius |
Passkeys and FIDO2 on a real device-login page
Passkeys and FIDO2 put a key pair in hardware. The private key never leaves the device, and signatures are origin-bound to the real relying party. Industry language correctly calls that phishing-resistant at the login act: a reverse-proxy kit cannot replay the ceremony to a fake origin the same way it relays passwords and OTP. On a generic enterprise IdP that only accepts hardware-bound signatures, the user proves possession locally. That hardens ordinary interactive sign-in. It does not, by itself, refuse an OAuth device authorization grant the tenant still allows, and it does not un-issue tokens after the user willingly approves a code on the legitimate Microsoft device-login page.
The enrollment gap EvilTokens could still abuse
FIDO2 and passkeys are phishing-resistant at authentication only. If email OTP, SMS, push, or helpdesk-read secrets still onboard a new device, an operator who already holds a cloud session can chase that weaker gate. EvilTokens sometimes registered new devices after token theft. Full-lifecycle phishing-proof coverage means no phishable factor appears at registration, device onboarding, authorization, authentication, or decommissioning. Resistant login plus a phishable enrollment path still leaves a persistence hole. Proof closes that hole only when the already-enrolled device is the sole gate for adding another.
Key Takeaways for Defenders
- Disable Microsoft 365 device code flow in Conditional Access for workforce users who do not need it; keep exceptions narrow and inventoried.
- On any suspicion of EvilTokens-style mail theft, revoke refresh and access tokens immediately and review newly registered devices.
- Hunt malicious inbox rules and unusual Graph activity rather than waiting for another MFA prompt that will never appear.
- Require already-enrolled hardware for any new device registration so stolen sessions cannot casually mint durable second factors.
- Prefer per-app, device-bound explicit sign-on over one shared SSO token that turns a single grant into a skeleton key.
The forward path for device-code OAuth theft is architectural refusal of the grant and of transferable enrollment secrets. Stronger prompts after the user already said yes on microsoft.com are not a substitute.
FAQ
Would passkeys alone have stopped EvilTokens from receiving M365 tokens?
No. Passkeys alone would not have stopped EvilTokens from receiving Microsoft 365 OAuth tokens when users willingly completed the real device-code approval. Victims authenticated on legitimate microsoft.com, finished whatever MFA the tenant required, and Microsoft issued access and refresh tokens to Storm-2992’s polling client. Passkeys are phishing-resistant at interactive login. They do not disable the OAuth 2.0 device authorization grant or retract tokens after a completed real ceremony.
What should security teams configure first to prevent Microsoft 365 device code flow phishing?
Security teams should block device code flow through Conditional Access wherever the organization does not truly need it, following Microsoft’s EvilTokens guidance, then pair that block with rapid session and token revocation playbooks. Tight exceptions (such as specific Teams device resource accounts) must stay inventoried. Prefer phishing-resistant MFA at interactive sign-in as hygiene, not as a claim that willing device-code approval becomes harmless while the flow stays enabled.
Does MFA 2.0 undo OAuth refresh tokens stolen in the EvilTokens campaign?
No. MFA 2.0 does not undo OAuth refresh tokens stolen after users finished real Microsoft authentication in the EvilTokens campaign. Phishing-proof device-bound credentials prevent many remote login harvests by removing transferable factors across the identity lifecycle, but tokens already issued to an attacker client are a post-authentication containment problem. Revoke, Conditional Access denial of device code flow, and strict device enrollment policy are the controls that address that residue.
Why does MFA 2.0 avoid classic SSO after a breach like EvilTokens?
MFA 2.0 avoids classic SSO because one stolen Microsoft 365 session token can unlock every integrated app without a fresh proof, which is exactly the blast radius EvilTokens operators enjoyed for mail and Graph. Secure Explicit Sign-On keeps one-tap UX while each application gets its own fresh, device-bound signature. No shared, reusable federation cookie exists to replay across the estate after a single bad grant.
How does phishing-proof enrollment limit EvilTokens-style persistence?
Phishing-proof enrollment limits EvilTokens-style persistence by refusing phishable factors when a new device is added, so an operator holding a stolen refresh token cannot complete onboarding with SMS, email OTP, push, or helpdesk-read secrets. Some EvilTokens cases registered new devices for longer-lived access after the initial token theft. Requiring an already-enrolled device for any additional enrollment narrows that path. Login cryptography alone does not.