Tools / Guides / Malicious inbox rules

BEC: find malicious inbox rules and forwarding in Microsoft 365

How attackers use inbox rules and mail forwarding after a Microsoft 365 account takeover, the PowerShell and audit log searches that find them, which rules are normal, and how to clean up.

Updated 2026-11-05 · 8 min read

After an attacker takes over a Microsoft 365 mailbox, one of the first things they usually do is create an inbox rule. It doesn't need admin rights, it survives a password reset, and it keeps the real user from seeing replies to the fake invoices the attacker is about to send. Forwarding is the other half: a quiet copy of everything that arrives, sent to an outside address.

So whenever you handle a suspicious sign-in, a phishing click or a reported payment-change email, check the mailbox for malicious inbox rules and forwarding before you close the ticket. Resetting the password without doing this is the most common way business email compromise (BEC) cleanups fail.

What does a malicious inbox rule look like?

Attacker rules are built to hide things from the user. The patterns repeat across almost every BEC case:

A rule that forwards or redirects to an outside address is just as serious, even with a normal-looking name.

Where can mail forwarding be set?

There are three places, and you need to check all of them:

WhereHow it shows up
Mailbox forwarding (Outlook settings or admin)ForwardingSmtpAddress or ForwardingAddress on the mailbox
Inbox ruleForwardTo, ForwardAsAttachmentTo or RedirectTo on a rule
Transport rule (admin only)A mail flow rule that adds a recipient or redirects. Rare in BEC, because it needs an Exchange admin account

Outbound forwarding may already be blocked. The default outbound spam policy blocks automatic forwarding to external addresses. So a forwarding rule can exist and do nothing, or be quietly allowed by a custom policy someone created years ago. Check the policy before you tell anyone whether mail actually left.

How do I find inbox rules with PowerShell?

Connect with Connect-ExchangeOnline (read-only roles are enough), then for one mailbox:

Get-InboxRule -Mailbox user@contoso.com -IncludeHidden |
  Select-Object Name, Enabled, From, SubjectOrBodyContainsWords, MoveToFolder,
    DeleteMessage, MarkAsRead, ForwardTo, ForwardAsAttachmentTo, RedirectTo |
  Format-List

-IncludeHidden matters. Rules created through some APIs don't appear in Outlook's rule list, and without the switch they can be missing from PowerShell output too.

For the whole tenant, look for the patterns above:

Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox,SharedMailbox | ForEach-Object {
  Get-InboxRule -Mailbox $_.UserPrincipalName -IncludeHidden -ErrorAction SilentlyContinue |
    Where-Object { $_.ForwardTo -or $_.ForwardAsAttachmentTo -or $_.RedirectTo -or $_.DeleteMessage -or
                   $_.MoveToFolder -match 'RSS|Archive|Conversation History|Deleted' -or $_.Name.Trim().Length -le 2 } |
    Select-Object MailboxOwnerId, Name, Enabled, MoveToFolder, DeleteMessage, ForwardTo, RedirectTo
} | Format-Table -AutoSize

And mailbox-level forwarding:

Get-Mailbox -ResultSize Unlimited | Where-Object { $_.ForwardingSmtpAddress -or $_.ForwardingAddress } |
  Select-Object UserPrincipalName, ForwardingSmtpAddress, ForwardingAddress, DeliverToMailboxAndForward

On a large tenant the rule loop takes a while. Run it once for the incident, then use the audit log for anything ongoing.

How do I find when a rule was created, and by whom?

The unified audit log records rule changes under three operation names. UpdateInboxRules is the one people miss: it's what Outlook desktop and some APIs write, while New-InboxRule and Set-InboxRule come from Outlook on the web and PowerShell.

Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-30) -EndDate (Get-Date) `
  -Operations New-InboxRule,Set-InboxRule,UpdateInboxRules,Set-Mailbox -ResultSize 5000 |
  Select-Object CreationDate, UserIds, Operations, AuditData

The AuditData JSON holds the client IP and the rule's parameters. Compare that IP with the user's normal sign-ins. A rule created from a hosting provider or a country the user has never signed in from is the strongest evidence you will get. In Microsoft Sentinel the same events are in OfficeActivity:

OfficeActivity
| where TimeGenerated > ago(30d)
| where Operation in ("New-InboxRule", "Set-InboxRule", "UpdateInboxRules", "Set-Mailbox")
| project TimeGenerated, UserId, Operation, ClientIP, Parameters
| order by TimeGenerated desc

Which inbox rules are usually normal?

The quickest test is still the audit log: if the rule was created from the same IP and device the user always uses, ask the user. If it came from an IP they have never used, treat the account as compromised regardless of what the rule does.

What to do when you find one

  1. Export the rule first (the PowerShell output above) for the incident record, then disable or remove it, and clear mailbox forwarding with Set-Mailbox -ForwardingSmtpAddress $null -ForwardingAddress $null.
  2. Reset the password and revoke sessions. A reset alone does not end tokens already issued. Use Revoke sessions on the user in Entra, or Revoke-MgUserSignInSession.
  3. Check the MFA methods. Attackers often register their own phone or authenticator app. Look for "User registered security info" in the Entra audit log.
  4. Check app consents for the user: an OAuth app with mail access keeps working after a password reset.
  5. Read the Sent Items and the hidden folders the rule pointed at. That tells you which suppliers or customers were targeted, and who needs a call before they pay a changed bank account.

The impossible travel guide covers the sign-in side of the same investigation, and the phishing triage checklist covers the email that usually started it.

FAQ

Does a password reset remove inbox rules?

No. Rules and forwarding are mailbox settings and stay until someone removes them. That's exactly why attackers create them.

Can a normal user create a forwarding rule to an external address?

They can create it. Whether mail actually leaves depends on the outbound spam filter policy, which blocks external automatic forwarding by default. Check Get-HostedOutboundSpamFilterPolicy | Select Name, AutoForwardingMode.

Why can't I see the rule in Outlook?

Some rules are created through APIs that leave them out of the Outlook rule list. Use Get-InboxRule -IncludeHidden in Exchange Online PowerShell instead of checking in Outlook.

How far back can I search the audit log?

180 days by default for audit (Standard), longer with audit (Premium) licensing. Run the search as soon as you suspect a compromise; it's the only record of where the rule came from.