Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Office 365 - Multiple Users Email Forwarded to Same Destination

Back
Idd75e8289-d1cb-44d4-bd59-2f44a9172478
RulenameOffice 365 - Multiple Users Email Forwarded to Same Destination
DescriptionIdentifies when multiple (more than one) users’ mailboxes are configured to forward to the same destination.

This could be an attacker-controlled destination mailbox configured to collect mail from multiple compromised user accounts.
SeverityMedium
TacticsCollection
Exfiltration
TechniquesT1114
T1020
Required data connectorsAzureActiveDirectory
KindScheduled
Query frequency1d
Query period7d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - Office_MailForwarding.yaml
Version2.0.4
Arm templated75e8289-d1cb-44d4-bd59-2f44a9172478.json
Deploy To Azure
let queryfrequency = 1d;
  let queryperiod = 7d;
  EnrichedMicrosoft365AuditLogs
  | where TimeGenerated > ago(queryperiod)
  | where Workload =~ "Exchange"
  //| where Operation in ("Set-Mailbox", "New-InboxRule", "Set-InboxRule")  // Uncomment or adjust based on actual field usage
  | where tostring(AdditionalProperties.Parameters) has_any ("ForwardTo", "RedirectTo", "ForwardingSmtpAddress")
  | mv-apply DynamicParameters = todynamic(tostring(AdditionalProperties.Parameters)) on (
      summarize ParsedParameters = make_bag(bag_pack(tostring(DynamicParameters.Name), DynamicParameters.Value))
    )
  | evaluate bag_unpack(ParsedParameters, columnsConflict='replace_source')
  | extend DestinationMailAddress = tolower(case(
      isnotempty(column_ifexists("ForwardTo", "")), column_ifexists("ForwardTo", ""),
      isnotempty(column_ifexists("RedirectTo", "")), column_ifexists("RedirectTo", ""),
      isnotempty(column_ifexists("ForwardingSmtpAddress", "")), trim_start(@"smtp:", column_ifexists("ForwardingSmtpAddress", "")),
      ""))
  | where isnotempty(DestinationMailAddress)
  | mv-expand split(DestinationMailAddress, ";")
  | extend ClientIPValues = extract_all(@'\[?(::ffff:)?(?P<IPAddress>(\d+\.\d+\.\d+\.\d+)|[^\]]+)\]?([-:](?P<Port>\d+))?', dynamic(["IPAddress", "Port"]), ClientIp)[0]
  | extend ClientIP = tostring(ClientIPValues[0]), Port = tostring(ClientIPValues[1])
  | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), DistinctUserCount = dcount(UserId), UserId = make_set(UserId, 250), Ports = make_set(Port, 250), EventCount = count() by tostring(DestinationMailAddress), ClientIP
  | where DistinctUserCount > 1 and EndTime > ago(queryfrequency)
  | mv-expand UserId to typeof(string)
  | extend AccountName = tostring(split(UserId, "@")[0]), AccountUPNSuffix = tostring(split(UserId, "@")[1])
queryPeriod: 7d
version: 2.0.4
tactics:
- Collection
- Exfiltration
queryFrequency: 1d
id: d75e8289-d1cb-44d4-bd59-2f44a9172478
triggerOperator: gt
requiredDataConnectors:
- dataTypes:
  - EnrichedMicrosoft365AuditLogs
  connectorId: AzureActiveDirectory
severity: Medium
entityMappings:
- entityType: Account
  fieldMappings:
  - columnName: UserId
    identifier: FullName
  - columnName: AccountName
    identifier: Name
  - columnName: AccountUPNSuffix
    identifier: UPNSuffix
- entityType: IP
  fieldMappings:
  - columnName: ClientIP
    identifier: Address
