Threat Intelligence
Your MFA Is Working Exactly as Designed. That Is the Problem.
How attackers steal Microsoft 365 tokens, register devices, add FIDO keys, and read your mail without ever knowing your password.
As an adversary operations group (AOG) analyst, I spend my days looking at how real attackers break into Microsoft 365. Not the theoretical stuff. The actual intrusions. The ones where the SOC escalate to the CIRT team because “we don’t know how they got in.”
Here is what I keep seeing: a device code phishes for a captured token, and then within 15 minutes a rogue device is registered in Entra ID. Within an hour, an attacker is reading mail, downloading SharePoint files, and adding their own FIDO2 key to the account.
The victim changed their password. It did not matter.
The Token Problem
Microsoft 365 uses OAuth 2.0. Tokens are bearer credentials. Whoever holds the token is the user. The system does not check who you are. It checks what you hold.
There are five types of tokens in play:
- Access tokens live for 60-90 minutes. They are what the API checks. Short-lived by design but once issued they cannot be revoked unless you have Continuous Access Evaluation enabled. Most organizations do not.
- Refresh tokens live for 90 days. They silently mint new access tokens in the background. This is why you do not have to log in every time you open Outlook. It is also why a password reset fails as a remediation. Refresh tokens survive password changes. Microsoft designed them this deliberately. They are not a bug.
- Primary refresh tokens are device-bound super-tokens. One PRT can mint access tokens for any application in the tenant. This includes Outlook, Teams, SharePoint, OneDrive, Intune, the Microsoft Graph API, every first-party Microsoft service, and any third-party app federated through Entra ID. A PRT is the closest thing to a skeleton key in modern identity.
- Device tokens are bound to a registered device. They satisfy device-based conditional access policies. If your conditional access policy says, “require compliant device” and an attacker registers a rogue device, that policy is satisfied.
- FOCI tokens exploit Microsoft’s Family of Client IDs. A refresh token obtained for one first-party app (Teams) can mint access tokens for any other FOCI app (Outlook, SharePoint, OneDrive). This is designed for seamless SSO. It also means one successfully phished device code unlocks the entire Microsoft ecosystem.
How the Attack Actually Works
The attacker requests a device code from Microsoft’s legitimate OAuth endpoint. They use a known FOCI client ID, often the Microsoft Authentication Broker. No custom infrastructure needed. No fake login page.
They send that code to the victim via Teams, email, or SMS. The message looks like this: “Please verify your device at microsoft.com/devicelogin and enter code ABCD-1234.”
The victim goes to Microsoft’s real login page. They enter their password. They complete MFA. Everything looks legitimate because it is legitimate. The user is authenticating on Microsoft’s own website.
Meanwhile, the attacker is polling the token endpoint every five to 10 seconds. As soon as the victim completes authentication, Microsoft hands the tokens to the attacker’s polling client. The attacker never sees the password. Never sees the MFA code. They do not need to. They have something better. They have the tokens.
This is not a phishing page bypass. This is the legitimate Microsoft authentication ceremony being used as a token delivery mechanism. MFA did not fail. MFA worked exactly as designed. The user completed MFA. Microsoft issued tokens. The attacker received them.
What Happens Next
Within minutes of capturing the token, the attacker registers a device in Entra ID. They call POST /v1.0/devices with a device name like GraphSpy-Device-07, operating system Windows, version 10.0.26100. The device is now a recognized member of the tenant. It satisfies any conditional access policy that checks for device compliance.
From the registered device, the attacker requests a primary refresh token. The PRT is bound to the attacker-controlled device. It can mint access tokens for any application. It is valid for 90 days. It survives password resets.
The attacker then enrolls Windows Hello for Business on the rogue device. This happens server-side. No physical TPM required. The server returns a credential that can generate new PRTs even after the current one expires.
The attacker adds a FIDO2 security key to the victim’s account. They call POST /v1.0/users/{id}/authentication/fido2Methods. The key is now a recognized authentication method. The attacker can sign in as the user without knowing the password. No MFA challenge. Just the FIDO2 key they added themselves.
Now the attacker reads mail (GET /me/mailFolders/inbox/messages). They search for passwords, reset links, MFA registration emails, financial documents. They create inbox rules to forward specific emails to an external account. They send emails as the victim to further their access.
They access OneDrive (GET /me/drive/root/children). They download files. They move to SharePoint (GET /sites/{id}/drive/root/children). They enumerate Teams channels (GET /teams/{id}/channels/{id}/filesFolder). They download everything.
All of this happens through the Microsoft Graph API. No malware. No unusual processes on the endpoint. The attacker never touches the victim’s device. They operate entirely through API calls authenticated with stolen tokens.
Why Password Reset Does Not Work
Here is the structural flaw in most incident response playbooks.
The standard response to a compromised account is disable the account, reset the password, re-enable.
This does not revoke OAuth refresh tokens. The attacker’s tokens remain valid. They continue minting new access tokens silently through non-interactive sign-in. The victim changes their password. The attacker does not care. They are not using the password.
The correct sequence is:
- Call revokeSignInSessions for the affected user. This invalidates all existing refresh tokens and browser session cookies.
- Remove any devices the attacker registered in Entra ID.
- Remove any authentication methods the attacker added, including FIDO2 keys, WHfB enrolment, and phone numbers.
- Revoke any OAuth consent grants the attacker approved.
- Reset the password.
- Re-enable the account.
Monitor for 72 hours for any non-interactive sign-in attempts from unfamiliar IPs.
Steps 1 through 4 must happen before step 5. Every playbook I review gets this wrong.
What Defenders Miss
Three detection gaps keep showing up.
- Nobody looks at the AuthenticationProtocol field in Entra ID sign-in logs. It is right there. It says deviceCode when the sign-in used device code flow. But most SOC teams are not querying it. They look at failed logins, impossible travel, and known bad IPs. Those indicators do not catch device code phishing because the authentication is successful and the IP belongs to the user, not the attacker.
- Device registration events are not monitored. Entra ID generates an audit event every time a device is registered. But most organizations have no alerting on this. An attacker can register a rogue device in your tenant, and nobody notices unless they are specifically looking for it.
- Nobody correlates authentication events with post-authentication behaviour. The highest-confidence signal is not the sign-in itself. It is what happens after. The inbox rule created 10 minutes after a device code auth. The bulk mail read. The FIDO2 key addition. These behavioural signals are obvious in retrospect but invisible without correlation.
What You Should Do
- Block device code flow via conditional access. Get as close to a unilateral block as your environment allows. Microsoft’s own guidance says to do this. Most organizations have not done it because they are afraid of breaking something. Audit first. Then block.
- Deploy detection queries. Monitor AuthenticationProtocol equals deviceCode. Monitor device registration events. Correlate authentication with behavior. The queries are straightforward. They run in Sentinel or Defender. You need about four of them to cover the entire attack chain.
- Audit your existing OAuth consents. I guarantee you have applications with Mail.Read and Files.ReadWrite.All that nobody approved. Revoke them.
- Update your incident response playbooks. If your playbook for a compromised account says “reset password” and stops there, it is incomplete. You need token revocation. You need device removal. You need authentication method review. These are not optional steps.
- And if you are still using passwords as your primary authentication method, stop. Move to FIDO2 security keys or Passkeys. Phishing-resistant authentication does not produce reusable tokens. That is the long-term fix.
The Bottom Line
Token theft is not exotic. It is not a nation-state capability. It is a push-button attack available to anyone who can send a Teams message. The tools are open source. The technique is documented. The only thing standing between an attacker and your Microsoft 365 data is whether your SOC knows where to look.
Most do not. That needs to change.