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

DCOM Lateral Movement

Back
Idd58035ff-0bac-4c61-a7f4-f58939ff9764
RulenameDCOM Lateral Movement
DescriptionThis detection looks for cases of close-time proximity between incoming network traffic on RPC/TCP, followed by the creation of a DCOM object, followed by the creation of a child process of the DCOM object.

The query first identifies incoming network traffic over RPC/TCP, followed by the creation of a DCOM object (process) within 2 seconds, followed by the creation of a child process of this DCOM object.
SeverityMedium
TacticsLateralMovement
TechniquesT1021.003
Required data connectorsMicrosoftThreatProtection
KindScheduled
Query frequency1h
Query period1h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/FalconFriday/Analytic Rules/DCOMLateralMovement.yaml
Version1.0.0
Arm templated58035ff-0bac-4c61-a7f4-f58939ff9764.json
Deploy To Azure
let allowListedExecs = dynamic(["TiWorker.exe", "dllhost.exe", "backgroundTaskHost.exe", "mobsync.exe", "WmiPrvSE.exe", "RuntimeBroker.exe", "smartscreen.exe", "SppExtComObj.Exe", "usocoreworker.exe", "browser_broker.exe", "ssoncom.exe"]);
let rpcNetwEvents = materialize(DeviceNetworkEvents
| where InitiatingProcessFileName =~ "svchost.exe" and InitiatingProcessCommandLine has "rpcss" and LocalPort == 135
| where LocalIP !~ RemoteIP and ActionType != "ListeningConnectionCreated"
| project TimestampNetwEvent=bin(Timestamp, 5s),TimestampNetwEventExact=Timestamp, DeviceId, DeviceName, RPCHostID=InitiatingProcessId, RPCHostFileName=InitiatingProcessFileName, LocalIP, RemoteIP);
let dcomProcEvents = materialize (DeviceProcessEvents
| where InitiatingProcessFileName =~ "svchost.exe" and InitiatingProcessCommandLine has "dcomlaunch"
| project TimestampProcEvent=bin(Timestamp, 5s),TimestampProcEventExact=Timestamp, DeviceId, DeviceName, DCOMHostPID=InitiatingProcessId, DCOMHostFileName=InitiatingProcessFileName, DCOMPID=ProcessId, DCOMFileName=FileName, DCOMCmdLine=ProcessCommandLine);
let lastBootTime = materialize(DeviceProcessEvents
| where FileName =~ "services.exe"
| summarize LastBootTime=max(Timestamp) by DeviceId);
let RemoteDcomProcs = materialize(rpcNetwEvents
| join kind=inner dcomProcEvents on DeviceId 
| join kind=leftouter lastBootTime on DeviceId
| where TimestampProcEvent > LastBootTime+5m // Ignore first 5 min after boot.
// Avoiding < 2 since if the time between netw and proc creation is negative, they can't be related. Network event must come first. 
| where datetime_diff("second", TimestampProcEventExact, TimestampNetwEventExact) between (0 .. 2) 
// Allow-listing some usual suspects which create lot of noise. This is dangerous though...huge gap for bypass. 
| where DCOMFileName  !in~ (allowListedExecs));
RemoteDcomProcs
| join kind=inner hint.strategy=broadcast (
    DeviceProcessEvents 
    | where InitiatingProcessParentFileName =~ "svchost.exe" and InitiatingProcessFileName in ((RemoteDcomProcs | project DCOMFileName))) 