triggerThreshold: 0
relevantTechniques:
- T1114
- T1020
query: |
  let queryfrequency = 1d;
    let queryperiod = 7d;
    EnrichedMicrosoft365AuditLogs
    | where TimeGenerated > ago(queryperiod)
    | where Workload =~ "Exchange"
    //| where Operation in ("Set-Mailbox", "New-InboxRule", "Set-InboxRule")  // Uncomment or adjust based on actual field usage
    | where tostring(AdditionalProperties.Parameters) has_any ("ForwardTo", "RedirectTo", "ForwardingSmtpAddress")
    | mv-apply DynamicParameters = todynamic(tostring(AdditionalProperties.Parameters)) on (
        summarize ParsedParameters = make_bag(bag_pack(tostring(DynamicParameters.Name), DynamicParameters.Value))
      )
    | evaluate bag_unpack(ParsedParameters, columnsConflict='replace_source')
    | extend DestinationMailAddress = tolower(case(
        isnotempty(column_ifexists("ForwardTo", "")), column_ifexists("ForwardTo", ""),
        isnotempty(column_ifexists("RedirectTo", "")), column_ifexists("RedirectTo", ""),
        isnotempty(column_ifexists("ForwardingSmtpAddress", "")), trim_start(@"smtp:", column_ifexists("ForwardingSmtpAddress", "")),
        ""))
    | where isnotempty(DestinationMailAddress)
    | mv-expand split(DestinationMailAddress, ";")
    | extend ClientIPValues = extract_all(@'\[?(::ffff:)?(?P<IPAddress>(\d+\.\d+\.\d+\.\d+)|[^\]]+)\]?([-:](?P<Port>\d+))?', dynamic(["IPAddress", "Port"]), ClientIp)[0]
    | extend ClientIP = tostring(ClientIPValues[0]), Port = tostring(ClientIPValues[1])
    | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), DistinctUserCount = dcount(UserId), UserId = make_set(UserId, 250), Ports = make_set(Port, 250), EventCount = count() by tostring(DestinationMailAddress), ClientIP
    | where DistinctUserCount > 1 and EndTime > ago(queryfrequency)
    | mv-expand UserId to typeof(string)
    | extend AccountName = tostring(split(UserId, "@")[0]), AccountUPNSuffix = tostring(split(UserId, "@")[1])  
kind: Scheduled
name: Office 365 - Multiple Users Email Forwarded to Same Destination
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - Office_MailForwarding.yaml
description: |
  Identifies when multiple (more than one) users' mailboxes are configured to forward to the same destination. 
  This could be an attacker-controlled destination mailbox configured to collect mail from multiple compromised user accounts.  
status: Available
{
  "$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/d75e8289-d1cb-44d4-bd59-2f44a9172478')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/d75e8289-d1cb-44d4-bd59-2f44a9172478')]",
      "properties": {
        "alertRuleTemplateName": "d75e8289-d1cb-44d4-bd59-2f44a9172478",
        "customDetails": null,
        "description": "Identifies when multiple (more than one) users' mailboxes are configured to forward to the same destination. \nThis could be an attacker-controlled destination mailbox configured to collect mail from multiple compromised user accounts.\n",
        "displayName": "Office 365 - Multiple Users Email Forwarded to Same Destination",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "UserId",
                "identifier": "FullName"
              },
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "AccountUPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "ClientIP",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - Office_MailForwarding.yaml",
        "query": "let queryfrequency = 1d;\n  let queryperiod = 7d;\n  EnrichedMicrosoft365AuditLogs\n  | where TimeGenerated > ago(queryperiod)\n  | where Workload =~ \"Exchange\"\n  //| where Operation in (\"Set-Mailbox\", \"New-InboxRule\", \"Set-InboxRule\")  // Uncomment or adjust based on actual field usage\n  | where tostring(AdditionalProperties.Parameters) has_any (\"ForwardTo\", \"RedirectTo\", \"ForwardingSmtpAddress\")\n  | mv-apply DynamicParameters = todynamic(tostring(AdditionalProperties.Parameters)) on (\n      summarize ParsedParameters = make_bag(bag_pack(tostring(DynamicParameters.Name), DynamicParameters.Value))\n    )\n  | evaluate bag_unpack(ParsedParameters, columnsConflict='replace_source')\n  | extend DestinationMailAddress = tolower(case(\n      isnotempty(column_ifexists(\"ForwardTo\", \"\")), column_ifexists(\"ForwardTo\", \"\"),\n      isnotempty(column_ifexists(\"RedirectTo\", \"\")), column_ifexists(\"RedirectTo\", \"\"),\n      isnotempty(column_ifexists(\"ForwardingSmtpAddress\", \"\")), trim_start(@\"smtp:\", column_ifexists(\"ForwardingSmtpAddress\", \"\")),\n      \"\"))\n  | where isnotempty(DestinationMailAddress)\n  | mv-expand split(DestinationMailAddress, \";\")\n  | extend ClientIPValues = extract_all(@'\\[?(::ffff:)?(?P<IPAddress>(\\d+\\.\\d+\\.\\d+\\.\\d+)|[^\\]]+)\\]?([-:](?P<Port>\\d+))?', dynamic([\"IPAddress\", \"Port\"]), ClientIp)[0]\n  | extend ClientIP = tostring(ClientIPValues[0]), Port = tostring(ClientIPValues[1])\n  | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), DistinctUserCount = dcount(UserId), UserId = make_set(UserId, 250), Ports = make_set(Port, 250), EventCount = count() by tostring(DestinationMailAddress), ClientIP\n  | where DistinctUserCount > 1 and EndTime > ago(queryfrequency)\n  | mv-expand UserId to typeof(string)\n  | extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P7D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Collection",
          "Exfiltration"
        ],
        "techniques": [
          "T1020",
          "T1114"
        ],
        "templateVersion": "2.0.4",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}