Threat Essentials - Mail redirect via ExO transport rule
Id | d7c575b2-84f5-48cb-92c5-70d7e8246284 |
Rulename | Threat Essentials - Mail redirect via ExO transport rule |
Description | Identifies when Exchange Online transport rule configured to forward emails. This could be an adversary mailbox configured to collect mail from multiple user accounts. |
Severity | Medium |
Tactics | Collection Exfiltration |
Techniques | T1114 T1020 |
Required data connectors | Office365 |
Kind | Scheduled |
Query frequency | 1d |
Query period | 1d |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SecurityThreatEssentialSolution/Analytic Rules/Threat_Essentials_Mail_redirect_via_ExO_transport_rule.yaml |
Version | 1.0.2 |
Arm template | d7c575b2-84f5-48cb-92c5-70d7e8246284.json |
OfficeActivity
| where OfficeWorkload == "Exchange"
| where Operation in~ ("New-TransportRule", "Set-TransportRule")
| extend p = parse_json(Parameters)
| extend RuleName = case(
Operation =~ "Set-TransportRule", tostring(OfficeObjectId),
Operation =~ "New-TransportRule", tostring(p[1].Value),
"Unknown"
)
| mvexpand p
| where (p.Name =~ "BlindCopyTo" or p.Name =~ "RedirectMessageTo") and isnotempty(p.Value)
| extend RedirectTo = p.Value
| extend ClientIPOnly = case(
ClientIP has "." and ClientIP has ":", tostring(split(ClientIP,":")[0]),
ClientIP has "." and ClientIP has "-", tostring(split(ClientIP,"-")[0]),
ClientIP has "[", tostring(trim_start(@'[[]',tostring(split(ClientIP,"]")[0]))),
ClientIP
)
| extend Port = case(
ClientIP has "." and ClientIP has ":", (split(ClientIP,":")[1]),
ClientIP has "." and ClientIP has "-", (split(ClientIP,"-")[1]),
ClientIP has "[" and ClientIP has ":", tostring(split(ClientIP,"]:")[1]),
ClientIP has "[" and ClientIP has "-", tostring(split(ClientIP,"]-")[1]),
ClientIP
)
| extend ClientIP = ClientIPOnly
| project TimeGenerated, RedirectTo, ClientIP, Port, UserId, Operation, RuleName
| extend Name=split(UserId, "@")[0], UPNSuffix=split(UserId, "@")[1]
relevantTechniques:
- T1114
- T1020
name: Threat Essentials - Mail redirect via ExO transport rule
requiredDataConnectors:
- dataTypes:
- OfficeActivity
connectorId: Office365
entityMappings:
- fieldMappings:
- identifier: Name
columnName: Name
- identifier: UPNSuffix
columnName: UPNSuffix
entityType: Account
- fieldMappings:
- identifier: Address
columnName: ClientIP
entityType: IP
triggerThreshold: 0
id: d7c575b2-84f5-48cb-92c5-70d7e8246284
tactics:
- Collection
- Exfiltration
version: 1.0.2
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SecurityThreatEssentialSolution/Analytic Rules/Threat_Essentials_Mail_redirect_via_ExO_transport_rule.yaml
queryPeriod: 1d
kind: Scheduled
queryFrequency: 1d
severity: Medium
status: Available
description: |
'Identifies when Exchange Online transport rule configured to forward emails.
This could be an adversary mailbox configured to collect mail from multiple user accounts.'
query: |
OfficeActivity
| where OfficeWorkload == "Exchange"
| where Operation in~ ("New-TransportRule", "Set-TransportRule")
| extend p = parse_json(Parameters)
| extend RuleName = case(
Operation =~ "Set-TransportRule", tostring(OfficeObjectId),
Operation =~ "New-TransportRule", tostring(p[1].Value),
"Unknown"
)
| mvexpand p
| where (p.Name =~ "BlindCopyTo" or p.Name =~ "RedirectMessageTo") and isnotempty(p.Value)
| extend RedirectTo = p.Value
| extend ClientIPOnly = case(
ClientIP has "." and ClientIP has ":", tostring(split(ClientIP,":")[0]),
ClientIP has "." and ClientIP has "-", tostring(split(ClientIP,"-")[0]),
ClientIP has "[", tostring(trim_start(@'[[]',tostring(split(ClientIP,"]")[0]))),
ClientIP
)
| extend Port = case(
ClientIP has "." and ClientIP has ":", (split(ClientIP,":")[1]),
ClientIP has "." and ClientIP has "-", (split(ClientIP,"-")[1]),
ClientIP has "[" and ClientIP has ":", tostring(split(ClientIP,"]:")[1]),
ClientIP has "[" and ClientIP has "-", tostring(split(ClientIP,"]-")[1]),
ClientIP
)
| extend ClientIP = ClientIPOnly
| project TimeGenerated, RedirectTo, ClientIP, Port, UserId, Operation, RuleName
| extend Name=split(UserId, "@")[0], UPNSuffix=split(UserId, "@")[1]
triggerOperator: gt
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/d7c575b2-84f5-48cb-92c5-70d7e8246284')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/d7c575b2-84f5-48cb-92c5-70d7e8246284')]",
"properties": {
"alertRuleTemplateName": "d7c575b2-84f5-48cb-92c5-70d7e8246284",
"customDetails": null,
"description": "'Identifies when Exchange Online transport rule configured to forward emails.\nThis could be an adversary mailbox configured to collect mail from multiple user accounts.'\n",
"displayName": "Threat Essentials - Mail redirect via ExO transport rule",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "Name",
"identifier": "Name"
},
{
"columnName": "UPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "ClientIP",
"identifier": "Address"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SecurityThreatEssentialSolution/Analytic Rules/Threat_Essentials_Mail_redirect_via_ExO_transport_rule.yaml",
"query": "OfficeActivity\n| where OfficeWorkload == \"Exchange\"\n| where Operation in~ (\"New-TransportRule\", \"Set-TransportRule\")\n| extend p = parse_json(Parameters)\n| extend RuleName = case(\n Operation =~ \"Set-TransportRule\", tostring(OfficeObjectId),\n Operation =~ \"New-TransportRule\", tostring(p[1].Value),\n \"Unknown\"\n )\n| mvexpand p\n| where (p.Name =~ \"BlindCopyTo\" or p.Name =~ \"RedirectMessageTo\") and isnotempty(p.Value)\n| extend RedirectTo = p.Value\n| extend ClientIPOnly = case(\n ClientIP has \".\" and ClientIP has \":\", tostring(split(ClientIP,\":\")[0]),\n ClientIP has \".\" and ClientIP has \"-\", tostring(split(ClientIP,\"-\")[0]),\n ClientIP has \"[\", tostring(trim_start(@'[[]',tostring(split(ClientIP,\"]\")[0]))),\n ClientIP\n )\n| extend Port = case(\n ClientIP has \".\" and ClientIP has \":\", (split(ClientIP,\":\")[1]),\n ClientIP has \".\" and ClientIP has \"-\", (split(ClientIP,\"-\")[1]),\n ClientIP has \"[\" and ClientIP has \":\", tostring(split(ClientIP,\"]:\")[1]),\n ClientIP has \"[\" and ClientIP has \"-\", tostring(split(ClientIP,\"]-\")[1]),\n ClientIP\n )\n| extend ClientIP = ClientIPOnly\n| project TimeGenerated, RedirectTo, ClientIP, Port, UserId, Operation, RuleName\n| extend Name=split(UserId, \"@\")[0], UPNSuffix=split(UserId, \"@\")[1]\n",
"queryFrequency": "P1D",
"queryPeriod": "P1D",
"severity": "Medium",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"Collection",
"Exfiltration"
],
"techniques": [
"T1020",
"T1114"
],
"templateVersion": "1.0.2",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}