Business Email Compromise (BEC) Playbook¶
Financial Recall Window is Time-Critical
Wire transfers may be recoverable within 72 hours via bank callback. Contact the sending bank's fraud department immediately — before any other investigation step if a transfer has already been sent.
Metadata¶
| Field | Value |
|---|---|
| Playbook ID | IR-PB-002 |
| Severity | High (P2) — Critical if financial loss confirmed |
| RTO — Containment | < 2 hours |
| Financial Recall Window | < 72 hours (ACH/wire) |
| Owner | IR Lead |
| Co-owners | Finance, Legal, HR |
| Last Reviewed | 2025-01-01 |
Trigger Conditions¶
Activate this playbook on any of the following:
- [ ] Unusual login alert on executive or finance account (new geo, impossible travel, unknown device)
- [ ] Email forwarding rule created to external address post-login
- [ ] Wire transfer or ACH request originating from executive email, especially to new/changed account
- [ ] Finance team reports urgent payment request bypassing normal controls
- [ ] MFA push flood or phishing simulation failure on exec accounts
- [ ] SIEM alert: inbox rule creation + external forwarding within same session
- [ ] Vendor impersonation detected — payment redirect request on supplier invoice
Decision Tree¶
flowchart TD
A([BEC Trigger Detected]) --> B{Is account\ncompromised?\nActive session?}
B -- Yes --> C[Disable account\nRevoke all sessions\nReset credentials + MFA]
B -- Investigating --> D[Preserve logs\nDo not alert user yet]
C --> E{Was a financial\ntransfer sent?}
D --> E
E -- Yes --> F[URGENT: Bank Callback\nContact CFO + Finance\nFBI IC3 report]
E -- No --> G{Are mail forwarding\nrules present?}
F --> G
G -- Yes --> H[Remove forwarding rules\nAudit mailbox\nReview sent items]
G -- No --> I[Full mailbox audit\nHunt for additional\ncompromised accounts]
H --> I
I --> J{Additional accounts\ncompromised?}
J -- Yes --> K[Expand scope\nRepeat containment\nfor each account]
J -- No --> L[Proceed to\nEradicate phase]
K --> L
L --> M([Notify stakeholders\nRegulatory review]) Phase 1 — Contain (0–2 Hours)¶
1.1 Disable Compromised Account and Revoke Sessions¶
Microsoft 365 — PowerShell:
# Connect to Microsoft Graph / Exchange Online
Connect-ExchangeOnline -UserPrincipalName admin@company.com
Connect-MgGraph -Scopes "User.ReadWrite.All","Directory.ReadWrite.All"
# Disable the account
Set-MgUser -UserId "compromised.user@company.com" -AccountEnabled $false
Write-Host "[$(Get-Date -Format u)] Account disabled."
# Revoke all active refresh tokens (invalidates all sessions immediately)
Revoke-MgUserSignInSession -UserId "compromised.user@company.com"
Write-Host "[$(Get-Date -Format u)] All sessions revoked."
# Block sign-in via Azure AD Conditional Access (belt-and-suspenders)
Update-MgUser -UserId "compromised.user@company.com" -AccountEnabled:$false
Google Workspace:
# Using GAM (Google Apps Manager)
gam update user compromised.user@company.com suspended on
gam user compromised.user@company.com signout
1.2 Remove Malicious Mail Forwarding Rules¶
# List all inbox rules for affected user
Get-InboxRule -Mailbox "compromised.user@company.com" |
Select-Object Name, Enabled, ForwardTo, RedirectTo, ForwardAsAttachmentTo |
Format-Table -AutoSize
# Remove specific malicious forwarding rule
Remove-InboxRule -Mailbox "compromised.user@company.com" -Identity "Rule Name Here" -Confirm:$false
Write-Host "[$(Get-Date -Format u)] Forwarding rule removed."
# Audit ALL external forwarding rules across the organization
Get-Mailbox -ResultSize Unlimited |
ForEach-Object {
Get-InboxRule -Mailbox $_.UserPrincipalName |
Where-Object { $_.ForwardTo -or $_.RedirectTo -or $_.ForwardAsAttachmentTo } |
Select-Object @{n='Mailbox';e={$_.UserPrincipalName}}, Name, ForwardTo, RedirectTo
} | Export-Csv "external_forwarding_audit_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
# Disable SMTP forwarding (external) as emergency measure
Set-Mailbox -Identity "compromised.user@company.com" -DeliverToMailboxAndForward $false -ForwardingSmtpAddress $null
1.3 Revoke OAuth Tokens and Third-Party App Access¶
# List all OAuth app grants for the user
Get-MgUserAppRoleAssignment -UserId "compromised.user@company.com" |
Select-Object AppDisplayName, CreatedDateTime
# Revoke all OAuth2 permission grants
$grants = Get-MgUserOauth2PermissionGrant -UserId "compromised.user@company.com"
foreach ($grant in $grants) {
Remove-MgOauth2PermissionGrant -OAuth2PermissionGrantId $grant.Id
Write-Host "Revoked grant: $($grant.ClientId)"
}
1.4 Block Attacker IP and Session¶
# Extract attacker IP from sign-in logs
Get-MgAuditLogSignIn -Filter "userPrincipalName eq 'compromised.user@company.com'" -Top 50 |
Select-Object CreatedDateTime, IpAddress, Location, RiskState |
Sort-Object CreatedDateTime -Descending
# Add IP to Named Location block list (Conditional Access)
# Document attacker IP for firewall block rule — submit to network team
$attackerIP = "x.x.x.x"
Write-Host "Block $attackerIP on perimeter firewall and proxy — ticket: INC-XXXX"
Phase 2 — Eradicate (2–24 Hours)¶
2.1 Full Mailbox Audit¶
# Export mailbox audit log (last 90 days)
Search-MailboxAuditLog -Identity "compromised.user@company.com" `
-LogonTypes Delegate,Admin,Owner `
-StartDate (Get-Date).AddDays(-90) `
-EndDate (Get-Date) `
-ShowDetails |
Export-Csv "mailbox_audit_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
# Review sent items for fraudulent messages sent from the account
# Look for: payment requests, vendor change requests, W-2 requests, wire instructions
- [ ] Review all sent items from the compromise window
- [ ] Identify any fraudulent emails sent to finance, HR, or external parties
- [ ] Identify any emails sent to vendors requesting payment detail changes
- [ ] Check if attacker deleted sent items (check Recoverable Items)
2.2 Hunt for Additional Compromised Accounts¶
# Check for impossible travel / anomalous sign-ins across all accounts
Get-MgAuditLogSignIn -Filter "riskState eq 'atRisk' or riskLevelAggregated eq 'high'" -Top 200 |
Select-Object UserPrincipalName, CreatedDateTime, IpAddress, RiskState, RiskDetail
# Look for inbox rule creation events across the org (last 30 days)
Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-30) -EndDate (Get-Date) `
-Operations "New-InboxRule","Set-InboxRule" -ResultSize 500 |
Select-Object CreatedDate, UserIds, Operations, AuditData |
Export-Csv "inbox_rule_audit.csv" -NoTypeInformation
2.3 Credential Reset¶
- [ ] Reset account password with temporary credential — enforce MFA re-enrollment
- [ ] Reset MFA device registration (attacker may have added their own authenticator)
- [ ] Review and remove any unauthorized MFA methods added
- [ ] Re-issue hardware token or authenticator app enrollment
# Remove all existing MFA methods and force re-registration
$methods = Get-MgUserAuthenticationMethod -UserId "compromised.user@company.com"
foreach ($method in $methods) {
# Do not remove the current admin session method
Write-Host "Review method: $($method.AdditionalProperties['@odata.type'])"
}
# Force MFA re-registration at next login
# Set via Entra ID > Authentication Methods > Require re-register
Financial Recovery Procedures¶
Time-critical: Bank callback window is typically 24–72 hours for wire transfers.
Bank Callback Procedure¶
- [ ] Immediately call the originating bank's fraud/wire transfer department (not the general number)
- [ ] Provide: transaction date, amount, originating account, beneficiary account, SWIFT/routing details
- [ ] Request SWIFT recall message (MT192/MT199) for international wires
- [ ] Request ACH return for domestic ACH transactions (Return Reason Code R07 — Authorization Revoked)
- [ ] Obtain a case/reference number from the bank fraud team
- [ ] Follow up in writing within 1 hour with full transaction details
SWIFT Recall Process¶
1. Contact your bank relationship manager AND fraud hotline simultaneously
2. Provide: UETR (Unique End-to-End Transaction Reference) from wire confirmation
3. Bank initiates MT192 (Request for Cancellation) to correspondent/beneficiary bank
4. Track recall status — escalate if no response within 4 hours
5. Coordinate with FBI if funds have moved internationally
FBI Internet Crime Complaint Center (IC3) Report¶
- [ ] File at ic3.gov within 24 hours of discovery
- [ ] Include: sender/receiver bank details, amount, date, transaction reference numbers
- [ ] Request FBI Financial Fraud Kill Chain (FFKC) activation for large transfers (>$50K)
- [ ] IC3 can coordinate with FinCEN to freeze funds in transit
Prevention Controls¶
MFA Enforcement¶
# Identify accounts without MFA (M365)
Get-MgUser -All -Property UserPrincipalName,DisplayName |
ForEach-Object {
$mfa = Get-MgUserAuthenticationMethod -UserId $_.Id
if ($mfa.Count -le 1) { $_ | Select-Object UserPrincipalName, DisplayName }
}
Mail Flow Rules — Block External Forwarding¶
# Create transport rule to block automatic external forwarding
New-TransportRule -Name "Block External Email Forwarding" `
-FromScope InOrganization `
-SentToScope NotInOrganization `
-MessageTypeMatches AutoForward `
-RejectMessageReasonText "Automatic forwarding to external addresses is not permitted." `
-StopRuleProcessing $true
Conditional Access — Require MFA for All Users¶
- [ ] Enable Conditional Access policy: Require MFA for all users, all apps
- [ ] Enable Conditional Access policy: Block legacy authentication protocols
- [ ] Enable Identity Protection: Auto-remediate high-risk sign-ins (require MFA or block)
- [ ] Configure Named Locations — block sign-in from high-risk countries
Notification Requirements¶
| Stakeholder | Timing | Channel | Content |
|---|---|---|---|
| CFO / Finance | Immediate (T+0) | Phone | Financial exposure amount, actions taken |
| Legal Counsel | T+15 min | Phone | Privilege invoked, regulatory exposure |
| CISO | T+15 min | Phone | Technical brief, containment status |
| HR (if exec involved) | T+30 min | Secure call | Sensitive — need-to-know only |
| Cyber Insurance | T+4h | Phone + email | Claim notice, preserve coverage |
| Affected Vendors | After legal review | Secure email | Warn of fraudulent communications |
| Regulatory (if PII in mailbox) | Per GDPR/HIPAA | Written | Within regulatory deadline |
Recovery Checklist¶
Detection & Triage¶
- [ ] BEC confirmed (not phishing simulation)
- [ ] IR Lead and Finance lead on bridge
- [ ] Compromised account(s) identified
Contain¶
- [ ] Account(s) disabled and sessions revoked
- [ ] Forwarding rules removed
- [ ] OAuth tokens revoked
- [ ] Attacker IP blocked
Financial Recovery¶
- [ ] Bank fraud team contacted (log time and case number)
- [ ] SWIFT/ACH recall initiated (if applicable)
- [ ] FBI IC3 report filed
- [ ] Cyber insurance notified
Eradicate¶
- [ ] Mailbox audit complete — fraudulent emails identified
- [ ] All additional compromised accounts found and contained
- [ ] MFA methods reviewed and attacker-added devices removed
- [ ] Credentials fully reset with MFA re-enrollment
Prevent¶
- [ ] Org-wide forwarding rule audit complete
- [ ] Transport rule blocking external auto-forward in place
- [ ] Conditional access policies reviewed and hardened
- [ ] Awareness communication sent to finance and exec teams
Post-Incident¶
- [ ] Lessons learned documented
- [ ] Tabletop exercise scheduled (finance wire fraud scenario)
- [ ] UEBA tuning — add BEC detection use cases