EXT-07: Detecting and Blocking Mail Forwarding

Overview

Automatic email forwarding to external addresses is a common data exfiltration technique. Attackers who compromise an account often set up forwarding rules to silently copy sensitive communications. This guide helps you detect existing forwarding rules, block unauthorized forwarding, and implement ongoing monitoring.

Prerequisites

Required Roles

  • Global Administrator - Full access to all settings
  • Exchange Administrator - Can manage Exchange Online settings
  • Security Administrator - Can view security configurations
  • Compliance Administrator - Access to audit logs and DLP

Required Licenses

  • Microsoft 365 E3/E5 or Business Premium
  • Exchange Online (included in above)

Time Estimate

  • Audit Existing Rules: 30-45 minutes
  • Policy Configuration: 20-30 minutes
  • Monitoring Setup: 15-20 minutes

Step-by-Step Instructions

Step 1: Audit Existing Forwarding Rules

Types of Email Forwarding

TypeDescriptionRisk Level
Inbox RulesUser-created rules in OutlookHigh - often used in attacks
Transport RulesAdmin-created org-wide rulesMedium - should be documented
SMTP ForwardingMailbox property forwardingHigh - server-side forwarding
Delegate ForwardingSend-on-behalf permissionsMedium - requires additional access

Step 2: Find SMTP Forwarding

SMTP forwarding is configured at the mailbox level:

