Hunting for DCOM Lateral Movement Authorized Testing Disclaimer : The offensive techniques and attack simulations described in this skill are intended exclusively for authorized penetration testing, red team engagements, purple team exercises, and security research conducted with explicit written permission from the system owner. Unauthorized use of these techniques against systems you do not own or have permission to test is illegal and unethical. Always operate within the scope of your engagement and comply with applicable laws and regulations. Overview Distributed Component Object Model (D…

\\t' -k2 | uniq -c | sort -rn\n\n# Track RPC endpoint mapper connections between internal hosts\ncat /opt/zeek/logs/current/conn.log | \\\n zeek-cut ts id.orig_h id.resp_h id.resp_p duration | \\\n awk '$4 == 135' | \\\n awk '{print $2, \"->\", $3}' | sort | uniq -c | sort -rn | head -20\n```\n\n### Step 7: DCOM Attack Surface Audit and Hardening\n\n```powershell\n# Audit DCOM configuration across the domain\n# Enumerate remotely accessible DCOM objects\n\n# List DCOM applications registered on local system\nGet-CimInstance -ClassName Win32_DCOMApplication |\n Select-Object AppID, Name |\n Sort-Object Name |\n Format-Table -AutoSize\n\n# Check DCOM launch permissions for high-risk objects\n$clsids = @{\n \"MMC20.Application\" = \"{49B2791A-B1AE-4C90-9B8E-E860BA07F889}\"\n \"ShellWindows\" = \"{9BA05972-F6A8-11CF-A442-00A0C90A8F39}\"\n \"ShellBrowserWindow\" = \"{C08AFD90-F2A1-11D1-8455-00A0C91F3880}\"\n \"Excel.Application\" = \"{00024500-0000-0000-C000-000000000046}\"\n \"Outlook.Application\" = \"{0006F03A-0000-0000-C000-000000000046}\"\n}\n\nforeach ($name in $clsids.Keys) {\n $clsid = $clsids[$name]\n $regPath = \"HKLM:\\SOFTWARE\\Classes\\CLSID\\$clsid\"\n if (Test-Path $regPath) {\n $launchPermission = (Get-ItemProperty -Path \"$regPath\" -Name \"LaunchPermission\" -ErrorAction SilentlyContinue)\n Write-Host \"[*] $name ($clsid): $(if ($launchPermission) { 'Custom permissions set' } else { 'DEFAULT permissions (potentially exploitable)' })\"\n } else {\n Write-Host \"[-] $name ($clsid): Not found on this system\"\n }\n}\n\n# Check if DCOM is enabled (should be restricted on servers that don't need it)\n$dcomEnabled = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\Microsoft\\Ole\" -Name \"EnableDCOM\").EnableDCOM\nWrite-Host \"`n[*] DCOM Enabled: $dcomEnabled\"\n\n# Check remote launch and activation permissions\n$remoteLaunch = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\Microsoft\\Ole\" -Name \"DefaultLaunchPermission\" -ErrorAction SilentlyContinue)\nWrite-Host \"[*] Default Launch Permission: $(if ($remoteLaunch) { 'Custom' } else { 'System Default' })\"\n```\n\n```powershell\n# Hardening: Restrict DCOM remote access via Group Policy\n# These settings should be applied via GPO in production\n\n# Disable DCOM on systems that do not require it\n# Computer Configuration > Administrative Templates > System > Distributed COM >\n# Application Compatibility > Enable Distributed COM on this computer = Disabled\n\n# Restrict DCOM launch permissions via registry\n# Set-ItemProperty -Path \"HKLM:\\SOFTWARE\\Microsoft\\Ole\" -Name \"EnableDCOM\" -Value \"N\"\n\n# Block RPC/DCOM at the host firewall for non-admin traffic\n# New-NetFirewallRule -DisplayName \"Block Inbound DCOM/RPC\" `\n# -Direction Inbound -LocalPort 135 -Protocol TCP `\n# -Action Block -RemoteAddress \"Any\" `\n# -Group \"DCOM Hardening\"\n#\n# New-NetFirewallRule -DisplayName \"Allow DCOM from Admin Subnets\" `\n# -Direction Inbound -LocalPort 135 -Protocol TCP `\n# -Action Allow -RemoteAddress \"10.10.0.0/24\" `\n# -Group \"DCOM Hardening\"\n\n# Windows Firewall: Restrict dynamic RPC port range\n# netsh int ipv4 set dynamicport tcp start=49152 num=1024\n```\n\n## Key Concepts\n\n| Term | Definition |\n|------|------------|\n| **DCOM (T1021.003)** | Distributed Component Object Model -- extends COM to allow remote object instantiation and method invocation over RPC, abused for lateral movement |\n| **MMC20.Application** | COM object (CLSID {49B2791A-B1AE-4C90-9B8E-E860BA07F889}) controlling MMC snap-ins; `ExecuteShellCommand` method enables remote command execution |\n| **ShellWindows** | COM object (CLSID {9BA05972-F6A8-11CF-A442-00A0C90A8F39}) that activates within an existing explorer.exe process, executing commands without creating a new COM server process |\n| **ShellBrowserWindow** | COM object (CLSID {C08AFD90-F2A1-11D1-8455-00A0C91F3880}) similar to ShellWindows, uses `Document.Application.ShellExecute` for stealthy command execution |\n| **RPC Endpoint Mapper** | Service on TCP port 135 that maps RPC interfaces to dynamic ports; all DCOM communication begins with an endpoint mapper query |\n| **Sysmon Event ID 1** | Process Create event capturing parent-child process relationships, command lines, and user context -- critical for identifying DCOM-spawned processes |\n| **Sysmon Event ID 3** | Network Connection event capturing source/destination IPs and ports -- used to correlate RPC connections with subsequent process creation |\n| **DcomLaunch** | Windows service (svchost.exe -k DcomLaunch) that manages DCOM server process activation; parent process of COM servers spawned via remote DCOM calls |\n| **WMI-Activity ETW** | Event Tracing for Windows provider that logs WMI method calls, instance creations, and queries -- provides visibility into DCOM-triggered WMI operations |\n\n## Tools & Systems\n\n| Tool | Purpose |\n|------|---------|\n| **Sysmon** | Endpoint telemetry for process creation (EID 1), network connections (EID 3), and image loads (EID 7) essential for DCOM detection |\n| **Splunk / Elastic SIEM** | Log aggregation and correlation platform for DCOM detection rules and threat hunting queries |\n| **Microsoft Sentinel** | Cloud SIEM with built-in KQL queries and analytics rules for DCOM lateral movement detection |\n| **Sigma** | Vendor-agnostic detection rule format for portable DCOM detection rules |\n| **Zeek** | Network security monitor for DCE-RPC protocol analysis and RPC endpoint mapper traffic monitoring |\n| **Atomic Red Team** | MITRE ATT&CK test framework with T1021.003 atomics for validating DCOM detection coverage |\n| **Impacket (dcomexec.py)** | Python-based DCOM execution tool used by attackers and red teamers for testing DCOM lateral movement |\n| **CIMSession / PowerShell** | Native Windows tooling for DCOM object instantiation used in both legitimate administration and attacks |\n\n## Common Scenarios\n\n### Scenario 1: MMC20.Application Lateral Movement to File Server\n\n**Context**: A SOC analyst receives an alert for mmc.exe spawning cmd.exe on a file server (10.10.20.50) at 03:22 UTC. No administrator activity is scheduled at this time.\n\n**Approach**:\n1. Query Sysmon Event ID 1 on 10.10.20.50: confirm mmc.exe (parent: svchost.exe -k DcomLaunch) spawned cmd.exe with command line `/c net user /domain > C:\\temp\\users.txt`\n2. Query Sysmon Event ID 3 on 10.10.20.50: identify inbound TCP connection on port 135 from 10.10.5.30 at 03:22:01, followed by a high-port connection at 03:22:02\n3. Correlate Event ID 4624 on 10.10.20.50: find LogonType 3 from 10.10.5.30 at 03:22:00 with admin credentials\n4. Investigate 10.10.5.30: check for compromise indicators -- find Mimikatz artifacts in memory, evidence of credential dumping at 03:15\n5. Trace the attack chain: initial phishing compromise at 02:45, credential theft at 03:15, DCOM lateral movement at 03:22\n6. Contain: isolate 10.10.5.30 and 10.10.20.50, force password reset for compromised admin account, block inbound RPC from non-admin subnets\n\n**Pitfalls**:\n- Dismissing mmc.exe activity as legitimate MMC administration without checking the parent process and command line\n- Not correlating the network logon (4624) with the process creation to identify the true source host\n- Failing to investigate the source host for initial compromise indicators\n\n### Scenario 2: ShellWindows Stealthy Lateral Movement\n\n**Context**: During a threat hunt, an analyst queries for explorer.exe spawning cmd.exe on domain controllers and finds several instances on DC01 with no interactive logon sessions.\n\n**Approach**:\n1. Verify no interactive sessions: query Event ID 4624 LogonType 2 or 10 on DC01 -- none found during the time window\n2. Query Sysmon Event ID 1: explorer.exe spawning cmd.exe with encoded PowerShell commands at 14:05, 14:12, and 14:18\n3. Decode the PowerShell: reveals reconnaissance commands (Get-ADUser, Get-ADGroup, Get-ADComputer)\n4. Query Sysmon Event ID 3: inbound RPC connections from 10.10.3.15 preceding each process creation\n5. Identify the ShellWindows pattern: no new mmc.exe or dllhost.exe process created -- commands execute through existing explorer.exe, consistent with ShellWindows/ShellBrowserWindow DCOM abuse\n6. Investigate 10.10.3.15: compromised workstation with Cobalt Strike beacon artifacts\n\n**Pitfalls**:\n- Missing the attack because ShellWindows does not create a separate COM server process -- requires monitoring explorer.exe child processes\n- Not having Sysmon Event ID 3 configured to capture network connections from explorer.exe\n- Filtering out explorer.exe as a legitimate parent process without considering the server context\n\n## Output Format\n\n```\nHunt ID: TH-DCOM-[DATE]-[SEQ]\nAlert Severity: High\nMITRE Technique: T1021.003 (Remote Services: DCOM)\n\nSource Host: [IP/Hostname of attacker's machine]\nTarget Host: [IP/Hostname where DCOM executed]\nDCOM Object: [MMC20.Application | ShellWindows | ShellBrowserWindow]\nCLSID: [COM object class identifier]\n\nProcess Chain:\n Parent: [svchost.exe -k DcomLaunch | explorer.exe | mmc.exe]\n Child: [cmd.exe | powershell.exe | ...]\n Command Line: [Full command executed]\n\nNetwork Indicators:\n RPC Connection: [Source IP]:port -> [Target IP]:135 at [timestamp]\n DCOM Port: [Source IP]:port -> [Target IP]:[high-port] at [timestamp]\n\nAuthentication Context:\n Event 4624: LogonType 3 from [Source IP] at [timestamp]\n Account: [Domain\\Username]\n Logon ID: [Logon session identifier]\n\nRisk Assessment: [Critical/High/Medium]\nRecommended Action: [Isolate, investigate source, reset credentials, restrict DCOM]\n```\n---","attachment_filenames":["references/api-reference.md","scripts/agent.py","scripts/detect_dcom_lateral_movement.py"],"attachments":[{"filename":"references/api-reference.md","content":"# DCOM Lateral Movement Detection API Reference\n\n## MITRE ATT&CK Mapping\n\n| Technique | ID | Description |\n|-----------|----|-------------|\n| Remote Services: DCOM | T1021.003 | Adversaries use DCOM to execute commands on remote systems |\n| Lateral Movement | TA0008 | Tactic covering movement between networked systems |\n| Windows Management Instrumentation | T1047 | WMI often correlated with DCOM lateral movement |\n\n## DCOM COM Objects Abused for Lateral Movement\n\n| COM Object | CLSID | Method | Parent Process |\n|------------|-------|--------|---------------|\n| MMC20.Application | {49B2791A-B1AE-4C90-9B8E-E860BA07F889} | ExecuteShellCommand | mmc.exe via svchost.exe -k DcomLaunch |\n| ShellWindows | {9BA05972-F6A8-11CF-A442-00A0C90A8F39} | Document.Application.ShellExecute | explorer.exe (existing process) |\n| ShellBrowserWindow | {C08AFD90-F2A1-11D1-8455-00A0C91F3880} | Document.Application.ShellExecute | explorer.exe (existing process) |\n| Excel.Application | {00024500-0000-0000-C000-000000000046} | DDEInitiate / RegisterXLL | excel.exe via svchost.exe -k DcomLaunch |\n| Outlook.Application | {0006F03A-0000-0000-C000-000000000046} | CreateObject | outlook.exe via svchost.exe -k DcomLaunch |\n\n## Sysmon Event IDs for DCOM Detection\n\n| Event ID | Name | DCOM Relevance |\n|----------|------|----------------|\n| 1 | Process Create | Detects DCOM parent (mmc.exe, dllhost.exe, explorer.exe) spawning suspicious children |\n| 3 | Network Connection | Captures inbound RPC (port 135) and dynamic high-port DCOM connections |\n| 7 | Image Loaded | Tracks loading of DCOM-related DLLs (ole32.dll, comsvcs.dll, rpcrt4.dll) |\n| 10 | Process Access | Detects cross-process access patterns from DCOM processes |\n| 11 | File Create | Identifies file drops from DCOM-executed commands |\n\n## Windows Security Event IDs\n\n| Event ID | Log | DCOM Context |\n|----------|-----|-------------|\n| 4624 (Type 3) | Security | Network logon preceding DCOM execution on target |\n| 4672 | Security | Special privileges assigned during DCOM remote activation |\n| 4688 | Security | Process creation (alternative to Sysmon EID 1 if enabled) |\n\n## WMI-Activity Operational Event IDs\n\n| Event ID | Description |\n|----------|-------------|\n| 5857 | WMI provider loaded (DCOM can trigger WMI operations) |\n| 5858 | WMI query error |\n| 5860 | Temporary WMI event consumer registration |\n| 5861 | Permanent WMI event consumer registration |\n\n## Network Indicators\n\n| Protocol | Port | Description |\n|----------|------|-------------|\n| TCP | 135 | RPC Endpoint Mapper - all DCOM starts here |\n| TCP | 49152-65535 | Dynamic RPC ports for DCOM data transfer |\n| TCP | 445 | SMB - may follow DCOM for file operations |\n| TCP | 139 | NetBIOS Session Service |\n\n## Splunk SPL - DCOM Detection Queries\n\n```spl\n# MMC20.Application lateral movement\nindex=wineventlog sourcetype=\"XmlWinEventLog:Microsoft-Windows-Sysmon/Operational\"\nEventCode=1 ParentImage=\"*\\\\mmc.exe\"\n(Image=\"*\\\\cmd.exe\" OR Image=\"*\\\\powershell.exe\")\n| table _time ComputerName ParentImage Image CommandLine User\n\n# Inbound RPC connections (DCOM prerequisite)\nindex=wineventlog sourcetype=\"XmlWinEventLog:Microsoft-Windows-Sysmon/Operational\"\nEventCode=3 DestinationPort=135 Initiated=\"false\"\n| stats dc(SourceIp) as sources count by ComputerName\n| where sources > 3\n```\n\n## KQL - Microsoft Sentinel Queries\n\n```kql\n// DCOM process creation from mmc.exe or dllhost.exe\nSysmonEvent\n| where EventID == 1\n| where ParentImage endswith \"\\\\mmc.exe\" or ParentImage endswith \"\\\\dllhost.exe\"\n| where Image endswith \"\\\\cmd.exe\" or Image endswith \"\\\\powershell.exe\"\n| project TimeGenerated, Computer, ParentImage, Image, CommandLine, User\n```\n\n## python-evtx - Parse Sysmon EVTX\n\n```python\nfrom Evtx.Evtx import FileHeader\nfrom lxml import etree\n\nNS = {\"evt\": \"http://schemas.microsoft.com/win/2004/08/events/event\"}\nwith open(\"Microsoft-Windows-Sysmon%4Operational.evtx\", \"rb\") as f:\n fh = FileHeader(f)\n for record in fh.records():\n root = etree.fromstring(record.xml().encode(\"utf-8\"))\n eid = root.find(\".//evt:System/evt:EventID\", NS)\n if eid is not None and eid.text == \"1\":\n data = {e.get(\"Name\"): e.text for e in root.findall(\".//evt:EventData/evt:Data\", NS)}\n print(data.get(\"ParentImage\"), \"->\", data.get(\"Image\"))\n```\n\n## Atomic Red Team - T1021.003 Test Cases\n\n| Atomic Test | Description |\n|-------------|-------------|\n| MMC20.Application Lateral Movement | Instantiates MMC20.Application DCOM and calls ExecuteShellCommand |\n| ShellWindows Lateral Movement | Uses ShellWindows CLSID for remote command execution |\n| Excel DDE DCOM | Creates remote Excel instance and triggers DDE execution |\n\n## Impacket - dcomexec.py\n\n```bash\n# Attack tool reference (for detection validation in authorized testing)\n# dcomexec.py creates a DCOM connection and executes commands\n# Protocol: Uses MMC20.Application, ShellWindows, or ShellBrowserWindow\npython3 dcomexec.py domain/user:password@target_ip \"whoami\"\npython3 dcomexec.py -object MMC20 domain/user:password@target_ip \"cmd.exe /c ipconfig\"\npython3 dcomexec.py -object ShellWindows domain/user:password@target_ip \"powershell -c Get-Process\"\n```\n\n## References\n\n- MITRE ATT&CK T1021.003: https://attack.mitre.org/techniques/T1021/003/\n- Cybereason DCOM Research: https://www.cybereason.com/blog/dcom-lateral-movement-techniques\n- MDSec DCOM Lateral Movement: https://www.mdsec.co.uk/2020/09/i-like-to-move-it-windows-lateral-movement-part-2-dcom/\n- Elastic Detection Rule: https://www.elastic.co/guide/en/security/8.19/incoming-dcom-lateral-movement-with-shellbrowserwindow-or-shellwindows.html\n- Atomic Red Team T1021.003: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1021.003/T1021.003.md\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":5744,"content_sha256":"55bfea0ebc70fa38f1e9f5d06566221411003ea265d3fabe62c60d990715e7ce"},{"filename":"scripts/agent.py","content":"#!/usr/bin/env python3\n\"\"\"DCOM Lateral Movement Detection Agent - Hunts for DCOM object abuse via Sysmon event correlation.\"\"\"\n\nimport json\nimport logging\nimport argparse\nimport os\nimport sys\nimport subprocess\nfrom collections import defaultdict\nfrom datetime import datetime, timedelta\n\nlogging.basicConfig(level=logging.INFO, format=\"%(asctime)s [%(levelname)s] %(message)s\")\nlogger = logging.getLogger(__name__)\n\n# DCOM COM object CLSIDs used for lateral movement\nDCOM_CLSIDS = {\n \"{49B2791A-B1AE-4C90-9B8E-E860BA07F889}\": \"MMC20.Application\",\n \"{9BA05972-F6A8-11CF-A442-00A0C90A8F39}\": \"ShellWindows\",\n \"{C08AFD90-F2A1-11D1-8455-00A0C91F3880}\": \"ShellBrowserWindow\",\n \"{00024500-0000-0000-C000-000000000046}\": \"Excel.Application\",\n \"{0006F03A-0000-0000-C000-000000000046}\": \"Outlook.Application\",\n}\n\nDCOM_PARENT_PROCESSES = [\"mmc.exe\", \"dllhost.exe\", \"explorer.exe\"]\nSUSPICIOUS_CHILDREN = [\n \"cmd.exe\", \"powershell.exe\", \"pwsh.exe\", \"wscript.exe\",\n \"cscript.exe\", \"mshta.exe\", \"rundll32.exe\", \"regsvr32.exe\",\n \"certutil.exe\", \"bitsadmin.exe\",\n]\n\nSYSMON_NS = \"http://schemas.microsoft.com/win/2004/08/events/event\"\nEVTX_PARSE_TIMEOUT = 300 # seconds\n\n\ndef parse_evtx_records(evtx_path):\n \"\"\"Parse Sysmon EVTX file into structured events using python-evtx.\"\"\"\n try:\n from Evtx.Evtx import FileHeader\n from lxml import etree\n except ImportError:\n logger.error(\"Required packages missing. Install: pip install python-evtx lxml\")\n sys.exit(1)\n\n events = []\n ns = {\"evt\": SYSMON_NS}\n with open(evtx_path, \"rb\") as f:\n fh = FileHeader(f)\n for record in fh.records():\n try:\n xml = record.xml()\n root = etree.fromstring(xml.encode(\"utf-8\"))\n event_id_elem = root.find(\".//evt:System/evt:EventID\", ns)\n if event_id_elem is None:\n continue\n eid = int(event_id_elem.text)\n if eid not in (1, 3, 7):\n continue\n data = {}\n for elem in root.findall(\".//evt:EventData/evt:Data\", ns):\n data[elem.get(\"Name\", \"\")] = elem.text or \"\"\n time_elem = root.find(\".//evt:System/evt:TimeCreated\", ns)\n timestamp = time_elem.get(\"SystemTime\", \"\") if time_elem is not None else \"\"\n comp_elem = root.find(\".//evt:System/evt:Computer\", ns)\n computer = comp_elem.text if comp_elem is not None else \"\"\n data[\"EventID\"] = eid\n data[\"TimeCreated\"] = timestamp\n data[\"Computer\"] = computer\n events.append(data)\n except Exception:\n continue\n logger.info(\"Parsed %d Sysmon events (EID 1,3,7) from %s\", len(events), evtx_path)\n return events\n\n\ndef detect_mmc20_lateral(events):\n \"\"\"Detect MMC20.Application DCOM lateral movement: mmc.exe spawning suspicious children.\"\"\"\n findings = []\n for ev in events:\n if ev.get(\"EventID\") != 1:\n continue\n parent = ev.get(\"ParentImage\", \"\").lower()\n image = ev.get(\"Image\", \"\").lower()\n if \"mmc.exe\" not in parent:\n continue\n if not any(child in image for child in SUSPICIOUS_CHILDREN):\n continue\n findings.append({\n \"detection\": \"MMC20.Application DCOM Lateral Movement\",\n \"severity\": \"HIGH\",\n \"mitre\": \"T1021.003\",\n \"timestamp\": ev.get(\"TimeCreated\"),\n \"computer\": ev.get(\"Computer\"),\n \"parent_image\": ev.get(\"ParentImage\"),\n \"parent_cmdline\": ev.get(\"ParentCommandLine\"),\n \"child_image\": ev.get(\"Image\"),\n \"child_cmdline\": ev.get(\"CommandLine\"),\n \"user\": ev.get(\"User\"),\n \"clsid\": \"{49B2791A-B1AE-4C90-9B8E-E860BA07F889}\",\n })\n logger.info(\"MMC20 detections: %d\", len(findings))\n return findings\n\n\ndef detect_shell_dcom_lateral(events):\n \"\"\"Detect ShellWindows/ShellBrowserWindow: explorer.exe spawning cmd/powershell.\"\"\"\n findings = []\n for ev in events:\n if ev.get(\"EventID\") != 1:\n continue\n parent = ev.get(\"ParentImage\", \"\").lower()\n image = ev.get(\"Image\", \"\").lower()\n if \"explorer.exe\" not in parent:\n continue\n if not any(child in image for child in [\"cmd.exe\", \"powershell.exe\", \"pwsh.exe\",\n \"mshta.exe\", \"wscript.exe\", \"cscript.exe\"]):\n continue\n findings.append({\n \"detection\": \"ShellWindows/ShellBrowserWindow DCOM Lateral Movement\",\n \"severity\": \"MEDIUM\",\n \"mitre\": \"T1021.003\",\n \"timestamp\": ev.get(\"TimeCreated\"),\n \"computer\": ev.get(\"Computer\"),\n \"parent_image\": ev.get(\"ParentImage\"),\n \"child_image\": ev.get(\"Image\"),\n \"child_cmdline\": ev.get(\"CommandLine\"),\n \"user\": ev.get(\"User\"),\n \"clsid\": \"{9BA05972} or {C08AFD90}\",\n })\n logger.info(\"ShellWindows/ShellBrowserWindow detections: %d\", len(findings))\n return findings\n\n\ndef detect_dllhost_lateral(events):\n \"\"\"Detect DCOM via dllhost.exe spawning suspicious children.\"\"\"\n findings = []\n for ev in events:\n if ev.get(\"EventID\") != 1:\n continue\n parent = ev.get(\"ParentImage\", \"\").lower()\n image = ev.get(\"Image\", \"\").lower()\n if \"dllhost.exe\" not in parent:\n continue\n if not any(child in image for child in SUSPICIOUS_CHILDREN):\n continue\n parent_cmdline = ev.get(\"ParentCommandLine\", \"\")\n clsid = \"Unknown\"\n if \"/Processid:\" in parent_cmdline:\n start = parent_cmdline.find(\"/Processid:\") + len(\"/Processid:\")\n clsid_raw = parent_cmdline[start:].strip().strip(\"{}\")\n clsid = \"{\" + clsid_raw + \"}\"\n dcom_name = DCOM_CLSIDS.get(clsid.upper(), \"Unknown DCOM Object\")\n findings.append({\n \"detection\": f\"DCOM via dllhost.exe ({dcom_name})\",\n \"severity\": \"HIGH\",\n \"mitre\": \"T1021.003\",\n \"timestamp\": ev.get(\"TimeCreated\"),\n \"computer\": ev.get(\"Computer\"),\n \"parent_image\": ev.get(\"ParentImage\"),\n \"parent_cmdline\": parent_cmdline,\n \"child_image\": ev.get(\"Image\"),\n \"child_cmdline\": ev.get(\"CommandLine\"),\n \"user\": ev.get(\"User\"),\n \"clsid\": clsid,\n \"dcom_object\": dcom_name,\n })\n logger.info(\"dllhost.exe DCOM detections: %d\", len(findings))\n return findings\n\n\ndef detect_rpc_connections(events):\n \"\"\"Detect inbound RPC endpoint mapper connections (port 135) from Sysmon Event ID 3.\"\"\"\n rpc_connections = []\n for ev in events:\n if ev.get(\"EventID\") != 3:\n continue\n dest_port = ev.get(\"DestinationPort\", \"\")\n initiated = ev.get(\"Initiated\", \"\").lower()\n if dest_port == \"135\" and initiated == \"false\":\n rpc_connections.append({\n \"detection\": \"Inbound RPC Connection (DCOM Prerequisite)\",\n \"severity\": \"LOW\",\n \"timestamp\": ev.get(\"TimeCreated\"),\n \"computer\": ev.get(\"Computer\"),\n \"source_ip\": ev.get(\"SourceIp\"),\n \"dest_ip\": ev.get(\"DestinationIp\"),\n \"dest_port\": dest_port,\n \"image\": ev.get(\"Image\"),\n })\n logger.info(\"Inbound RPC (port 135) connections: %d\", len(rpc_connections))\n return rpc_connections\n\n\ndef correlate_rpc_with_process(rpc_events, process_findings, window_seconds=60):\n \"\"\"Correlate RPC connections with DCOM process creation for high-confidence detections.\"\"\"\n correlated = []\n for proc in process_findings:\n proc_time_str = proc.get(\"timestamp\", \"\")\n proc_computer = proc.get(\"computer\", \"\")\n if not proc_time_str:\n continue\n try:\n proc_dt = datetime.fromisoformat(proc_time_str.replace(\"Z\", \"+00:00\"))\n except (ValueError, TypeError):\n continue\n for rpc in rpc_events:\n rpc_time_str = rpc.get(\"timestamp\", \"\")\n rpc_computer = rpc.get(\"computer\", \"\")\n if not rpc_time_str or rpc_computer != proc_computer:\n continue\n try:\n rpc_dt = datetime.fromisoformat(rpc_time_str.replace(\"Z\", \"+00:00\"))\n except (ValueError, TypeError):\n continue\n delta = (proc_dt - rpc_dt).total_seconds()\n if 0 \u003c= delta \u003c= window_seconds:\n correlated.append({\n \"detection\": \"CORRELATED: RPC Connection -> DCOM Process Creation\",\n \"severity\": \"CRITICAL\",\n \"mitre\": \"T1021.003\",\n \"computer\": proc_computer,\n \"source_ip\": rpc.get(\"source_ip\"),\n \"rpc_time\": rpc_time_str,\n \"process_time\": proc_time_str,\n \"time_delta_seconds\": round(delta, 2),\n \"dcom_detection\": proc.get(\"detection\"),\n \"child_image\": proc.get(\"child_image\"),\n \"child_cmdline\": proc.get(\"child_cmdline\"),\n \"user\": proc.get(\"user\"),\n })\n break\n logger.info(\"Correlated RPC->Process chains: %d\", len(correlated))\n return correlated\n\n\ndef audit_dcom_config():\n \"\"\"Audit local DCOM configuration for high-risk COM objects (Windows only).\"\"\"\n if sys.platform != \"win32\":\n logger.info(\"DCOM config audit only available on Windows\")\n return []\n\n audit_results = []\n for clsid, name in DCOM_CLSIDS.items():\n try:\n result = subprocess.run(\n [\"reg\", \"query\", f\"HKLM\\\\SOFTWARE\\\\Classes\\\\CLSID\\\\{clsid}\"],\n capture_output=True, text=True, timeout=10\n )\n exists = result.returncode == 0\n audit_results.append({\n \"clsid\": clsid,\n \"name\": name,\n \"registered\": exists,\n \"risk\": \"HIGH\" if exists else \"N/A\",\n })\n except subprocess.TimeoutExpired:\n audit_results.append({\"clsid\": clsid, \"name\": name, \"registered\": \"TIMEOUT\", \"risk\": \"UNKNOWN\"})\n except Exception as e:\n audit_results.append({\"clsid\": clsid, \"name\": name, \"registered\": f\"ERROR: {e}\", \"risk\": \"UNKNOWN\"})\n\n # Check if DCOM is enabled\n try:\n result = subprocess.run(\n [\"reg\", \"query\", \"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Ole\", \"/v\", \"EnableDCOM\"],\n capture_output=True, text=True, timeout=10\n )\n dcom_enabled = \"Y\" in result.stdout if result.returncode == 0 else \"UNKNOWN\"\n audit_results.append({\"check\": \"DCOM Enabled\", \"value\": dcom_enabled,\n \"risk\": \"HIGH\" if dcom_enabled == \"Y\" else \"LOW\"})\n except (subprocess.TimeoutExpired, Exception):\n pass\n\n return audit_results\n\n\ndef generate_report(all_findings, dcom_audit, output_path):\n \"\"\"Generate JSON detection report.\"\"\"\n report = {\n \"scan_timestamp\": datetime.utcnow().isoformat() + \"Z\",\n \"mitre_technique\": \"T1021.003\",\n \"summary\": {\n \"total_findings\": len(all_findings),\n \"critical\": len([f for f in all_findings if f.get(\"severity\") == \"CRITICAL\"]),\n \"high\": len([f for f in all_findings if f.get(\"severity\") == \"HIGH\"]),\n \"medium\": len([f for f in all_findings if f.get(\"severity\") == \"MEDIUM\"]),\n \"low\": len([f for f in all_findings if f.get(\"severity\") == \"LOW\"]),\n },\n \"findings\": all_findings,\n \"dcom_config_audit\": dcom_audit,\n }\n\n with open(output_path, \"w\") as f:\n json.dump(report, f, indent=2, default=str)\n logger.info(\"Report saved to %s\", output_path)\n\n s = report[\"summary\"]\n print(f\"\\nDCOM LATERAL MOVEMENT DETECTION REPORT\")\n print(f\" Total findings: {s['total_findings']}\")\n print(f\" Critical: {s['critical']}, High: {s['high']}, Medium: {s['medium']}, Low: {s['low']}\")\n if s[\"critical\"] > 0:\n print(\" [!!!] CRITICAL: Correlated RPC + process creation chains detected\")\n return report\n\n\ndef main():\n parser = argparse.ArgumentParser(\n description=\"DCOM Lateral Movement Detection Agent (T1021.003)\"\n )\n parser.add_argument(\"--evtx\", required=True, help=\"Path to Sysmon .evtx log file\")\n parser.add_argument(\"--output\", \"-o\", default=\"dcom_detection_report.json\",\n help=\"Output JSON report path (default: dcom_detection_report.json)\")\n parser.add_argument(\"--correlation-window\", type=int, default=60,\n help=\"Seconds window for RPC-to-process correlation (default: 60)\")\n parser.add_argument(\"--audit-dcom\", action=\"store_true\",\n help=\"Audit local DCOM object registration (Windows only)\")\n parser.add_argument(\"--verbose\", \"-v\", action=\"store_true\", help=\"Enable debug logging\")\n args = parser.parse_args()\n\n if args.verbose:\n logging.getLogger().setLevel(logging.DEBUG)\n\n if not os.path.isfile(args.evtx):\n logger.error(\"EVTX file not found: %s\", args.evtx)\n sys.exit(1)\n\n logger.info(\"Parsing Sysmon events from: %s\", args.evtx)\n events = parse_evtx_records(args.evtx)\n\n mmc_findings = detect_mmc20_lateral(events)\n shell_findings = detect_shell_dcom_lateral(events)\n dllhost_findings = detect_dllhost_lateral(events)\n rpc_connections = detect_rpc_connections(events)\n\n all_process_findings = mmc_findings + shell_findings + dllhost_findings\n correlated = correlate_rpc_with_process(\n rpc_connections, all_process_findings, args.correlation_window\n )\n\n all_findings = correlated + all_process_findings\n all_findings.sort(key=lambda x: x.get(\"severity\", \"\"), reverse=True)\n\n dcom_audit = audit_dcom_config() if args.audit_dcom else []\n\n generate_report(all_findings, dcom_audit, args.output)\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":14078,"content_sha256":"daa942659ddcc406f92e0538ce0ced064464537692ed2f38ad085015368e2fd2"},{"filename":"scripts/detect_dcom_lateral_movement.py","content":"#!/usr/bin/env python3\n\"\"\"\nDCOM Lateral Movement Detection Script\nParses Windows Security and Sysmon event logs to detect DCOM-based lateral movement\nvia MMC20.Application, ShellWindows, and ShellBrowserWindow COM object abuse.\n\nMITRE ATT&CK: T1021.003 (Remote Services: Distributed Component Object Model)\n\nUsage:\n python detect_dcom_lateral_movement.py --evtx \u003cpath_to_sysmon_evtx>\n python detect_dcom_lateral_movement.py --evtx \u003csysmon.evtx> --security \u003csecurity.evtx>\n python detect_dcom_lateral_movement.py --evtx \u003csysmon.evtx> --json --output results.json\n\nRequirements:\n pip install python-evtx lxml\n\"\"\"\n\nimport argparse\nimport json\nimport sys\nimport os\nfrom datetime import datetime, timedelta\nfrom collections import defaultdict\n\ntry:\n import Evtx.Evtx as evtx\n import Evtx.Views as evtx_views\n from lxml import etree\nexcept ImportError:\n print(\"[!] Required packages not found. Install with: pip install python-evtx lxml\")\n sys.exit(1)\n\n\n# DCOM-related COM object CLSIDs\nDCOM_CLSIDS = {\n \"{49B2791A-B1AE-4C90-9B8E-E860BA07F889}\": \"MMC20.Application\",\n \"{9BA05972-F6A8-11CF-A442-00A0C90A8F39}\": \"ShellWindows\",\n \"{C08AFD90-F2A1-11D1-8455-00A0C91F3880}\": \"ShellBrowserWindow\",\n \"{00024500-0000-0000-C000-000000000046}\": \"Excel.Application\",\n \"{0006F03A-0000-0000-C000-000000000046}\": \"Outlook.Application\",\n}\n\n# Suspicious child processes when spawned by DCOM parent processes\nSUSPICIOUS_CHILDREN = [\n \"cmd.exe\", \"powershell.exe\", \"pwsh.exe\", \"wscript.exe\",\n \"cscript.exe\", \"mshta.exe\", \"rundll32.exe\", \"regsvr32.exe\",\n \"certutil.exe\", \"bitsadmin.exe\", \"msbuild.exe\",\n]\n\n# DCOM parent processes that spawn child processes during lateral movement\nDCOM_PARENTS = [\"mmc.exe\", \"dllhost.exe\", \"explorer.exe\", \"svchost.exe\"]\n\nSYSMON_NS = \"http://schemas.microsoft.com/win/2004/08/events/event\"\n\n\ndef parse_sysmon_event(record_xml):\n \"\"\"Parse a Sysmon event record XML into a dictionary.\"\"\"\n try:\n root = etree.fromstring(record_xml)\n except etree.XMLSyntaxError:\n return None\n\n ns = {\"e\": SYSMON_NS}\n event = {}\n\n system = root.find(\".//e:System\", ns)\n if system is not None:\n event_id_elem = system.find(\"e:EventID\", ns)\n event[\"EventID\"] = int(event_id_elem.text) if event_id_elem is not None else 0\n time_elem = system.find(\"e:TimeCreated\", ns)\n if time_elem is not None:\n event[\"TimeCreated\"] = time_elem.get(\"SystemTime\", \"\")\n computer_elem = system.find(\"e:Computer\", ns)\n event[\"Computer\"] = computer_elem.text if computer_elem is not None else \"\"\n\n event_data = root.find(\".//e:EventData\", ns)\n if event_data is not None:\n for data in event_data.findall(\"e:Data\", ns):\n name = data.get(\"Name\", \"\")\n value = data.text or \"\"\n event[name] = value\n\n return event\n\n\ndef is_dcom_parent(image_path):\n \"\"\"Check if the process image is a known DCOM parent.\"\"\"\n if not image_path:\n return False\n image_lower = image_path.lower()\n return any(parent in image_lower for parent in DCOM_PARENTS)\n\n\ndef is_suspicious_child(image_path):\n \"\"\"Check if the process image is a suspicious child for DCOM context.\"\"\"\n if not image_path:\n return False\n image_lower = image_path.lower()\n return any(child in image_lower for child in SUSPICIOUS_CHILDREN)\n\n\ndef check_dcomllaunch_parent(command_line):\n \"\"\"Check if the parent command line indicates DcomLaunch service.\"\"\"\n if not command_line:\n return False\n return \"dcomlaunch\" in command_line.lower()\n\n\ndef detect_dcom_process_creation(events):\n \"\"\"\n Detect DCOM lateral movement via Sysmon Event ID 1 (Process Create).\n Looks for DCOM parent processes spawning suspicious children.\n \"\"\"\n findings = []\n\n for event in events:\n if event.get(\"EventID\") != 1:\n continue\n\n parent_image = event.get(\"ParentImage\", \"\")\n image = event.get(\"Image\", \"\")\n parent_cmdline = event.get(\"ParentCommandLine\", \"\")\n cmdline = event.get(\"CommandLine\", \"\")\n user = event.get(\"User\", \"\")\n time_created = event.get(\"TimeCreated\", \"\")\n computer = event.get(\"Computer\", \"\")\n\n # Pattern 1: mmc.exe spawning suspicious child (MMC20.Application)\n if \"mmc.exe\" in parent_image.lower() and is_suspicious_child(image):\n findings.append({\n \"timestamp\": time_created,\n \"computer\": computer,\n \"detection_type\": \"MMC20.Application DCOM Lateral Movement\",\n \"dcom_object\": \"MMC20.Application\",\n \"clsid\": \"{49B2791A-B1AE-4C90-9B8E-E860BA07F889}\",\n \"parent_image\": parent_image,\n \"parent_commandline\": parent_cmdline,\n \"child_image\": image,\n \"child_commandline\": cmdline,\n \"user\": user,\n \"severity\": \"HIGH\",\n \"mitre\": \"T1021.003\",\n })\n\n # Pattern 2: DcomLaunch svchost spawning dllhost or mmc\n if check_dcomllaunch_parent(parent_cmdline) and is_suspicious_child(image):\n findings.append({\n \"timestamp\": time_created,\n \"computer\": computer,\n \"detection_type\": \"DcomLaunch Service Spawning Suspicious Process\",\n \"dcom_object\": \"Unknown (DcomLaunch)\",\n \"clsid\": \"N/A\",\n \"parent_image\": parent_image,\n \"parent_commandline\": parent_cmdline,\n \"child_image\": image,\n \"child_commandline\": cmdline,\n \"user\": user,\n \"severity\": \"HIGH\",\n \"mitre\": \"T1021.003\",\n })\n\n # Pattern 3: explorer.exe spawning cmd/powershell on servers\n # (ShellWindows/ShellBrowserWindow)\n if \"explorer.exe\" in parent_image.lower() and is_suspicious_child(image):\n # Check if this might be interactive (less suspicious) or DCOM (more suspicious)\n findings.append({\n \"timestamp\": time_created,\n \"computer\": computer,\n \"detection_type\": \"ShellWindows/ShellBrowserWindow DCOM Lateral Movement (Requires Correlation)\",\n \"dcom_object\": \"ShellWindows or ShellBrowserWindow\",\n \"clsid\": \"{9BA05972-F6A8-11CF-A442-00A0C90A8F39} or {C08AFD90-F2A1-11D1-8455-00A0C91F3880}\",\n \"parent_image\": parent_image,\n \"parent_commandline\": parent_cmdline,\n \"child_image\": image,\n \"child_commandline\": cmdline,\n \"user\": user,\n \"severity\": \"MEDIUM\",\n \"mitre\": \"T1021.003\",\n })\n\n # Pattern 4: dllhost.exe spawning suspicious children\n if \"dllhost.exe\" in parent_image.lower() and is_suspicious_child(image):\n # Extract CLSID from dllhost command line if present\n detected_clsid = \"Unknown\"\n if \"/Processid:\" in parent_cmdline:\n clsid_start = parent_cmdline.find(\"/Processid:\") + len(\"/Processid:\")\n detected_clsid = parent_cmdline[clsid_start:].strip().strip(\"{}\")\n detected_clsid = \"{\" + detected_clsid + \"}\"\n\n dcom_name = DCOM_CLSIDS.get(detected_clsid.upper(), \"Unknown DCOM Object\")\n\n findings.append({\n \"timestamp\": time_created,\n \"computer\": computer,\n \"detection_type\": \"DCOM Object Execution via dllhost.exe\",\n \"dcom_object\": dcom_name,\n \"clsid\": detected_clsid,\n \"parent_image\": parent_image,\n \"parent_commandline\": parent_cmdline,\n \"child_image\": image,\n \"child_commandline\": cmdline,\n \"user\": user,\n \"severity\": \"HIGH\",\n \"mitre\": \"T1021.003\",\n })\n\n return findings\n\n\ndef detect_dcom_network_connections(events):\n \"\"\"\n Detect DCOM-related network connections via Sysmon Event ID 3.\n Looks for inbound RPC connections (port 135) to DCOM processes.\n \"\"\"\n findings = []\n\n for event in events:\n if event.get(\"EventID\") != 3:\n continue\n\n image = event.get(\"Image\", \"\")\n dest_port = event.get(\"DestinationPort\", \"\")\n source_ip = event.get(\"SourceIp\", \"\")\n dest_ip = event.get(\"DestinationIp\", \"\")\n initiated = event.get(\"Initiated\", \"\")\n time_created = event.get(\"TimeCreated\", \"\")\n computer = event.get(\"Computer\", \"\")\n\n # Inbound RPC connection (port 135) -- DCOM always starts here\n if dest_port == \"135\" and initiated.lower() == \"false\":\n findings.append({\n \"timestamp\": time_created,\n \"computer\": computer,\n \"detection_type\": \"Inbound RPC Endpoint Mapper Connection\",\n \"source_ip\": source_ip,\n \"destination_ip\": dest_ip,\n \"destination_port\": dest_port,\n \"process_image\": image,\n \"severity\": \"MEDIUM\",\n \"mitre\": \"T1021.003\",\n \"note\": \"DCOM communication begins with RPC endpoint mapper query on port 135\",\n })\n\n # DCOM process making outbound connection on high port (dynamic RPC)\n if is_dcom_parent(image) and dest_port and int(dest_port) > 49151:\n findings.append({\n \"timestamp\": time_created,\n \"computer\": computer,\n \"detection_type\": \"DCOM Process Dynamic RPC Connection\",\n \"source_ip\": source_ip,\n \"destination_ip\": dest_ip,\n \"destination_port\": dest_port,\n \"process_image\": image,\n \"severity\": \"LOW\",\n \"mitre\": \"T1021.003\",\n \"note\": \"DCOM process communicating on dynamic RPC port range\",\n })\n\n return findings\n\n\ndef correlate_network_and_process(process_findings, network_findings, window_seconds=60):\n \"\"\"\n Correlate network connections with process creation events.\n A network connection to port 135 followed by DCOM process creation\n within the time window is a strong indicator of lateral movement.\n \"\"\"\n correlated = []\n\n for proc in process_findings:\n proc_time = proc.get(\"timestamp\", \"\")\n proc_computer = proc.get(\"computer\", \"\")\n\n if not proc_time:\n continue\n\n try:\n proc_dt = datetime.fromisoformat(proc_time.replace(\"Z\", \"+00:00\"))\n except (ValueError, TypeError):\n continue\n\n for net in network_findings:\n net_time = net.get(\"timestamp\", \"\")\n net_computer = net.get(\"computer\", \"\")\n\n if not net_time or net_computer != proc_computer:\n continue\n\n try:\n net_dt = datetime.fromisoformat(net_time.replace(\"Z\", \"+00:00\"))\n except (ValueError, TypeError):\n continue\n\n time_diff = abs((proc_dt - net_dt).total_seconds())\n\n if time_diff \u003c= window_seconds and net_dt \u003c= proc_dt:\n correlated.append({\n \"correlation_type\": \"DCOM Lateral Movement Chain\",\n \"severity\": \"CRITICAL\",\n \"mitre\": \"T1021.003\",\n \"computer\": proc_computer,\n \"network_event\": {\n \"timestamp\": net_time,\n \"source_ip\": net.get(\"source_ip\"),\n \"destination_port\": net.get(\"destination_port\"),\n },\n \"process_event\": {\n \"timestamp\": proc_time,\n \"dcom_object\": proc.get(\"dcom_object\"),\n \"parent_image\": proc.get(\"parent_image\"),\n \"child_image\": proc.get(\"child_image\"),\n \"child_commandline\": proc.get(\"child_commandline\"),\n \"user\": proc.get(\"user\"),\n },\n \"time_delta_seconds\": round(time_diff, 2),\n })\n\n return correlated\n\n\ndef parse_evtx_file(filepath):\n \"\"\"Parse a .evtx file and return list of parsed events.\"\"\"\n events = []\n try:\n with evtx.Evtx(filepath) as log:\n for record in log.records():\n try:\n event = parse_sysmon_event(record.xml())\n if event:\n events.append(event)\n except Exception:\n continue\n except Exception as e:\n print(f\"[!] Error parsing {filepath}: {e}\")\n return events\n\n\ndef print_findings(findings, title):\n \"\"\"Print findings in a formatted table.\"\"\"\n if not findings:\n print(f\"\\n[+] {title}: No findings\")\n return\n\n print(f\"\\n{'=' * 80}\")\n print(f\" {title} ({len(findings)} findings)\")\n print(f\"{'=' * 80}\")\n\n for i, finding in enumerate(findings, 1):\n print(f\"\\n [{i}] {finding.get('detection_type', 'Unknown')}\")\n print(f\" Severity: {finding.get('severity', 'N/A')}\")\n print(f\" MITRE: {finding.get('mitre', 'N/A')}\")\n print(f\" Time: {finding.get('timestamp', 'N/A')}\")\n print(f\" Computer: {finding.get('computer', 'N/A')}\")\n\n if \"dcom_object\" in finding:\n print(f\" DCOM Object: {finding['dcom_object']}\")\n print(f\" CLSID: {finding.get('clsid', 'N/A')}\")\n if \"parent_image\" in finding:\n print(f\" Parent: {finding['parent_image']}\")\n print(f\" Child: {finding.get('child_image', 'N/A')}\")\n print(f\" Command: {finding.get('child_commandline', 'N/A')[:120]}\")\n if \"source_ip\" in finding:\n print(f\" Source IP: {finding['source_ip']}\")\n print(f\" Dest Port: {finding.get('destination_port', 'N/A')}\")\n if \"note\" in finding:\n print(f\" Note: {finding['note']}\")\n\n\ndef print_correlated(correlated):\n \"\"\"Print correlated findings.\"\"\"\n if not correlated:\n print(\"\\n[+] Correlated DCOM Chains: No findings\")\n return\n\n print(f\"\\n{'=' * 80}\")\n print(f\" CORRELATED DCOM LATERAL MOVEMENT CHAINS ({len(correlated)} findings)\")\n print(f\"{'=' * 80}\")\n\n for i, c in enumerate(correlated, 1):\n net = c[\"network_event\"]\n proc = c[\"process_event\"]\n print(f\"\\n [{i}] {c['correlation_type']}\")\n print(f\" Severity: {c['severity']}\")\n print(f\" Target: {c['computer']}\")\n print(f\" Source IP: {net['source_ip']} -> port {net['destination_port']}\")\n print(f\" Time Delta: {c['time_delta_seconds']}s\")\n print(f\" DCOM Object: {proc['dcom_object']}\")\n print(f\" Process Chain: {proc['parent_image']} -> {proc['child_image']}\")\n print(f\" Command: {proc.get('child_commandline', 'N/A')[:120]}\")\n print(f\" User: {proc.get('user', 'N/A')}\")\n\n\ndef main():\n parser = argparse.ArgumentParser(\n description=\"Detect DCOM lateral movement from Sysmon and Security event logs\"\n )\n parser.add_argument(\n \"--evtx\", required=True,\n help=\"Path to Sysmon .evtx log file\"\n )\n parser.add_argument(\n \"--security\",\n help=\"Path to Windows Security .evtx log file (optional, for 4624 correlation)\"\n )\n parser.add_argument(\n \"--json\", action=\"store_true\",\n help=\"Output results in JSON format\"\n )\n parser.add_argument(\n \"--output\", \"-o\",\n help=\"Output file path (default: stdout)\"\n )\n parser.add_argument(\n \"--correlation-window\", type=int, default=60,\n help=\"Time window in seconds for correlating network and process events (default: 60)\"\n )\n args = parser.parse_args()\n\n if not os.path.exists(args.evtx):\n print(f\"[!] File not found: {args.evtx}\")\n sys.exit(1)\n\n print(f\"[*] Parsing Sysmon events from: {args.evtx}\")\n events = parse_evtx_file(args.evtx)\n print(f\"[*] Parsed {len(events)} Sysmon events\")\n\n security_events = []\n if args.security:\n if os.path.exists(args.security):\n print(f\"[*] Parsing Security events from: {args.security}\")\n security_events = parse_evtx_file(args.security)\n print(f\"[*] Parsed {len(security_events)} Security events\")\n else:\n print(f\"[!] Security log not found: {args.security}\")\n\n print(\"[*] Analyzing for DCOM lateral movement indicators...\")\n\n process_findings = detect_dcom_process_creation(events)\n network_findings = detect_dcom_network_connections(events)\n correlated = correlate_network_and_process(\n process_findings, network_findings, args.correlation_window\n )\n\n all_results = {\n \"scan_time\": datetime.utcnow().isoformat() + \"Z\",\n \"sysmon_log\": args.evtx,\n \"security_log\": args.security or \"Not provided\",\n \"total_events_parsed\": len(events) + len(security_events),\n \"process_creation_findings\": process_findings,\n \"network_connection_findings\": network_findings,\n \"correlated_chains\": correlated,\n \"summary\": {\n \"process_detections\": len(process_findings),\n \"network_detections\": len(network_findings),\n \"correlated_chains\": len(correlated),\n \"critical_findings\": len([c for c in correlated]),\n \"high_findings\": len([f for f in process_findings if f.get(\"severity\") == \"HIGH\"]),\n },\n }\n\n if args.json:\n output = json.dumps(all_results, indent=2, default=str)\n if args.output:\n with open(args.output, \"w\") as f:\n f.write(output)\n print(f\"[*] JSON results written to: {args.output}\")\n else:\n print(output)\n else:\n print(f\"\\n[*] DCOM Lateral Movement Detection Report\")\n print(f\"[*] Scan Time: {all_results['scan_time']}\")\n print(f\"[*] Events Analyzed: {all_results['total_events_parsed']}\")\n\n print_findings(process_findings, \"DCOM Process Creation Detections\")\n print_findings(network_findings, \"DCOM Network Connection Detections\")\n print_correlated(correlated)\n\n print(f\"\\n{'=' * 80}\")\n print(f\" SUMMARY\")\n print(f\"{'=' * 80}\")\n s = all_results[\"summary\"]\n print(f\" Process Creation Detections: {s['process_detections']}\")\n print(f\" Network Connection Detections: {s['network_detections']}\")\n print(f\" Correlated Lateral Movement Chains: {s['correlated_chains']}\")\n print(f\" Critical Findings: {s['critical_findings']}\")\n print(f\" High Findings: {s['high_findings']}\")\n\n if args.output:\n with open(args.output, \"w\") as f:\n json.dump(all_results, f, indent=2, default=str)\n print(f\"\\n[*] Full results written to: {args.output}\")\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":18920,"content_sha256":"952b84997d634689e61329fecd50326478bdf61991f096c539f3320d256b8987"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Hunting for DCOM Lateral Movement","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Authorized Testing Disclaimer","type":"text","marks":[{"type":"strong"}]},{"text":": The offensive techniques and attack simulations described in this skill are intended exclusively for authorized penetration testing, red team engagements, purple team exercises, and security research conducted with explicit written permission from the system owner. Unauthorized use of these techniques against systems you do not own or have permission to test is illegal and unethical. Always operate within the scope of your engagement and comply with applicable laws and regulations.","type":"text"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"Distributed Component Object Model (DCOM) enables remote execution of COM objects across a network using RPC. Adversaries abuse specific DCOM objects -- MMC20.Application (CLSID {49B2791A-B1AE-4C90-9B8E-E860BA07F889}), ShellBrowserWindow (CLSID {C08AFD90-F2A1-11D1-8455-00A0C91F3880}), and ShellWindows (CLSID {9BA05972-F6A8-11CF-A442-00A0C90A8F39}) -- to execute commands on remote hosts without dropping files, making this a stealthy lateral movement technique mapped to MITRE ATT&CK T1021.003. This skill provides detection strategies using Sysmon telemetry, Windows Security Event correlation, network monitoring, and SIEM detection rules to identify DCOM abuse in enterprise environments.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Proactively hunting for lateral movement in Active Directory environments where DCOM is enabled","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Investigating alerts for suspicious mmc.exe, dllhost.exe, or explorer.exe child process creation on servers","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Building detection rules for MITRE ATT&CK T1021.003 (Remote Services: Distributed Component Object Model)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Correlating Sysmon Event ID 1 (Process Create) and Event ID 3 (Network Connection) to trace DCOM-based command execution chains","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Auditing DCOM exposure across the domain to reduce lateral movement attack surface","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"During purple team exercises validating detection coverage for DCOM-based techniques","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Do not use","type":"text","marks":[{"type":"strong"}]},{"text":" as a replacement for EDR-based lateral movement detection, without Sysmon or equivalent process telemetry deployed on endpoints, or in isolation without correlating network-level and host-level indicators.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Prerequisites","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Sysmon deployed on endpoints with configuration capturing Event ID 1 (Process Create), Event ID 3 (Network Connection), Event ID 7 (Image Loaded), and Event ID 10 (Process Access)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Windows Security Event Logs forwarded to SIEM (Event IDs 4624, 4672, 4688)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SIEM platform (Splunk, Elastic, Microsoft Sentinel) with correlation capability","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Network monitoring for RPC traffic (TCP 135 and dynamic high ports 49152-65535)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Baseline inventory of legitimate DCOM usage in the environment","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Understanding of MITRE ATT&CK Lateral Movement tactic (TA0008) and T1021.003","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Understand DCOM Lateral Movement Attack Vectors","type":"text"}]},{"type":"paragraph","content":[{"text":"DCOM lateral movement exploits three primary COM objects. Each has distinct forensic artifacts.","type":"text"}]},{"type":"paragraph","content":[{"text":"MMC20.Application","type":"text","marks":[{"type":"strong"}]},{"text":" -- The attacker instantiates the MMC snap-in remotely and calls ","type":"text"},{"text":"ExecuteShellCommand","type":"text","marks":[{"type":"code_inline"}]},{"text":" to run arbitrary commands on the target. This spawns mmc.exe as a child of svchost.exe (DcomLaunch service) on the target.","type":"text"}]},{"type":"paragraph","content":[{"text":"ShellBrowserWindow","type":"text","marks":[{"type":"strong"}]},{"text":" -- Uses the ","type":"text"},{"text":"Document.Application.ShellExecute","type":"text","marks":[{"type":"code_inline"}]},{"text":" method to execute commands through an existing explorer.exe process. Unlike MMC20, this does not create a new process for the COM server itself, making it stealthier.","type":"text"}]},{"type":"paragraph","content":[{"text":"ShellWindows","type":"text","marks":[{"type":"strong"}]},{"text":" -- Similar to ShellBrowserWindow, it activates within an existing explorer.exe instance and executes child processes from explorer.exe. The absence of a new COM server process makes it harder to detect without proper telemetry.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"powershell"},"content":[{"text":"# ATTACK SIMULATION (authorized testing only)\n# These commands demonstrate what adversaries execute -- use only in lab environments\n\n# MMC20.Application lateral movement\n# $dcom = [System.Activator]::CreateInstance(\n# [Type]::GetTypeFromProgID(\"MMC20.Application\", \"TARGET_IP\"))\n# $dcom.Document.ActiveView.ExecuteShellCommand(\n# \"cmd.exe\", $null, \"/c whoami > C:\\temp\\output.txt\", \"7\")\n\n# ShellWindows lateral movement\n# $dcom = [System.Activator]::CreateInstance(\n# [Type]::GetTypeFromCLSID(\n# [guid]\"9BA05972-F6A8-11CF-A442-00A0C90A8F39\", \"TARGET_IP\"))\n# $dcom.item().Document.Application.ShellExecute(\n# \"cmd.exe\", \"/c calc.exe\", \"C:\\windows\\system32\", $null, 0)\n\n# ShellBrowserWindow lateral movement\n# $dcom = [System.Activator]::CreateInstance(\n# [Type]::GetTypeFromCLSID(\n# [guid]\"C08AFD90-F2A1-11D1-8455-00A0C91F3880\", \"TARGET_IP\"))\n# $dcom.Document.Application.ShellExecute(\n# \"cmd.exe\", \"/c net user\", \"C:\\windows\\system32\", $null, 0)","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Configure Sysmon for DCOM Detection","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"xml"},"content":[{"text":"\u003c!-- Sysmon configuration excerpt for DCOM lateral movement detection -->\n\u003c!-- Add these rules to your existing Sysmon config -->\n\n\u003cSysmon schemaversion=\"4.90\">\n \u003cEventFiltering>\n\n \u003c!-- Event ID 1: Process Creation - Detect DCOM-spawned processes -->\n \u003cRuleGroup name=\"DCOM_ProcessCreate\" groupRelation=\"or\">\n \u003cProcessCreate onmatch=\"include\">\n \u003c!-- MMC20.Application: mmc.exe spawning child processes -->\n \u003cParentImage condition=\"end with\">mmc.exe\u003c/ParentImage>\n \u003c!-- DcomLaunch service spawning COM servers -->\n \u003cParentCommandLine condition=\"contains\">DcomLaunch\u003c/ParentCommandLine>\n \u003c!-- dllhost.exe spawning suspicious children -->\n \u003cParentImage condition=\"end with\">dllhost.exe\u003c/ParentImage>\n \u003c!-- explorer.exe spawning cmd/powershell (ShellWindows/ShellBrowserWindow) -->\n \u003cRule groupRelation=\"and\">\n \u003cParentImage condition=\"end with\">explorer.exe\u003c/ParentImage>\n \u003cImage condition=\"end with\">cmd.exe\u003c/Image>\n \u003c/Rule>\n \u003cRule groupRelation=\"and\">\n \u003cParentImage condition=\"end with\">explorer.exe\u003c/ParentImage>\n \u003cImage condition=\"end with\">powershell.exe\u003c/Image>\n \u003c/Rule>\n \u003c/ProcessCreate>\n \u003c/RuleGroup>\n\n \u003c!-- Event ID 3: Network Connection - Track DCOM RPC connections -->\n \u003cRuleGroup name=\"DCOM_NetworkConnect\" groupRelation=\"or\">\n \u003cNetworkConnect onmatch=\"include\">\n \u003c!-- RPC Endpoint Mapper -->\n \u003cDestinationPort condition=\"is\">135\u003c/DestinationPort>\n \u003c!-- DCOM processes making network connections -->\n \u003cImage condition=\"end with\">mmc.exe\u003c/Image>\n \u003cImage condition=\"end with\">dllhost.exe\u003c/Image>\n \u003c!-- svchost.exe DcomLaunch connections -->\n \u003cRule groupRelation=\"and\">\n \u003cImage condition=\"end with\">svchost.exe\u003c/Image>\n \u003cDestinationPort condition=\"more than\">49151\u003c/DestinationPort>\n \u003c/Rule>\n \u003c/NetworkConnect>\n \u003c/RuleGroup>\n\n \u003c!-- Event ID 7: Image Loaded - DCOM-related DLLs -->\n \u003cRuleGroup name=\"DCOM_ImageLoaded\" groupRelation=\"or\">\n \u003cImageLoad onmatch=\"include\">\n \u003cImageLoaded condition=\"end with\">comsvcs.dll\u003c/ImageLoaded>\n \u003cImageLoaded condition=\"end with\">ole32.dll\u003c/ImageLoaded>\n \u003cImageLoaded condition=\"end with\">rpcrt4.dll\u003c/ImageLoaded>\n \u003c/ImageLoad>\n \u003c/RuleGroup>\n\n \u003c/EventFiltering>\n\u003c/Sysmon>","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Deploy or update Sysmon configuration\n# sysmon64.exe -c dcom-detection-sysmon.xml\n\n# Verify Sysmon is capturing DCOM events\n# PowerShell: Get-WinEvent -LogName \"Microsoft-Windows-Sysmon/Operational\" -MaxEvents 10 |\n# Where-Object { $_.Id -in @(1,3) } | Format-Table TimeCreated, Id, Message -Wrap","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: Build SIEM Detection Rules for DCOM Object Abuse","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"# Sigma Rule: MMC20.Application DCOM Lateral Movement\ntitle: DCOM Lateral Movement via MMC20.Application\nid: 8a3b5f2e-c1d4-4a9f-b237-1e6f8d2c3a4b\nstatus: stable\ndescription: >\n Detects remote instantiation of MMC20.Application DCOM object by monitoring\n for mmc.exe spawned by svchost.exe DcomLaunch service with subsequent child\n process creation, indicating T1021.003 lateral movement.\nreferences:\n - https://attack.mitre.org/techniques/T1021/003/\n - https://www.cybereason.com/blog/dcom-lateral-movement-techniques\n - https://www.mdsec.co.uk/2020/09/i-like-to-move-it-windows-lateral-movement-part-2-dcom/\nlogsource:\n category: process_creation\n product: windows\ndetection:\n selection_parent:\n ParentImage|endswith: '\\mmc.exe'\n selection_child:\n Image|endswith:\n - '\\cmd.exe'\n - '\\powershell.exe'\n - '\\pwsh.exe'\n - '\\wscript.exe'\n - '\\cscript.exe'\n - '\\mshta.exe'\n - '\\rundll32.exe'\n - '\\regsvr32.exe'\n filter_legitimate:\n ParentCommandLine|contains:\n - 'devmgmt.msc'\n - 'diskmgmt.msc'\n - 'services.msc'\n - 'compmgmt.msc'\n condition: selection_parent and selection_child and not filter_legitimate\nlevel: high\ntags:\n - attack.lateral_movement\n - attack.t1021.003\nfalsepositives:\n - Legitimate remote MMC administration by authorized IT staff\n - SCCM or other management tools using DCOM for remote management","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"# Sigma Rule: ShellWindows/ShellBrowserWindow DCOM Lateral Movement\ntitle: DCOM Lateral Movement via ShellWindows or ShellBrowserWindow\nid: 2f7c9d1e-a8b3-4c5f-9012-3e4d5f6a7b8c\nstatus: stable\ndescription: >\n Detects DCOM lateral movement using ShellWindows (CLSID 9BA05972) or\n ShellBrowserWindow (CLSID C08AFD90) by monitoring for explorer.exe spawning\n cmd.exe or powershell.exe on systems where no user is interactively logged on,\n or where the network logon (Type 3) precedes the process creation.\nreferences:\n - https://attack.mitre.org/techniques/T1021/003/\n - https://www.elastic.co/guide/en/security/8.19/incoming-dcom-lateral-movement-with-shellbrowserwindow-or-shellwindows.html\nlogsource:\n category: process_creation\n product: windows\ndetection:\n selection:\n ParentImage|endswith: '\\explorer.exe'\n Image|endswith:\n - '\\cmd.exe'\n - '\\powershell.exe'\n - '\\pwsh.exe'\n - '\\mshta.exe'\n - '\\wscript.exe'\n - '\\cscript.exe'\n filter_interactive:\n LogonId: '0x3e7'\n condition: selection and not filter_interactive\nlevel: medium\ntags:\n - attack.lateral_movement\n - attack.t1021.003\nfalsepositives:\n - Users launching command prompts from Explorer context menus\n - Software installers launching child processes from explorer.exe","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"# Sigma Rule: Sysmon Network Connection to RPC Endpoint Mapper from DCOM Process\ntitle: DCOM Process Inbound RPC Connection Followed by Process Creation\nid: 4d9e2f1a-b3c5-4a7f-8901-2c3d4e5f6a7b\nstatus: experimental\ndescription: >\n Correlates Sysmon Event ID 3 (Network Connection) on port 135 with\n subsequent Event ID 1 (Process Create) from DCOM parent processes\n (mmc.exe, dllhost.exe, explorer.exe) within a short time window.\nlogsource:\n product: windows\n service: sysmon\ndetection:\n network_connection:\n EventID: 3\n DestinationPort: 135\n Initiated: 'false'\n process_creation:\n EventID: 1\n ParentImage|endswith:\n - '\\mmc.exe'\n - '\\dllhost.exe'\n - '\\svchost.exe'\n timeframe: 30s\n condition: network_connection | near process_creation\nlevel: high\ntags:\n - attack.lateral_movement\n - attack.t1021.003","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Deploy Splunk and KQL Detection Queries","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"spl"},"content":[{"text":"# Splunk: Detect MMC20.Application DCOM Lateral Movement\n# Correlates network logon (4624 Type 3) with mmc.exe process creation\n\nindex=wineventlog sourcetype=\"XmlWinEventLog:Microsoft-Windows-Sysmon/Operational\"\nEventCode=1 ParentImage=\"*\\\\mmc.exe\"\n(Image=\"*\\\\cmd.exe\" OR Image=\"*\\\\powershell.exe\" OR Image=\"*\\\\pwsh.exe\"\n OR Image=\"*\\\\wscript.exe\" OR Image=\"*\\\\cscript.exe\" OR Image=\"*\\\\mshta.exe\")\n| eval target_host=ComputerName\n| join target_host type=inner\n [search index=wineventlog EventCode=4624 LogonType=3\n | where AuthenticationPackageName=\"NTLM\" OR AuthenticationPackageName=\"Kerberos\"\n | eval target_host=ComputerName\n | rename IpAddress as source_ip, TargetUserName as logon_user\n | fields target_host source_ip logon_user _time]\n| where abs(_time - relative_time(now(), \"-5m\")) \u003c 300\n| table _time target_host Image ParentImage CommandLine source_ip logon_user\n| sort -_time","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"spl"},"content":[{"text":"# Splunk: Detect ShellWindows/ShellBrowserWindow DCOM Lateral Movement\n# Identifies explorer.exe spawning suspicious child processes on servers\n\nindex=wineventlog sourcetype=\"XmlWinEventLog:Microsoft-Windows-Sysmon/Operational\"\nEventCode=1 ParentImage=\"*\\\\explorer.exe\"\n(Image=\"*\\\\cmd.exe\" OR Image=\"*\\\\powershell.exe\" OR Image=\"*\\\\pwsh.exe\")\n| eval target_host=ComputerName\n| join target_host type=inner\n [search index=wineventlog sourcetype=\"XmlWinEventLog:Microsoft-Windows-Sysmon/Operational\"\n EventCode=3 DestinationPort=135 Initiated=\"false\"\n | eval target_host=ComputerName\n | rename SourceIp as dcom_source_ip\n | fields target_host dcom_source_ip _time]\n| where abs(_time - relative_time(now(), \"-2m\")) \u003c 120\n| stats count values(Image) as child_processes values(CommandLine) as commands\n by target_host dcom_source_ip\n| where count > 0\n| table target_host dcom_source_ip child_processes commands count","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"spl"},"content":[{"text":"# Splunk: DCOM RPC Endpoint Mapper Connection Anomaly\n# Identifies hosts receiving unusual volumes of inbound RPC connections\n\nindex=wineventlog sourcetype=\"XmlWinEventLog:Microsoft-Windows-Sysmon/Operational\"\nEventCode=3 DestinationPort=135 Initiated=\"false\"\n| stats dc(SourceIp) as unique_sources count by ComputerName\n| where unique_sources > 3 OR count > 10\n| sort -unique_sources\n| table ComputerName unique_sources count","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"kql"},"content":[{"text":"-- Microsoft Sentinel KQL: DCOM Lateral Movement via MMC20.Application\n\nlet dcom_network = SysmonEvent\n| where EventID == 3\n| where DestinationPort == 135\n| where InitiatedConnection == false\n| project NetworkTime=TimeGenerated, TargetComputer=Computer,\n SourceIP=SourceIp, DestPort=DestinationPort;\n\nlet dcom_process = SysmonEvent\n| where EventID == 1\n| where ParentImage endswith \"\\\\mmc.exe\"\n or ParentImage endswith \"\\\\dllhost.exe\"\n| where Image endswith \"\\\\cmd.exe\"\n or Image endswith \"\\\\powershell.exe\"\n or Image endswith \"\\\\pwsh.exe\"\n or Image endswith \"\\\\wscript.exe\"\n or Image endswith \"\\\\mshta.exe\"\n| project ProcessTime=TimeGenerated, TargetComputer=Computer,\n ParentImage, Image, CommandLine, User;\n\ndcom_network\n| join kind=inner (dcom_process) on TargetComputer\n| where abs(datetime_diff('second', NetworkTime, ProcessTime)) \u003c 60\n| project NetworkTime, ProcessTime, TargetComputer, SourceIP,\n ParentImage, Image, CommandLine, User\n| sort by NetworkTime desc","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"kql"},"content":[{"text":"-- Microsoft Sentinel KQL: ShellWindows DCOM Lateral Movement\n\nSecurityEvent\n| where EventID == 4624 and LogonType == 3\n| where AuthenticationPackageName in (\"NTLM\", \"Kerberos\")\n| project LogonTime=TimeGenerated, TargetComputer=Computer,\n SourceIP=IpAddress, LogonUser=TargetUserName\n| join kind=inner (\n SysmonEvent\n | where EventID == 1\n | where ParentImage endswith \"\\\\explorer.exe\"\n | where Image endswith \"\\\\cmd.exe\"\n or Image endswith \"\\\\powershell.exe\"\n or Image endswith \"\\\\pwsh.exe\"\n | project ProcessTime=TimeGenerated, TargetComputer=Computer,\n Image, CommandLine, User\n) on TargetComputer\n| where ProcessTime between (LogonTime .. (LogonTime + 2m))\n| project LogonTime, ProcessTime, TargetComputer, SourceIP,\n LogonUser, Image, CommandLine\n| sort by LogonTime desc","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5: WMI Event Correlation for DCOM Activity","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"spl"},"content":[{"text":"# Splunk: Correlate WMI events with DCOM lateral movement\n# WMI-Activity operational log captures DCOM-triggered WMI calls\n\nindex=wineventlog source=\"WinEventLog:Microsoft-Windows-WMI-Activity/Operational\"\n| where EventCode IN (5857, 5858, 5859, 5860, 5861)\n| eval event_type=case(\n EventCode=5857, \"WMI Provider Loaded\",\n EventCode=5858, \"WMI Query Error\",\n EventCode=5859, \"WMI Provider Event\",\n EventCode=5860, \"WMI Temporary Event Registration\",\n EventCode=5861, \"WMI Permanent Event Registration\")\n| stats count values(event_type) as wmi_events by ComputerName\n| where count > 5\n| table ComputerName wmi_events count","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"powershell"},"content":[{"text":"# PowerShell: Query WMI operational log for DCOM-related activity\n# Run on target systems during investigation\n\nGet-WinEvent -LogName \"Microsoft-Windows-WMI-Activity/Operational\" -MaxEvents 500 |\n Where-Object {\n $_.Id -in @(5857, 5858, 5860, 5861) -and\n $_.Message -match \"DCOM|MMC20|ShellWindows|ShellBrowserWindow\"\n } |\n Select-Object TimeCreated, Id,\n @{N='Detail'; E={$_.Message.Substring(0, [Math]::Min(200, $_.Message.Length))}} |\n Format-Table -AutoSize\n\n# Query Sysmon for DCOM parent-child process chains\nGet-WinEvent -LogName \"Microsoft-Windows-Sysmon/Operational\" -FilterXPath @\"\n*[System[(EventID=1)]] and\n*[EventData[\n (Data[@Name='ParentImage'] and\n (contains(Data[@Name='ParentImage'],'mmc.exe') or\n contains(Data[@Name='ParentImage'],'dllhost.exe')))\n]]\n\"@ -MaxEvents 100 |\n Select-Object TimeCreated,\n @{N='ParentImage'; E={$_.Properties[20].Value}},\n @{N='Image'; E={$_.Properties[4].Value}},\n @{N='CommandLine'; E={$_.Properties[10].Value}},\n @{N='User'; E={$_.Properties[12].Value}} |\n Format-Table -AutoSize","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 6: Network-Level DCOM Detection with Zeek","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Zeek script for detecting DCOM lateral movement at the network level\n# Monitors RPC Endpoint Mapper (port 135) and subsequent high-port connections\n\ncat > /opt/zeek/share/zeek/site/custom-detections/dcom-lateral-movement.zeek \u003c\u003c 'ZEEKEOF'\n@load base/frameworks/notice\n@load base/frameworks/sumstats\n@load base/protocols/dce-rpc\n\nmodule DCOMLateralMovement;\n\nexport {\n redef enum Notice::Type += {\n DCOM_Lateral_Movement_Suspected,\n DCOM_RPC_Scan\n };\n\n # Threshold for unique targets receiving RPC connections from single source\n const rpc_target_threshold: count = 3 &redef;\n const rpc_time_window: interval = 10min &redef;\n}\n\nevent zeek_init()\n{\n local r1 = SumStats::Reducer(\n $stream=\"dcom.rpc_targets\",\n $apply=set(SumStats::UNIQUE)\n );\n\n SumStats::create([\n $name=\"detect-dcom-lateral\",\n $epoch=rpc_time_window,\n $reducers=set(r1),\n $threshold_val(key: SumStats::Key, result: SumStats::Result) = {\n return result[\"dcom.rpc_targets\"]$unique + 0.0;\n },\n $threshold=rpc_target_threshold + 0.0,\n $threshold_crossed(key: SumStats::Key, result: SumStats::Result) = {\n NOTICE([\n $note=DCOM_RPC_Scan,\n $msg=fmt(\"Host %s connected to %d hosts on RPC/135 in %s - possible DCOM lateral movement\",\n key$str, result[\"dcom.rpc_targets\"]$unique, rpc_time_window),\n $identifier=key$str\n ]);\n }\n ]);\n}\n\nevent connection_state_remove(c: connection)\n{\n if ( c$id$resp_p == 135/tcp && c$id$resp_h in Site::local_nets )\n {\n SumStats::observe(\"dcom.rpc_targets\",\n [$str=cat(c$id$orig_h)],\n [$str=cat(c$id$resp_h)]\n );\n }\n}\nZEEKEOF\n\n# Monitor DCE-RPC operations related to DCOM objects\ncat /opt/zeek/logs/current/dce_rpc.log | \\\n zeek-cut ts id.orig_h id.resp_h endpoint operation | \\\n grep -iE \"IDispatch|IRemoteActivation|IRemUnknown|IObjectExporter\" | \\\n sort -t

Hunting for DCOM Lateral Movement Authorized Testing Disclaimer : The offensive techniques and attack simulations described in this skill are intended exclusively for authorized penetration testing, red team engagements, purple team exercises, and security research conducted with explicit written permission from the system owner. Unauthorized use of these techniques against systems you do not own or have permission to test is illegal and unethical. Always operate within the scope of your engagement and comply with applicable laws and regulations. Overview Distributed Component Object Model (D…

\\t' -k2 | uniq -c | sort -rn\n\n# Track RPC endpoint mapper connections between internal hosts\ncat /opt/zeek/logs/current/conn.log | \\\n zeek-cut ts id.orig_h id.resp_h id.resp_p duration | \\\n awk '$4 == 135' | \\\n awk '{print $2, \"->\", $3}' | sort | uniq -c | sort -rn | head -20","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 7: DCOM Attack Surface Audit and Hardening","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"powershell"},"content":[{"text":"# Audit DCOM configuration across the domain\n# Enumerate remotely accessible DCOM objects\n\n# List DCOM applications registered on local system\nGet-CimInstance -ClassName Win32_DCOMApplication |\n Select-Object AppID, Name |\n Sort-Object Name |\n Format-Table -AutoSize\n\n# Check DCOM launch permissions for high-risk objects\n$clsids = @{\n \"MMC20.Application\" = \"{49B2791A-B1AE-4C90-9B8E-E860BA07F889}\"\n \"ShellWindows\" = \"{9BA05972-F6A8-11CF-A442-00A0C90A8F39}\"\n \"ShellBrowserWindow\" = \"{C08AFD90-F2A1-11D1-8455-00A0C91F3880}\"\n \"Excel.Application\" = \"{00024500-0000-0000-C000-000000000046}\"\n \"Outlook.Application\" = \"{0006F03A-0000-0000-C000-000000000046}\"\n}\n\nforeach ($name in $clsids.Keys) {\n $clsid = $clsids[$name]\n $regPath = \"HKLM:\\SOFTWARE\\Classes\\CLSID\\$clsid\"\n if (Test-Path $regPath) {\n $launchPermission = (Get-ItemProperty -Path \"$regPath\" -Name \"LaunchPermission\" -ErrorAction SilentlyContinue)\n Write-Host \"[*] $name ($clsid): $(if ($launchPermission) { 'Custom permissions set' } else { 'DEFAULT permissions (potentially exploitable)' })\"\n } else {\n Write-Host \"[-] $name ($clsid): Not found on this system\"\n }\n}\n\n# Check if DCOM is enabled (should be restricted on servers that don't need it)\n$dcomEnabled = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\Microsoft\\Ole\" -Name \"EnableDCOM\").EnableDCOM\nWrite-Host \"`n[*] DCOM Enabled: $dcomEnabled\"\n\n# Check remote launch and activation permissions\n$remoteLaunch = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\Microsoft\\Ole\" -Name \"DefaultLaunchPermission\" -ErrorAction SilentlyContinue)\nWrite-Host \"[*] Default Launch Permission: $(if ($remoteLaunch) { 'Custom' } else { 'System Default' })\"","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"powershell"},"content":[{"text":"# Hardening: Restrict DCOM remote access via Group Policy\n# These settings should be applied via GPO in production\n\n# Disable DCOM on systems that do not require it\n# Computer Configuration > Administrative Templates > System > Distributed COM >\n# Application Compatibility > Enable Distributed COM on this computer = Disabled\n\n# Restrict DCOM launch permissions via registry\n# Set-ItemProperty -Path \"HKLM:\\SOFTWARE\\Microsoft\\Ole\" -Name \"EnableDCOM\" -Value \"N\"\n\n# Block RPC/DCOM at the host firewall for non-admin traffic\n# New-NetFirewallRule -DisplayName \"Block Inbound DCOM/RPC\" `\n# -Direction Inbound -LocalPort 135 -Protocol TCP `\n# -Action Block -RemoteAddress \"Any\" `\n# -Group \"DCOM Hardening\"\n#\n# New-NetFirewallRule -DisplayName \"Allow DCOM from Admin Subnets\" `\n# -Direction Inbound -LocalPort 135 -Protocol TCP `\n# -Action Allow -RemoteAddress \"10.10.0.0/24\" `\n# -Group \"DCOM Hardening\"\n\n# Windows Firewall: Restrict dynamic RPC port range\n# netsh int ipv4 set dynamicport tcp start=49152 num=1024","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Key Concepts","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Term","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Definition","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"DCOM (T1021.003)","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Distributed Component Object Model -- extends COM to allow remote object instantiation and method invocation over RPC, abused for lateral movement","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MMC20.Application","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"COM object (CLSID {49B2791A-B1AE-4C90-9B8E-E860BA07F889}) controlling MMC snap-ins; ","type":"text"},{"text":"ExecuteShellCommand","type":"text","marks":[{"type":"code_inline"}]},{"text":" method enables remote command execution","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ShellWindows","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"COM object (CLSID {9BA05972-F6A8-11CF-A442-00A0C90A8F39}) that activates within an existing explorer.exe process, executing commands without creating a new COM server process","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ShellBrowserWindow","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"COM object (CLSID {C08AFD90-F2A1-11D1-8455-00A0C91F3880}) similar to ShellWindows, uses ","type":"text"},{"text":"Document.Application.ShellExecute","type":"text","marks":[{"type":"code_inline"}]},{"text":" for stealthy command execution","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"RPC Endpoint Mapper","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Service on TCP port 135 that maps RPC interfaces to dynamic ports; all DCOM communication begins with an endpoint mapper query","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sysmon Event ID 1","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Process Create event capturing parent-child process relationships, command lines, and user context -- critical for identifying DCOM-spawned processes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sysmon Event ID 3","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Network Connection event capturing source/destination IPs and ports -- used to correlate RPC connections with subsequent process creation","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"DcomLaunch","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Windows service (svchost.exe -k DcomLaunch) that manages DCOM server process activation; parent process of COM servers spawned via remote DCOM calls","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"WMI-Activity ETW","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Event Tracing for Windows provider that logs WMI method calls, instance creations, and queries -- provides visibility into DCOM-triggered WMI operations","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Tools & Systems","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tool","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Purpose","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sysmon","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Endpoint telemetry for process creation (EID 1), network connections (EID 3), and image loads (EID 7) essential for DCOM detection","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Splunk / Elastic SIEM","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Log aggregation and correlation platform for DCOM detection rules and threat hunting queries","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Microsoft Sentinel","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cloud SIEM with built-in KQL queries and analytics rules for DCOM lateral movement detection","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sigma","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Vendor-agnostic detection rule format for portable DCOM detection rules","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Zeek","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Network security monitor for DCE-RPC protocol analysis and RPC endpoint mapper traffic monitoring","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Atomic Red Team","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MITRE ATT&CK test framework with T1021.003 atomics for validating DCOM detection coverage","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Impacket (dcomexec.py)","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Python-based DCOM execution tool used by attackers and red teamers for testing DCOM lateral movement","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CIMSession / PowerShell","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Native Windows tooling for DCOM object instantiation used in both legitimate administration and attacks","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Scenarios","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Scenario 1: MMC20.Application Lateral Movement to File Server","type":"text"}]},{"type":"paragraph","content":[{"text":"Context","type":"text","marks":[{"type":"strong"}]},{"text":": A SOC analyst receives an alert for mmc.exe spawning cmd.exe on a file server (10.10.20.50) at 03:22 UTC. No administrator activity is scheduled at this time.","type":"text"}]},{"type":"paragraph","content":[{"text":"Approach","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Query Sysmon Event ID 1 on 10.10.20.50: confirm mmc.exe (parent: svchost.exe -k DcomLaunch) spawned cmd.exe with command line ","type":"text"},{"text":"/c net user /domain > C:\\temp\\users.txt","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Query Sysmon Event ID 3 on 10.10.20.50: identify inbound TCP connection on port 135 from 10.10.5.30 at 03:22:01, followed by a high-port connection at 03:22:02","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Correlate Event ID 4624 on 10.10.20.50: find LogonType 3 from 10.10.5.30 at 03:22:00 with admin credentials","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Investigate 10.10.5.30: check for compromise indicators -- find Mimikatz artifacts in memory, evidence of credential dumping at 03:15","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Trace the attack chain: initial phishing compromise at 02:45, credential theft at 03:15, DCOM lateral movement at 03:22","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Contain: isolate 10.10.5.30 and 10.10.20.50, force password reset for compromised admin account, block inbound RPC from non-admin subnets","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Pitfalls","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dismissing mmc.exe activity as legitimate MMC administration without checking the parent process and command line","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Not correlating the network logon (4624) with the process creation to identify the true source host","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Failing to investigate the source host for initial compromise indicators","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Scenario 2: ShellWindows Stealthy Lateral Movement","type":"text"}]},{"type":"paragraph","content":[{"text":"Context","type":"text","marks":[{"type":"strong"}]},{"text":": During a threat hunt, an analyst queries for explorer.exe spawning cmd.exe on domain controllers and finds several instances on DC01 with no interactive logon sessions.","type":"text"}]},{"type":"paragraph","content":[{"text":"Approach","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verify no interactive sessions: query Event ID 4624 LogonType 2 or 10 on DC01 -- none found during the time window","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Query Sysmon Event ID 1: explorer.exe spawning cmd.exe with encoded PowerShell commands at 14:05, 14:12, and 14:18","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Decode the PowerShell: reveals reconnaissance commands (Get-ADUser, Get-ADGroup, Get-ADComputer)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Query Sysmon Event ID 3: inbound RPC connections from 10.10.3.15 preceding each process creation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identify the ShellWindows pattern: no new mmc.exe or dllhost.exe process created -- commands execute through existing explorer.exe, consistent with ShellWindows/ShellBrowserWindow DCOM abuse","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Investigate 10.10.3.15: compromised workstation with Cobalt Strike beacon artifacts","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Pitfalls","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Missing the attack because ShellWindows does not create a separate COM server process -- requires monitoring explorer.exe child processes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Not having Sysmon Event ID 3 configured to capture network connections from explorer.exe","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Filtering out explorer.exe as a legitimate parent process without considering the server context","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output Format","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Hunt ID: TH-DCOM-[DATE]-[SEQ]\nAlert Severity: High\nMITRE Technique: T1021.003 (Remote Services: DCOM)\n\nSource Host: [IP/Hostname of attacker's machine]\nTarget Host: [IP/Hostname where DCOM executed]\nDCOM Object: [MMC20.Application | ShellWindows | ShellBrowserWindow]\nCLSID: [COM object class identifier]\n\nProcess Chain:\n Parent: [svchost.exe -k DcomLaunch | explorer.exe | mmc.exe]\n Child: [cmd.exe | powershell.exe | ...]\n Command Line: [Full command executed]\n\nNetwork Indicators:\n RPC Connection: [Source IP]:port -> [Target IP]:135 at [timestamp]\n DCOM Port: [Source IP]:port -> [Target IP]:[high-port] at [timestamp]\n\nAuthentication Context:\n Event 4624: LogonType 3 from [Source IP] at [timestamp]\n Account: [Domain\\Username]\n Logon ID: [Logon session identifier]\n\nRisk Assessment: [Critical/High/Medium]\nRecommended Action: [Isolate, investigate source, reset credentials, restrict DCOM]","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"hunting-for-dcom-lateral-movement","tags":["threat-hunting","DCOM","lateral-movement","T1021.003","Sysmon","MMC20","ShellWindows","ShellBrowserWindow","COM-objects","WMI","RPC"],"author":"@skillopedia","domain":"cybersecurity","source":{"stars":13207,"repo_name":"anthropic-cybersecurity-skills","origin_url":"https://github.com/mukul975/anthropic-cybersecurity-skills/blob/HEAD/skills/hunting-for-dcom-lateral-movement/SKILL.md","repo_owner":"mukul975","body_sha256":"3db9ed5be4f94a21395b0e7b4f95c5a375441465b564b7f398c2e6577425830d","cluster_key":"d589f59bdc8f2c0f1407d9d50a6f7a30782316a0df08a956c6fc1ffa79c12e53","clean_bundle":{"format":"clean-skill-bundle-v1","source":"mukul975/anthropic-cybersecurity-skills/skills/hunting-for-dcom-lateral-movement/SKILL.md","attachments":[{"id":"e51d269b-30de-5192-9874-750c19940f7f","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/e51d269b-30de-5192-9874-750c19940f7f/attachment.md","path":"references/api-reference.md","size":5744,"sha256":"55bfea0ebc70fa38f1e9f5d06566221411003ea265d3fabe62c60d990715e7ce","contentType":"text/markdown; charset=utf-8"},{"id":"53801688-01ef-50c7-beb1-371b02c646da","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/53801688-01ef-50c7-beb1-371b02c646da/attachment.py","path":"scripts/agent.py","size":14078,"sha256":"daa942659ddcc406f92e0538ce0ced064464537692ed2f38ad085015368e2fd2","contentType":"text/x-python; charset=utf-8"},{"id":"4ef838c1-4042-5bc5-8ee6-e790a00c7c02","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/4ef838c1-4042-5bc5-8ee6-e790a00c7c02/attachment.py","path":"scripts/detect_dcom_lateral_movement.py","size":18920,"sha256":"952b84997d634689e61329fecd50326478bdf61991f096c539f3320d256b8987","contentType":"text/x-python; charset=utf-8"}],"bundle_sha256":"2e6da437a31ebce94c8afe748713d9a9a01e3764a9838ea63578dec4c98d148d","attachment_count":3,"text_attachments":3,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/hunting-for-dcom-lateral-movement/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"security","category_label":"Security"},"exact_dupes_collapsed_into_this":0},"license":"Apache-2.0","version":"v1","category":"security","nist_csf":["DE.CM-01","DE.AE-02","DE.AE-07","ID.RA-05"],"subdomain":"threat-hunting","import_tag":"clean-skills-v1","description":"Hunt for DCOM-based lateral movement by detecting abuse of MMC20.Application, ShellBrowserWindow, and ShellWindows COM objects through Sysmon Event ID 1 (process creation) and Event ID 3 (network connection) correlation, WMI event analysis, RPC endpoint mapper traffic on port 135, and DCOM-specific parent-child process relationships.\n","d3fend_techniques":["Application Protocol Command Analysis","Network Isolation","Network Traffic Analysis","Client-server Payload Profiling","Network Traffic Community Deviation"]}},"renderedAt":1782981850690}

Hunting for DCOM Lateral Movement Authorized Testing Disclaimer : The offensive techniques and attack simulations described in this skill are intended exclusively for authorized penetration testing, red team engagements, purple team exercises, and security research conducted with explicit written permission from the system owner. Unauthorized use of these techniques against systems you do not own or have permission to test is illegal and unethical. Always operate within the scope of your engagement and comply with applicable laws and regulations. Overview Distributed Component Object Model (D…