Compromised Microsoft 365 account response runbook
By Emil Björk · Microsoft ecosystem consultant, Gothenburg
Compromised Microsoft 365 account runbook: what to run in the first fifteen minutes, what to check in the first hour, and when it is safe to hand it back.
9 min read
Share as imagePNGThis is the runbook for the moment the alert is no longer "suspicious" but confirmed: someone other than the user is signed in. It is deliberately ordered. The order matters more than the speed, because the two most common mistakes — resetting the password before revoking sessions, and cleaning up before recording evidence — both make the incident longer.
If the account is a mailbox being used for fraud, the BEC response playbook covers the money side. If you are still deciding whether it is compromised at all, start with the sign-in log investigation runbook. This guide assumes you already know.
Before you touch anything: thirty seconds of evidence
Two things, and only two, before containment:
- Note the time (UTC) you declared the incident and the user principal name. Everything you search later is anchored on these.
- Open the user's sign-in logs in the Entra admin center and leave the tab open. You will filter it later; right now you just want the last 24 hours in front of you before anything you do adds noise.
Do not export mailboxes, do not screenshot every rule, do not start a Word document. Containment first.
The first fifteen minutes: containment
Run these in this order. Each step assumes the previous one is done.
- Disable the account. Entra admin center, or
Update-MgUser -UserId user@contoso.com -AccountEnabled:$false. This stops new token issuance. It does not stop tokens already issued — hence step 2. - Revoke sessions.
Revoke-MgUserSignInSession -UserId user@contoso.com. This invalidates refresh tokens, so every client has to reauthenticate — and cannot, because the account is disabled. Access tokens already in hand live until they expire, which is typically about an hour for most Microsoft 365 workloads; Continuous Access Evaluation shortens that dramatically for Exchange, SharePoint and Teams. - Reset the password to a long random value the user does not know yet. Do this after revocation: a reset alone does not kill existing refresh tokens on every client type.
- Mark the user as compromised in Entra ID Protection (Risky users → Confirm compromised). This raises the user's risk to High so any risk-based Conditional Access policy bites immediately, and it teaches the detection engine.
- Reset MFA. Entra admin center → user → Authentication methods → Require re-register multifactor authentication, then delete any method you do not recognise. Attackers who have been in for more than a few minutes almost always register their own Authenticator or a new phone number.
- If the user is an admin, remove all role assignments and PIM eligibilities now, and check whether any other admin account was touched from the same session. An attacker in a Global Administrator account for an hour can leave persistence you will not find in the user's own mailbox.
If you run Defender XDR with automatic attack disruption enabled, steps 1, 2 and 4 may already have happened. Check the incident before repeating them — but repeating them is harmless.
The first hour: persistence hunting
The attacker's goal in the first hours of any compromise is to survive the password reset. Check every one of these — not the ones you think are likely.
Mailbox
- Inbox rules:
Get-InboxRule -Mailbox user@contoso.com | Format-List Name,Enabled,Description. Look for rules that delete, move to RSS Feeds or Archive, or forward. Rules with blank names are a classic tell. - Forwarding:
Get-Mailbox user@contoso.com | Format-List ForwardingAddress,ForwardingSmtpAddress,DeliverToMailboxAndForward. - Delegates and Send As:
Get-MailboxPermissionandGet-RecipientPermissionon the mailbox. Remove anything added in the window. - Mailbox audit:
Search-UnifiedAuditLog(or the Purview audit search) for the user over the incident window — look forNew-InboxRule,Set-Mailbox,Add-MailboxPermission,MailItemsAccessed, andSearchQueryInitiatedevents. The last two tell you what the attacker read and searched for.
Identity
- OAuth consents:
Get-MgUserOauth2PermissionGrant -UserId user@contoso.com. Any grant to an app you do not recognise, particularly one requestingMail.Read,Mail.Send,Files.ReadWrite.Alloroffline_access, is persistence. Revoke it, and then check whether the same app has grants from other users. - Registered devices: Entra admin center → user → Devices. A newly registered or joined device you do not recognise gets deleted, and if it was joined it also gets a look in Intune.
- Authentication methods: already reset in containment, but confirm that the list is now empty apart from what the user will re-register.
- Application-level: if the user owned any app registrations, check whether new client secrets or certificates were added. This is the most commonly missed persistence mechanism.
Collaboration
- SharePoint and OneDrive sharing: audit log operations
SharingSet,AnonymousLinkCreated,SharingInvitationCreatedfor the user. An attacker who has read the mailbox often shares a folder externally as a second exit. - Teams: check for new external chats, new apps installed to the user's scope, and any meeting join links sent out.
Record what you find as you go. A short bullet list with timestamps is enough; you are writing for the person doing the post-incident review, not a court.
Scope: was it only one account?
Take the attacker's IP addresses and user agents from the sign-in log and search all sign-ins for them over the last 30 days. In Defender XDR, AADSignInEventsBeta and EmailEvents in advanced hunting answer this in one query; in Entra alone, the sign-in log filter on IP address works. Every account that shares an indicator goes through this runbook too.
Then look at what the compromised account sent: message trace from the mailbox over the window, and any outbound messages with attachments or links. Recipients inside your organisation who clicked are your next candidates.
Handing the account back
Do not re-enable until every one of these is true:
- Persistence checks above are complete and everything found is removed.
- The user has been spoken to — by phone or in person, not email — and knows a new password and MFA registration are coming.
- MFA re-registration happens with a human from IT present or on a call. Attackers have been known to sit in the re-registration window.
- Any device the attacker signed in from that belongs to the user has been reviewed, or wiped if you cannot prove it is clean.
- A Conditional Access policy that requires MFA — ideally phishing-resistant — actually applies to this user. If the account was compromised because it was excluded from CA, fix the exclusion before re-enabling.
Then: enable the account, set the password to a value delivered out of band, have the user sign in and register methods, and watch the sign-in log for the next 48 hours. Clear the Risky user flag only after the user's first clean sign-ins.
What needs support, and what needs downtime
Nothing in this runbook requires Microsoft support. The one exception is if the compromised account was the only Global Administrator and the attacker changed the recovery details — that becomes a tenant-recovery case with Microsoft, and it is slow, which is why break-glass accounts exist.
Downtime is limited to the affected user, for however long persistence hunting takes. Resist pressure to shorten that window. An account re-enabled with an inbox rule still in place is the start of the next incident, not the end of this one.
Worked example: a phished finance-team account, minute by minute
09:14 — A finance-team user reports a suspicious "invoice approval" email they clicked, entering their password and MFA code on a look-alike login page. The alert reaches IT at 09:22.
09:23 — Containment starts. The account is disabled, sessions are revoked, and the user is marked compromised in Identity Protection. Password reset follows immediately after — the responder resists the reflex to reset the password first, since that alone would not have killed the refresh token the phishing page just captured.
09:31 — MFA reset finds the problem: the attacker registered a new Authenticator app registration at 09:18, four minutes after the phish, using the stolen session before it was revoked. It is deleted; the user's original phone-based method is left in place for now since it predates the incident.
09:40 — Persistence hunting starts. An inbox rule created at 09:19 named nothing (blank display name) forwards any message containing "wire" or "invoice" to an external address and then deletes it from the inbox. This is the actual objective — the attacker was staging a follow-on invoice-fraud attempt against the finance team's outgoing payments, not just reading mail.
09:52 — OAuth consent check finds nothing unusual; the attacker's four-minute window was too short to add an app registration. Scope check against the attacker's IP and user agent across the last 30 days turns up no other account.
10:15 — The user is called, not emailed, and told what happened. MFA re-registration happens on that call with IT watching the screen share.
11:30 — Account re-enabled, sign-in log watched through the afternoon, no further anomalies. The blank-named inbox rule and its exact forwarding condition are documented for the post-incident review, since it is specific enough to be worth a detection rule of its own going forward.
The lesson that generalises: the four minutes between the phish and containment were enough for the attacker to establish a mailbox rule but not enough for OAuth-app persistence or lateral movement — and the actual objective (a forwarding rule aimed at payment-related mail) would have been invisible without deliberately checking every persistence mechanism in the first-hour list, not just the one that looked most likely.
MSP checklist
- Confirm which tenant an alert belongs to before starting containment — a shared SOC dashboard across many client tenants makes it easy to run a step against the wrong customer's user under time pressure.
- Keep break-glass and emergency-access procedures documented per client, not assumed to be identical, since Conditional Access exclusions and admin role assignments vary between them — see Conditional Access break-glass accounts.
- Confirm which clients have Defender XDR automatic attack disruption enabled before assuming steps 1, 2, and 4 already happened — a client on a lower licensing tier needs every containment step run manually.
- After the incident, brief the client in plain language (what happened, what was contained, what changed) separately from the internal technical write-up — the two audiences need different levels of detail, and a client-facing summary that reads like an internal log erodes rather than builds confidence.
Frequently asked questions
- What are the first steps when a Microsoft 365 account is compromised?
- Revoke sessions, block sign-in, reset the password, and delete unrecognised MFA methods — in the first ten minutes, in roughly that order. Then remove inbox rules and forwarding, revoke suspicious app consents, mark the user compromised in Identity Protection, and only then investigate scope.
- How do I know what a compromised account accessed?
- Unified audit log for actions (files opened, emails sent, rules created, sharing links), Entra sign-in logs (interactive and non-interactive) for sessions, Defender for Office 365 Explorer for mail sent, and Defender for Cloud Apps activity log if licensed. Bound the window with the first suspicious sign-in and the containment time.
- When can a compromised account be handed back to the user?
- After the investigation has established scope, the password and MFA are new and registered on a trusted device, persistence (rules, forwarding, consents, devices) is removed, the risk is dismissed or remediated in Identity Protection, and the user has been briefed on what happened and what to watch for.
Further reading
Was this useful?
Spot something wrong or want a topic covered? Send it through the contact form.