Detection rules › Splunk

O365 Email Transport Rule Changed

Status
production
Severity
low
Group by
Operation, group.id, signature, user
Author
Steven Dick
Source
github.com/splunk/security_content

The following analytic identifies when a user with sufficient access to Exchange Online alters the mail flow/transport rule configuration of the organization. Transport rules are a set of rules that can be used by attackers to modify or delete emails based on specific conditions, this activity could indicate an attacker hiding or exfiltrated data.

Known false positives

  • Legitimate administrative changes for business needs.

MITRE ATT&CK coverage

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule body

name: O365 Email Transport Rule Changed
id: 11ebb7c2-46bd-41c9-81e1-d0b4b34583a2
version: 7
creation_date: '2025-01-15'
modification_date: '2026-05-13'
author: Steven Dick
status: production
type: Anomaly
description: The following analytic identifies when a user with sufficient access to Exchange Online alters the mail flow/transport rule configuration of the organization. Transport rules are a set of rules that can be used by attackers to modify or delete emails based on specific conditions, this activity could indicate an attacker hiding or exfiltrated data.
data_source:
    - Office 365 Universal Audit Log
search: |-
    `o365_management_activity` Workload=Exchange AND Operation IN ("Set-*","Disable-*","New-*","Remove-*") AND Operation="*TransportRule"
    | eval object_name = case('Parameters{}.Name'=="Name",mvindex('Parameters{}.Value',mvfind('Parameters{}.Name',"^Name$")),true(),ObjectId), object_id = case('Parameters{}.Name'=="Identity",mvindex('Parameters{}.Value',mvfind('Parameters{}.Name',"^Identity$")),true(),Id)
    | stats values(object_name) as object_name, min(_time) as firstTime, max(_time) as lastTime, count by object_id, UserId, Operation, signature
    | rename UserId as user
    | `security_content_ctime(firstTime)`
    | `security_content_ctime(lastTime)`
    | `o365_email_transport_rule_changed_filter`
how_to_implement: You must install the Splunk Microsoft Office 365 Add-on and ingest Office 365 management activity events.
known_false_positives: Legitimate administrative changes for business needs.
references:
    - https://attack.mitre.org/techniques/T1114/003/
    - https://cardinalops.com/blog/cardinalops-contributes-new-mitre-attck-techniques-related-to-abuse-of-mail-transport-rules/
    - https://www.microsoft.com/en-us/security/blog/2022/09/22/malicious-OAuth-applications-used-to-compromise-email-servers-and-spread-spam/
intermediate_findings:
    entities:
        - field: user
          type: user
          score: 20
          message: The user [$user$] altered the exchange transport rule id [$object_name$]
threat_objects:
    - field: object_id
      type: signature
    - field: object_name
      type: signature
analytic_story:
    - Data Exfiltration
    - Office 365 Account Takeover
asset_type: O365 Tenant
mitre_attack_id:
    - T1114.003
    - T1564.008
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: cloud
security_domain: threat

Stages and Predicates

Stage 1: search

`o365_management_activity` Workload=Exchange AND Operation IN ("Set-*","Disable-*","New-*","Remove-*") AND Operation="*TransportRule"

Stage 2: eval

| eval object_name = case('Parameters{}.Name'=="Name",mvindex('Parameters{}.Value',mvfind('Parameters{}.Name',"^Name$")),true(),ObjectId), object_id = case('Parameters{}.Name'=="Identity",mvindex('Parameters{}.Value',mvfind('Parameters{}.Name',"^Identity$")),true(),Id)
object_id =
ifParameters{}.Name="Identity"mvindex('Parameters{}.Value', <FUNCTION:mvfind>)
elseId
object_name =
ifParameters{}.Name="Name"mvindex('Parameters{}.Value', <FUNCTION:mvfind>)
elseObjectId

Stage 3: stats

| stats values(object_name) as object_name, min(_time) as firstTime, max(_time) as lastTime, count by object_id, UserId, Operation, signature

Stage 4: rename

| rename UserId as user

Stage 5: search

| `security_content_ctime(firstTime)`

Stage 6: search

| `security_content_ctime(lastTime)`

Stage 7: search

| `o365_email_transport_rule_changed_filter`

Indicators

These rows show field, operator, and value matches.