Via Exchange Admin Center

  1. Navigate to Exchange admin center (https://admin.exchange.microsoft.com)
  2. Go to RecipientsMailboxes
  3. For each mailbox, click to view properties
  4. Check Mail flow settingsEmail forwarding

Via PowerShell (Recommended for Bulk)

# Connect to Exchange Online
Connect-ExchangeOnline

# Find all mailboxes with external forwarding
$mailboxes = Get-Mailbox -ResultSize Unlimited

$forwardingReport = @()

foreach ($mbx in $mailboxes) {
    if ($mbx.ForwardingSmtpAddress -or $mbx.ForwardingAddress) {
        $forwardingReport += [PSCustomObject]@{
            DisplayName = $mbx.DisplayName
            UserPrincipalName = $mbx.UserPrincipalName
            ForwardingSmtpAddress = $mbx.ForwardingSmtpAddress
            ForwardingAddress = $mbx.ForwardingAddress
            DeliverToMailboxAndForward = $mbx.DeliverToMailboxAndForward
            ForwardingType = "SMTP Forwarding"
        }
    }
}

Write-Host "Found $($forwardingReport.Count) mailboxes with SMTP forwarding"
$forwardingReport | Format-Table -AutoSize
$forwardingReport | Export-Csv -Path "SMTPForwarding.csv" -NoTypeInformation

Step 3: Find Inbox Rules with External Forwarding

Users can create inbox rules that forward or redirect email:

Connect-ExchangeOnline

# Get all mailboxes
$mailboxes = Get-Mailbox -ResultSize Unlimited

$inboxRulesReport = @()

foreach ($mbx in $mailboxes) {
    $rules = Get-InboxRule -Mailbox $mbx.UserPrincipalName -ErrorAction SilentlyContinue

    foreach ($rule in $rules) {
        # Check for forwarding actions
        if ($rule.ForwardTo -or $rule.ForwardAsAttachmentTo -or $rule.RedirectTo) {
            # Check if forwarding to external
            $targets = @()
            $targets += $rule.ForwardTo
            $targets += $rule.ForwardAsAttachmentTo
            $targets += $rule.RedirectTo

            foreach ($target in $targets) {
                if ($target -and $target -notlike "*@$(($mbx.PrimarySmtpAddress -split '@')[1])") {
                    $inboxRulesReport += [PSCustomObject]@{
                        Mailbox = $mbx.UserPrincipalName
                        RuleName = $rule.Name
                        RuleEnabled = $rule.Enabled
                        ForwardTo = $rule.ForwardTo -join "; "
                        ForwardAsAttachment = $rule.ForwardAsAttachmentTo -join "; "
                        RedirectTo = $rule.RedirectTo -join "; "
                        RuleIdentity = $rule.Identity
                    }
                }
            }
        }
    }
}

Write-Host "Found $($inboxRulesReport.Count) inbox rules forwarding externally"
$inboxRulesReport | Format-Table Mailbox, RuleName, ForwardTo, RedirectTo -AutoSize
$inboxRulesReport | Export-Csv -Path "InboxRulesForwarding.csv" -NoTypeInformation

Step 4: Find Transport Rules with External Forwarding

Check admin-configured transport rules:

Connect-ExchangeOnline

# Get all transport rules
$transportRules = Get-TransportRule

$externalForwardingRules = $transportRules | Where-Object {
    $_.BlindCopyTo -or $_.CopyTo -or $_.RedirectMessageTo
} | Select-Object Name, State, Priority, BlindCopyTo, CopyTo, RedirectMessageTo

$externalForwardingRules | Format-Table -AutoSize

if ($externalForwardingRules.Count -gt 0) {
    Write-Host "Review these transport rules for external forwarding" -ForegroundColor Yellow
}

Step 5: Block External Forwarding

Option A: Block at Organization Level (Recommended)

  1. Navigate to Exchange admin center
  2. Go to Mail flowRemote domains
  3. Click on Default (or create a new policy for specific domains)
  4. Under Reply types allowed, disable:
    • Automatic replies
    • Automatic forwarding
  5. Click Save

Via PowerShell

Connect-ExchangeOnline

# Block auto-forwarding for the default remote domain (affects all external domains)
Set-RemoteDomain -Identity Default -AutoForwardEnabled $false

# Verify the change
Get-RemoteDomain -Identity Default | Select-Object Name, AutoForwardEnabled

Option B: Create Transport Rule to Block Forwarding

For more granular control:

Connect-ExchangeOnline

# Create transport rule to block external forwarding
New-TransportRule -Name "Block External Auto-Forwarding" `
    -MessageTypeMatches "AutoForward" `
    -SentToScope "NotInOrganization" `
    -RejectMessageReasonText "External email forwarding is not permitted. Contact IT for exceptions." `
    -ExceptIfSentTo "approved-external@partner.com" `
    -ExceptIfFrom "exception-user@company.com" `
    -Priority 0 `
    -Mode Enforce

Write-Host "Transport rule created to block external forwarding"

Option C: Block via Outbound Spam Policy (Microsoft 365)

  1. Navigate to Microsoft Defender portal (https://security.microsoft.com)
  2. Go to Policies & rulesThreat policiesAnti-spam
  3. Click Anti-spam outbound policy (Default)
  4. Under Forwarding rules, set:
    • Automatic forwarding rules: Off - Forwarding is disabled
  5. Click Save

Step 6: Remove Unauthorized Forwarding

Remove SMTP Forwarding

Connect-ExchangeOnline

# Remove forwarding from a specific mailbox
$mailbox = "user@company.com"
Set-Mailbox -Identity $mailbox -ForwardingSmtpAddress $null -ForwardingAddress $null

Write-Host "Forwarding removed from $mailbox"

Remove Inbox Rules

Connect-ExchangeOnline

# Remove specific inbox rule
$mailbox = "user@company.com"
$ruleName = "Forward to personal"

Remove-InboxRule -Mailbox $mailbox -Identity $ruleName -Confirm:$false

Write-Host "Inbox rule removed"

Bulk Remove All External Forwarding Rules

Connect-ExchangeOnline

# Remove all inbox rules that forward externally
$mailboxes = Get-Mailbox -ResultSize Unlimited

foreach ($mbx in $mailboxes) {
    $rules = Get-InboxRule -Mailbox $mbx.UserPrincipalName -ErrorAction SilentlyContinue

    foreach ($rule in $rules) {
        if ($rule.ForwardTo -or $rule.ForwardAsAttachmentTo -or $rule.RedirectTo) {
            Remove-InboxRule -Mailbox $mbx.UserPrincipalName -Identity $rule.Name -Confirm:$false
            Write-Host "Removed rule '$($rule.Name)' from $($mbx.UserPrincipalName)"
        }
    }

    # Also remove SMTP forwarding
    if ($mbx.ForwardingSmtpAddress -or $mbx.ForwardingAddress) {
        Set-Mailbox -Identity $mbx.UserPrincipalName -ForwardingSmtpAddress $null -ForwardingAddress $null
        Write-Host "Removed SMTP forwarding from $($mbx.UserPrincipalName)"
    }
}

Step 7: Configure Exceptions for Legitimate Use

Some forwarding may be legitimate (e.g., shared mailboxes, integrations):

Allow Specific Users to Forward

# Create transport rule with exceptions
Set-TransportRule -Identity "Block External Auto-Forwarding" `
    -ExceptIfFrom "legitimate-forwarder@company.com", "integration-mailbox@company.com"

Create Exception Group

# Create distribution group for forwarding exceptions
New-DistributionGroup -Name "Mail Forwarding Exceptions" -Type Security

# Add legitimate users
Add-DistributionGroupMember -Identity "Mail Forwarding Exceptions" -Member "user@company.com"

# Update transport rule to except this group
Set-TransportRule -Identity "Block External Auto-Forwarding" `
    -ExceptIfFromMemberOf "Mail Forwarding Exceptions"

Step 8: Set Up Monitoring and Alerts

Alert on New Forwarding Rules

  1. Navigate to Microsoft Defender portalPolicies & rules
  2. Go to Alert policies
  3. Create new alert:
    • Name: "Inbox Rule Created with External Forwarding"
    • Category: Threat management
    • Activity: New-InboxRule with forwarding action
    • Severity: High
    • Recipients: Security team

Use Audit Log for Detection

Connect-ExchangeOnline

# Search for recent forwarding rule creations
$startDate = (Get-Date).AddDays(-7)
$endDate = Get-Date

$auditLogs = Search-UnifiedAuditLog -StartDate $startDate -EndDate $endDate `
    -Operations "New-InboxRule", "Set-InboxRule", "Set-Mailbox" `
    -ResultSize 1000

$forwardingChanges = $auditLogs | ForEach-Object {
    $auditData = $_.AuditData | ConvertFrom-Json

    # Check if forwarding-related
    if ($auditData.Parameters.Name -match "ForwardTo|ForwardAsAttachment|RedirectTo|ForwardingSmtpAddress") {
        [PSCustomObject]@{
            Date = $_.CreationDate
            User = $_.UserIds
            Operation = $_.Operations
            Details = $auditData.Parameters | ConvertTo-Json -Compress
        }
    }
}

$forwardingChanges | Format-Table -AutoSize

Step 9: Implement Proactive Detection

Daily Forwarding Check Script

# Schedule via Azure Automation or Task Scheduler

Connect-ExchangeOnline

$previousReport = Import-Csv -Path "LastForwardingSnapshot.csv" -ErrorAction SilentlyContinue
$currentForwarding = @()

$mailboxes = Get-Mailbox -ResultSize Unlimited

foreach ($mbx in $mailboxes) {
    if ($mbx.ForwardingSmtpAddress) {
        $currentForwarding += [PSCustomObject]@{
            Mailbox = $mbx.UserPrincipalName
            ForwardTo = $mbx.ForwardingSmtpAddress.ToString()
            Type = "SMTP"
        }
    }

    $rules = Get-InboxRule -Mailbox $mbx.UserPrincipalName -ErrorAction SilentlyContinue
    foreach ($rule in $rules) {
        if ($rule.ForwardTo -or $rule.RedirectTo) {
            $currentForwarding += [PSCustomObject]@{
                Mailbox = $mbx.UserPrincipalName
                ForwardTo = ($rule.ForwardTo + $rule.RedirectTo) -join "; "
                Type = "InboxRule"
            }
        }
    }
}

# Compare with previous
$newForwarding = $currentForwarding | Where-Object {
    $current = $_
    -not ($previousReport | Where-Object { $_.Mailbox -eq $current.Mailbox -and $_.ForwardTo -eq $current.ForwardTo })
}

if ($newForwarding.Count -gt 0) {
    Write-Host "NEW FORWARDING DETECTED!" -ForegroundColor Red
    $newForwarding | Format-Table

    # Send alert
    $body = $newForwarding | ConvertTo-Html -Fragment
    Send-MailMessage -To "security@company.com" -Subject "Alert: New Email Forwarding Detected" -Body $body -BodyAsHtml
}

# Save current snapshot
$currentForwarding | Export-Csv -Path "LastForwardingSnapshot.csv" -NoTypeInformation

Step 10: Implement Defender for Cloud Apps Detection

Use MCAS/Defender for Cloud Apps for advanced detection:

  1. Navigate to Microsoft Defender portalCloud appsPolicies
  2. Create new policy:
    • Policy type: Activity policy
    • Activities matching all of the following:
      • Activity type = New-InboxRule
      • Activity parameter contains "ForwardTo" or "RedirectTo"
    • Alerts: Create alert, send to security team
    • Governance actions: Suspend user (optional, for high confidence)

Verification Checklist

After implementing mail forwarding controls:

  • Initial audit completed for SMTP forwarding
  • Initial audit completed for inbox rules
  • Transport rules reviewed for forwarding
  • External auto-forwarding blocked at remote domain level
  • Transport rule or outbound spam policy blocking forwarding
  • Unauthorized forwarding removed
  • Exception process documented and implemented
  • Alert policies configured for new forwarding rules
  • Proactive detection script scheduled
  • Defender for Cloud Apps policy created
  • Security team notified of baseline findings

Troubleshooting

Issue: Legitimate forwarding stopped working

Cause: Blocking policies may be too broad.

Solution:

  1. Identify the specific forwarding requirement
  2. Add user to exception group
  3. Or add specific exception to transport rule
  4. Document the business justification

Issue: Cannot find forwarding rules in audit log

Cause: Audit log search may have wrong date range or filters.

Solution:

  1. Expand date range
  2. Search for "New-InboxRule" and "Set-Mailbox" operations
  3. Verify audit logging is enabled
  4. Check retention period hasn't expired

Issue: Forwarding rule is hidden from user

Cause: Attackers often create hidden rules.

Solution:

# Show all inbox rules including hidden ones
Get-InboxRule -Mailbox "user@company.com" -IncludeHidden

# Remove hidden rule by identity
Remove-InboxRule -Mailbox "user@company.com" -Identity "RuleGUID" -Confirm:$false

Issue: External forwarding still works after blocking

Cause: Multiple forwarding mechanisms exist.

Solution:

  1. Verify all three blocking methods:
    • Remote domain auto-forward disabled
    • Transport rule blocking auto-forward
    • Outbound spam policy set to "Off"
  2. Check for transport rule exceptions
  3. Verify rules are processed in correct priority

Issue: Client-side rules bypass server policies

Cause: Outlook client rules may run locally.

Solution:

  1. Server-side rules (created via OWA or PowerShell) are always enforced
  2. For client rules, they execute before server policies
  3. Block at network/firewall level for complete protection
  4. Use DLP policies as additional layer

Issue: Forwarding works for some users but not others

Cause: Mailbox-level or user-level exceptions may exist.

Solution:

  1. Check if user is in exception group
  2. Review user's specific mailbox settings
  3. Check for user-specific transport rule exceptions
  4. Verify user license includes Exchange Online

Related Resources


Last updated: January 2025