Business Email Compromise (BEC) & Phishing Triage Playbook
Standard Operating Procedure for handling suspected Microsoft 365 / Exchange Online account takeover and Business Email Compromise (BEC).
⏱️ Phase 1: Immediate Containment (< 15 Minutes)
Section titled “⏱️ Phase 1: Immediate Containment (< 15 Minutes)”When an account is flagged as compromised, execute immediate containment steps:
1. Revoke Active Refresh Tokens & Reset Password
Section titled “1. Revoke Active Refresh Tokens & Reset Password”# Connect to Microsoft GraphConnect-MgGraph -Scopes "User.ReadWrite.All"
$targetUser = "victim.user@company.com"
# 1. Invalidate all active session tokens immediatelyRevoke-MgUserSignInSession -UserId $targetUser
# 2. Force password change on next loginUpdate-MgUser -UserId $targetUser -PasswordProfile @{ ForceChangePasswordNextSignIn = $true Password = "TemporaryGeneratedStrongPassword123!"}2. Check and Block Malicious Sign-In Risk in Entra ID
Section titled “2. Check and Block Malicious Sign-In Risk in Entra ID”Verify if MFA was modified or if additional FIDO2/phone methods were registered by the attacker:
Get-MgUserAuthenticationMethod -UserId $targetUser | Select-Object Id, @{N='Type';E={$_.'@odata.type'}}🔍 Phase 2: Forensic Mailbox Scoping
Section titled “🔍 Phase 2: Forensic Mailbox Scoping”Adversaries establish covert persistence inside mailboxes to intercept invoices, monitor threads, and delete alerts.
1. Audit Inbox Rules & External Forwarders
Section titled “1. Audit Inbox Rules & External Forwarders”# Connect-ExchangeOnline$mailbox = "victim.user@company.com"
# Check Transport / Mailbox level forwardingGet-Mailbox -Identity $mailbox | Select-Object UserPrincipalName, ForwardingAddress, ForwardingSmtpAddress, DeliverToMailboxAndForward
# Audit all custom inbox rules (look for rules moving to RSS, Junk, or external addresses)Get-InboxRule -Mailbox $mailbox | Select-Object Name, Enabled, Priority, ForwardTo, RedirectTo, MoveToFolder, DeleteMessage | Format-List2. Audit Mailbox Folder Permissions & Delegates
Section titled “2. Audit Mailbox Folder Permissions & Delegates”Adversaries often grant SendAs, SendOnBehalf, or FullAccess to another compromised tenant account.
# Check Full Access DelegatesGet-MailboxPermission -Identity $mailbox | Where-Object { $_.User -notmatch 'NT AUTHORITY' } | Format-Table -AutoSize
# Check Send As RightsGet-RecipientPermission -Identity $mailbox | Where-Object { $_.Trustee -notmatch 'NT AUTHORITY' } | Format-Table -AutoSize📱 Phase 3: Malicious OAuth Enterprise App Consent (Illicit Consent Grants)
Section titled “📱 Phase 3: Malicious OAuth Enterprise App Consent (Illicit Consent Grants)”Attackers trick users into granting permissions (e.g. Mail.ReadWrite, Offline_Access) to an external rogue Azure App Registration, allowing API access without needing passwords or MFA.
KQL Query: Hunt for Recent User App Consents
Section titled “KQL Query: Hunt for Recent User App Consents”AuditLogs| where TimeGenerated > ago(7d)| where OperationName in~ ("Consent to application", "Add delegated permission grant", "Add service principal")| extend ConsentingUser = tostring(InitiatedBy.user.userPrincipalName)| extend TargetApp = tostring(TargetResources[0].displayName)| extend PermissionsGranted = tostring(TargetResources[0].modifiedProperties[4].newValue)| project TimeGenerated, OperationName, ConsentingUser, TargetApp, PermissionsGranted, Result| sort by TimeGenerated descRemediation: Revoke Rogue OAuth Grant
Section titled “Remediation: Revoke Rogue OAuth Grant”# Remove malicious app consent grant via Microsoft GraphRemove-MgOauth2PermissionGrant -OAuth2PermissionGrantId "<OAuth2PermissionGrantId>"📊 Phase 4: Impact Analysis & Data Exposure
Section titled “📊 Phase 4: Impact Analysis & Data Exposure”Determine what emails the attacker accessed, read, or sent.
1. Identify Emails Sent by Attacker (Search-UnifiedAuditLog)
Section titled “1. Identify Emails Sent by Attacker (Search-UnifiedAuditLog)”Search-UnifiedAuditLog -RecordType ExchangeItem -Operations Send, SendAs -FreeText $targetUser -StartDate (Get-Date).AddDays(-3) -EndDate (Get-Date)2. Review MailItemsAccessed (E5 Feature)
Section titled “2. Review MailItemsAccessed (E5 Feature)”If your tenant possesses Purview Audit (Premium), query MailItemsAccessed in Log Analytics to identify specific message IDs read or synced via Bind / Sync actions.
CloudAppEvents| where TimeGenerated > ago(7d)| where ActionType == "MailItemsAccessed"| where RawEventData.UserId =~ "victim.user@company.com"| extend MailAccessType = tostring(RawEventData.OperationProperties[0].Value)| extend FoldersAccessed = RawEventData.Folders| project TimeGenerated, AccountDisplayName, IPAddress, MailAccessType, FoldersAccessed🛡️ Phase 5: Post-Incident Hardening Checklist
Section titled “🛡️ Phase 5: Post-Incident Hardening Checklist”- Clear all unauthorized Inbox and Forwarding rules.
- Remove rogue OAuth permission grants.
- Audit MFA methods and re-register authenticators.
- Notify finance/payroll if payroll changes or invoice details were discussed in affected threads.
- Submit phishing message samples to Defender for Office 365 for tenant-wide blocklisting.