on $left.DCOMHostPID == $right.InitiatingProcessParentId, DeviceId, $left.DCOMPID == $right.InitiatingProcessId
| where InitiatingProcessParentFileName =~ "svchost.exe" and InitiatingProcessFileName =~ DCOMFileName 
// Allow-listing the magic of Defender.
| where FileName !in~ ("csc.exe") 
| summarize make_set(ProcessCommandLine) by TimestampNetwEventExact, TimestampProcEventExact, DeviceId, DeviceName, InitiatingProcessId, LocalIP, RemoteIP, LastBootTime, DCOMCmdLine
severity: Medium
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/FalconFriday/Analytic Rules/DCOMLateralMovement.yaml
id: d58035ff-0bac-4c61-a7f4-f58939ff9764
name: DCOM Lateral Movement
query: |
  let allowListedExecs = dynamic(["TiWorker.exe", "dllhost.exe", "backgroundTaskHost.exe", "mobsync.exe", "WmiPrvSE.exe", "RuntimeBroker.exe", "smartscreen.exe", "SppExtComObj.Exe", "usocoreworker.exe", "browser_broker.exe", "ssoncom.exe"]);
  let rpcNetwEvents = materialize(DeviceNetworkEvents
  | where InitiatingProcessFileName =~ "svchost.exe" and InitiatingProcessCommandLine has "rpcss" and LocalPort == 135
  | where LocalIP !~ RemoteIP and ActionType != "ListeningConnectionCreated"
  | project TimestampNetwEvent=bin(Timestamp, 5s),TimestampNetwEventExact=Timestamp, DeviceId, DeviceName, RPCHostID=InitiatingProcessId, RPCHostFileName=InitiatingProcessFileName, LocalIP, RemoteIP);
  let dcomProcEvents = materialize (DeviceProcessEvents
  | where InitiatingProcessFileName =~ "svchost.exe" and InitiatingProcessCommandLine has "dcomlaunch"
  | project TimestampProcEvent=bin(Timestamp, 5s),TimestampProcEventExact=Timestamp, DeviceId, DeviceName, DCOMHostPID=InitiatingProcessId, DCOMHostFileName=InitiatingProcessFileName, DCOMPID=ProcessId, DCOMFileName=FileName, DCOMCmdLine=ProcessCommandLine);
  let lastBootTime = materialize(DeviceProcessEvents
  | where FileName =~ "services.exe"
  | summarize LastBootTime=max(Timestamp) by DeviceId);
  let RemoteDcomProcs = materialize(rpcNetwEvents
  | join kind=inner dcomProcEvents on DeviceId 
  | join kind=leftouter lastBootTime on DeviceId
  | where TimestampProcEvent > LastBootTime+5m // Ignore first 5 min after boot.
  // Avoiding < 2 since if the time between netw and proc creation is negative, they can't be related. Network event must come first. 
  | where datetime_diff("second", TimestampProcEventExact, TimestampNetwEventExact) between (0 .. 2) 
  // Allow-listing some usual suspects which create lot of noise. This is dangerous though...huge gap for bypass. 
  | where DCOMFileName  !in~ (allowListedExecs));
  RemoteDcomProcs
  | join kind=inner hint.strategy=broadcast (
      DeviceProcessEvents 
      | where InitiatingProcessParentFileName =~ "svchost.exe" and InitiatingProcessFileName in ((RemoteDcomProcs | project DCOMFileName))) 
  on $left.DCOMHostPID == $right.InitiatingProcessParentId, DeviceId, $left.DCOMPID == $right.InitiatingProcessId
  | where InitiatingProcessParentFileName =~ "svchost.exe" and InitiatingProcessFileName =~ DCOMFileName 
  // Allow-listing the magic of Defender.
  | where FileName !in~ ("csc.exe") 
  | summarize make_set(ProcessCommandLine) by TimestampNetwEventExact, TimestampProcEventExact, DeviceId, DeviceName, InitiatingProcessId, LocalIP, RemoteIP, LastBootTime, DCOMCmdLine  
entityMappings:
- fieldMappings:
  - columnName: DeviceName
    identifier: FullName
  entityType: Host
- fieldMappings:
  - columnName: RemoteIP
    identifier: Address
  entityType: IP
- fieldMappings:
  - columnName: DCOMCmdLine
    identifier: CommandLine
  entityType: Process
queryPeriod: 1h
triggerThreshold: 0
tactics:
- LateralMovement
version: 1.0.0
kind: Scheduled
relevantTechniques:
- T1021.003
queryFrequency: 1h
status: Available
requiredDataConnectors:
- dataTypes:
  - DeviceProcessEvents
  - DeviceNetworkEvents
  connectorId: MicrosoftThreatProtection
