Detecting Hidden Inbox Rules in Exchange Online

The Problem

Inbox rules in Exchange Online help automate email management – forwarding messages, organizing folders, or flagging items. But there’s a lesser-known risk: some inbox rules are hidden from standard PowerShell queries. These can be used for legitimate purposes – like automatic replies – but can also be abused by threat actors.

🚨 Hidden inbox rules have been used in real-world cyberattacks to forward sensitive emails, maintain persistence, and evade detection – even after a user resets their password or MFA settings.

Hidden Inbox Rules as a Security Risk

As Soteria highlights, attackers with compromised credentials often create inbox rules that:

  • Automatically forward emails to external addresses
  • Delete or move emails to obscure folders
  • Stay hidden from normal administrative reviews

These rules can help attackers exfiltrate sensitive information or maintain access silently.

That’s why proactively discovering hidden rules is not only good hygiene – it’s essential for security.

The Solution

To detect only hidden inbox rules, the following PowerShell script:

  • Scans all user mailboxes
  • Compares visible vs. all rules (-IncludeHidden)
  • Filters out known system rules like:
  • Flags corrupted rules with an HasErrors field
  • Cleans multi-line descriptions for smooth CSV export

Script Breakdown

Filtering Out Known System Rules

$excludedNames = @(
    "Junk E-mail Rule",
    "Microsoft.Exchange.OOF.InternalSenders.Global",
    "Microsoft.Exchange.OOF.KnownExternalSenders.Global",
    "Microsoft.Exchange.OOF.AllExternalSenders.Global"
)
  • $excludedNames: A predefined list of default system rules that are common and not security-relevant.
  • These are excluded from results to reduce noise.

Getting All Mailboxes

$mailboxes = Get-Mailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited
  • Get-Mailbox: Retrieves all user mailboxes in the tenant.
  • UserMailbox: Filters out shared, resource, or system mailboxes.
  • ResultSize Unlimited: Ensures we get the full list, not just the first 1000.

Looping Through Each Mailbox

foreach ($mbx in $mailboxes) {
    $visibleRules = Get-InboxRule -Mailbox $mbx.PrimarySmtpAddress
    $allRules = Get-InboxRule -Mailbox $mbx.PrimarySmtpAddress -IncludeHidden
}
  • foreach: Iterates through every mailbox to check their inbox rules.
  • -IncludeHidden: Ensures even the rules normally not returned by default are captured.

Isolating Hidden Rules Only

$hiddenRules = $allRules | Where-Object {
    $visibleRules.Name -notcontains $_.Name -and
    $excludedNames -notcontains $_.Name
}
  • Where-Object: Filters out visible rules and any system rules from $excludedNames.
  • The result: only hidden, non-standard rules remain.

Detecting Errors in Rules

$hasErrors = $rule.ToString() -like "*contains errors*"
  • ToString(): Captures warning text not exposed as a property.
  • “contains errors”: Checks for broken or malformed rules that may need manual review.

Cleaning Up Descriptions for CSV

$cleanDescription = ($rule.Description -replace '\r?\n', ' ').Trim()
  • Removes line breaks (\r\n) that would break CSV formatting.
  • Ensures the full rule description stays in one line.

Exporting the Results

$results | Export-Csv -Path ".\HiddenInboxRules_Report.csv" -NoTypeInformation -Encoding UTF8
  • Export-Csv: Outputs the results to a file for review or auditing.
  • UTF8 encoding: Ensures compatibility with Excel and international characters.

Sample Output

The final report contains:

  • Mailbox address
  • Rule name
  • Status (Enabled/Disabled)
  • Normalized rule description
  • HasErrors flag for corrupted or unreadable rules

Pro Tip

Consider integrating this script into a regular audit routine or alerting system. If you see forwarding rules to suspicious domains or rules created without proper naming – investigate further.

Summary

Hidden inbox rules may seem like a technical curiosity, but they represent a real threat vector when abused. As an Exchange or M365 admin, having visibility into these rules is a powerful way to spot red flags early.

Better safe than breached.

Script Source

Complete script as always is available for download on azure365addict GitHub. Feel free to customize the script to fit your specific needs and improve your device management processes. If you have any questions or need further assistance, feel free to reach out!

Happy scripting!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top