description: |
  This detection looks for cases of close-time proximity between incoming network traffic on RPC/TCP, followed by the creation of a DCOM object, followed by the creation of a child process of the DCOM object. 
  The query first identifies incoming network traffic over RPC/TCP, followed by the creation of a DCOM object (process) within 2 seconds, followed by the creation of a child process of this DCOM object.   
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": "2023-02-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/d58035ff-0bac-4c61-a7f4-f58939ff9764')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/d58035ff-0bac-4c61-a7f4-f58939ff9764')]",
      "properties": {
        "alertRuleTemplateName": "d58035ff-0bac-4c61-a7f4-f58939ff9764",
        "customDetails": null,
        "description": "This detection looks for cases of close-time proximity between incoming network traffic on RPC/TCP, followed by the creation of a DCOM object, followed by the creation of a child process of the DCOM object. \nThe query first identifies incoming network traffic over RPC/TCP, followed by the creation of a DCOM object (process) within 2 seconds, followed by the creation of a child process of this DCOM object. \n",
        "displayName": "DCOM Lateral Movement",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "DeviceName",
                "identifier": "FullName"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "RemoteIP",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "Process",
            "fieldMappings": [
              {
                "columnName": "DCOMCmdLine",
                "identifier": "CommandLine"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/FalconFriday/Analytic Rules/DCOMLateralMovement.yaml",
        "query": "let allowListedExecs = dynamic([\"TiWorker.exe\", \"dllhost.exe\", \"backgroundTaskHost.exe\", \"mobsync.exe\", \"WmiPrvSE.exe\", \"RuntimeBroker.exe\", \"smartscreen.exe\", \"SppExtComObj.Exe\", \"usocoreworker.exe\", \"browser_broker.exe\", \"ssoncom.exe\"]);\nlet rpcNetwEvents = materialize(DeviceNetworkEvents\n| where InitiatingProcessFileName =~ \"svchost.exe\" and InitiatingProcessCommandLine has \"rpcss\" and LocalPort == 135\n| where LocalIP !~ RemoteIP and ActionType != \"ListeningConnectionCreated\"\n| project TimestampNetwEvent=bin(Timestamp, 5s),TimestampNetwEventExact=Timestamp, DeviceId, DeviceName, RPCHostID=InitiatingProcessId, RPCHostFileName=InitiatingProcessFileName, LocalIP, RemoteIP);\nlet dcomProcEvents = materialize (DeviceProcessEvents\n| where InitiatingProcessFileName =~ \"svchost.exe\" and InitiatingProcessCommandLine has \"dcomlaunch\"\n| project TimestampProcEvent=bin(Timestamp, 5s),TimestampProcEventExact=Timestamp, DeviceId, DeviceName, DCOMHostPID=InitiatingProcessId, DCOMHostFileName=InitiatingProcessFileName, DCOMPID=ProcessId, DCOMFileName=FileName, DCOMCmdLine=ProcessCommandLine);\nlet lastBootTime = materialize(DeviceProcessEvents\n| where FileName =~ \"services.exe\"\n| summarize LastBootTime=max(Timestamp) by DeviceId);\nlet RemoteDcomProcs = materialize(rpcNetwEvents\n| join kind=inner dcomProcEvents on DeviceId \n| join kind=leftouter lastBootTime on DeviceId\n| where TimestampProcEvent > LastBootTime+5m // Ignore first 5 min after boot.\n// Avoiding < 2 since if the time between netw and proc creation is negative, they can't be related. Network event must come first. \n| where datetime_diff(\"second\", TimestampProcEventExact, TimestampNetwEventExact) between (0 .. 2) \n// Allow-listing some usual suspects which create lot of noise. This is dangerous though...huge gap for bypass. \n| where DCOMFileName  !in~ (allowListedExecs));\nRemoteDcomProcs\n| join kind=inner hint.strategy=broadcast (\n    DeviceProcessEvents \n    | where InitiatingProcessParentFileName =~ \"svchost.exe\" and InitiatingProcessFileName in ((RemoteDcomProcs | project DCOMFileName))) \non $left.DCOMHostPID == $right.InitiatingProcessParentId, DeviceId, $left.DCOMPID == $right.InitiatingProcessId\n| where InitiatingProcessParentFileName =~ \"svchost.exe\" and InitiatingProcessFileName =~ DCOMFileName \n// Allow-listing the magic of Defender.\n| where FileName !in~ (\"csc.exe\") \n| summarize make_set(ProcessCommandLine) by TimestampNetwEventExact, TimestampProcEventExact, DeviceId, DeviceName, InitiatingProcessId, LocalIP, RemoteIP, LastBootTime, DCOMCmdLine\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT1H",
        "severity": "Medium",
        "status": "Available",
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "LateralMovement"
        ],
        "techniques": [
          "T1021"
        ],
        "templateVersion": "1.0.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}