关于 hunting-for-dcom-lateral-movement
此技能面向企业安全团队,指导通过主机、网络和 SIEM 遥测发现 DCOM 横向移动,并审计相关攻击面。内容涵盖 MMC20.Application、ShellWindows 和 ShellBrowserWindow 等对象的检测规则与调查方法。
主要功能
- 01监控 Sysmon 进程与网络事件
- 02关联 Windows 安全日志
- 03提供 Splunk 与 KQL 检测查询
- 04分析 WMI 与 RPC 活动
- 05审计并加固 DCOM 配置
适用场景
- 01调查可疑 DCOM 命令执行
- 02构建 T1021.003 检测规则
- 03紫队演练验证检测覆盖
- 04审计域内 DCOM 暴露
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill hunting-for-dcom-lateral-movement安装后在 Claude Code 中输入/hunting-for-dcom-lateral-movement确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.pydetect_dcom_lateral_movement.py详细介绍
追踪 DCOM 横向移动
授权测试免责声明:本技能中描述的攻防技术和攻击模拟仅用于经系统所有者明确书面授权的渗透测试、红队演练、紫队演练和安全研究。未经授权对您不拥有或未获许可测试的系统使用这些技术是违法且不道德的。请始终在您的授权范围内操作,并遵守适用的法律法规。
概述
分布式组件对象模型(DCOM)支持通过网络使用 RPC 远程执行 COM 对象。攻击者滥用特定的 DCOM 对象——MMC20.Application(CLSID {49B2791A-B1AE-4C90-9B8E-E860BA07F889})、ShellBrowserWindow(CLSID {C08AFD90-F2A1-11D1-8455-00A0C91F3880})和 ShellWindows(CLSID {9BA05972-F6A8-11CF-A442-00A0C90A8F39})——在远程主机上执行命令而无需落地文件,使其成为一种隐蔽的横向移动技术,对应 MITRE ATT&CK T1021.003。本技能提供使用 Sysmon 遥测、Windows 安全事件关联、网络监控和 SIEM 检测规则的检测策略,以识别企业环境中的 DCOM 滥用。
何时使用
- 在启用 DCOM 的 Active Directory 环境中主动追踪横向移动
- 调查服务器上可疑的 mmc.exe、dllhost.exe 或 explorer.exe 子进程创建告警
- 为 MITRE ATT&CK T1021.003(远程服务:分布式组件对象模型)构建检测规则
- 关联 Sysmon 事件 ID 1(进程创建)和事件 ID 3(网络连接)以追踪基于 DCOM 的命令执行链
- 审计整个域中的 DCOM 暴露面,以减少横向移动攻击面
- 在紫队演练期间验证针对基于 DCOM 技术的检测覆盖情况
请勿使用作为基于 EDR 的横向移动检测的替代方案,在端点未部署 Sysmon 或等效进程遥测的情况下使用,或在不关联网络层和主机层指标的情况下单独使用。
前置条件
- 在端点部署 Sysmon,其配置需捕获事件 ID 1(进程创建)、事件 ID 3(网络连接)、事件 ID 7(映像加载)和事件 ID 10(进程访问)
- Windows 安全事件日志转发至 SIEM(事件 ID 4624、4672、4688)
- 具备关联能力的 SIEM 平台(Splunk、Elastic、Microsoft Sentinel)
- 对 RPC 流量(TCP 135 和动态高位端口 49152-65535)的网络监控
- 环境中合法 DCOM 使用的基线清单
- 了解 MITRE ATT&CK 横向移动战术(TA0008)和 T1021.003
工作流
步骤 1:理解 DCOM 横向移动攻击向量
DCOM 横向移动利用三个主要的 COM 对象。每个都有不同的取证痕迹。
MMC20.Application——攻击者远程实例化 MMC 管理单元,并调用 ExecuteShellCommand 在目标上运行任意命令。这会在目标上将 mmc.exe 生成为 svchost.exe(DcomLaunch 服务)的子进程。
ShellBrowserWindow——使用 Document.Application.ShellExecute 方法通过现有的 explorer.exe 进程执行命令。与 MMC20 不同,这不会为 COM 服务器本身创建新进程,因此更加隐蔽。
ShellWindows——与 ShellBrowserWindow 类似,它在现有的 explorer.exe 实例中激活,并从 explorer.exe 执行子进程。没有新的 COM 服务器进程使其在没有适当遥测的情况下更难检测。
# ATTACK SIMULATION (authorized testing only)
# These commands demonstrate what adversaries execute -- use only in lab environments
# MMC20.Application lateral movement
# $dcom = [System.Activator]::CreateInstance(
# [Type]::GetTypeFromProgID("MMC20.Application", "TARGET_IP"))
# $dcom.Document.ActiveView.ExecuteShellCommand(
# "cmd.exe", $null, "/c whoami > C:\temp\output.txt", "7")
# ShellWindows lateral movement
# $dcom = [System.Activator]::CreateInstance(
# [Type]::GetTypeFromCLSID(
# [guid]"9BA05972-F6A8-11CF-A442-00A0C90A8F39", "TARGET_IP"))
# $dcom.item().Document.Application.ShellExecute(
# "cmd.exe", "/c calc.exe", "C:\windows\system32", $null, 0)
# ShellBrowserWindow lateral movement
# $dcom = [System.Activator]::CreateInstance(
# [Type]::GetTypeFromCLSID(
# [guid]"C08AFD90-F2A1-11D1-8455-00A0C91F3880", "TARGET_IP"))
# $dcom.Document.Application.ShellExecute(
# "cmd.exe", "/c net user", "C:\windows\system32", $null, 0)
步骤 2:配置 Sysmon 以进行 DCOM 检测
<Sysmon schemaversion="4.90">
<EventFiltering>
<RuleGroup name="DCOM_ProcessCreate" groupRelation="or">
<ProcessCreate onmatch="include">
<ParentImage condition="end with">mmc.exe</ParentImage>
<ParentCommandLine condition="contains">DcomLaunch</ParentCommandLine>
<ParentImage condition="end with">dllhost.exe</ParentImage>
<Rule groupRelation="and">
<ParentImage condition="end with">explorer.exe</ParentImage>
<Image condition="end with">cmd.exe</Image>
</Rule>
<Rule groupRelation="and">
<ParentImage condition="end with">explorer.exe</ParentImage>
<Image condition="end with">powershell.exe</Image>
</Rule>
</ProcessCreate>
</RuleGroup>
<RuleGroup name="DCOM_NetworkConnect" groupRelation="or">
<NetworkConnect onmatch="include">
<DestinationPort condition="is">135</DestinationPort>
<Image condition="end with">mmc.exe</Image>
<Image condition="end with">dllhost.exe</Image>
<Rule groupRelation="and">
<Image condition="end with">svchost.exe</Image>
<DestinationPort condition="more than">49151</DestinationPort>
</Rule>
</NetworkConnect>
</RuleGroup>
<RuleGroup name="DCOM_ImageLoaded" groupRelation="or">
<ImageLoad onmatch="include">
<ImageLoaded condition="end with">comsvcs.dll</ImageLoaded>
<ImageLoaded condition="end with">ole32.dll</ImageLoaded>
<ImageLoaded condition="end with">rpcrt4.dll</ImageLoaded>
</ImageLoad>
</RuleGroup>
</EventFiltering>
</Sysmon>
# Deploy or update Sysmon configuration
# sysmon64.exe -c dcom-detection-sysmon.xml
# Verify Sysmon is capturing DCOM events
# PowerShell: Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 10 |
# Where-Object { $_.Id -in @(1,3) } | Format-Table TimeCreated, Id, Message -Wrap
步骤 3:为 DCOM 对象滥用构建 SIEM 检测规则
# Sigma Rule: MMC20.Application DCOM Lateral Movement
title: DCOM Lateral Movement via MMC20.Application
id: 8a3b5f2e-c1d4-4a9f-b237-1e6f8d2c3a4b
status: stable
description: >
Detects remote instantiation of MMC20.Application DCOM object by monitoring
for mmc.exe spawned by svchost.exe DcomLaunch service with subsequent child
process creation, indicating T1021.003 lateral movement.
references:
- https://attack.mitre.org/techniques/T1021/003/
- https://www.cybereason.com/blog/dcom-lateral-movement-techniques
- https://www.mdsec.co.uk/2020/09/i-like-to-move-it-windows-lateral-movement-part-2-dcom/
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith: '\mmc.exe'
selection_child:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
- '\wscript.exe'
- '\cscript.exe'
- '\mshta.exe'
- '\rundll32.exe'
- '\regsvr32.exe'
filter_legitimate:
ParentCommandLine|contains:
- 'devmgmt.msc'
- 'diskmgmt.msc'
- 'services.msc'
- 'compmgmt.msc'
condition: selection_parent and selection_child and not filter_legitimate
level: high
tags:
- attack.lateral_movement
- attack.t1021.003
falsepositives:
- Legitimate remote MMC administration by authorized IT staff
- SCCM or other management tools using DCOM for remote management
# Sigma Rule: ShellWindows/ShellBrowserWindow DCOM Lateral Movement
title: DCOM Lateral Movement via ShellWindows or ShellBrowserWindow
id: 2f7c9d1e-a8b3-4c5f-9012-3e4d5f6a7b8c
status: stable
description: >
Detects DCOM lateral movement using ShellWindows (CLSID 9BA05972) or
ShellBrowserWindow (CLSID C08AFD90) by monitoring for explorer.exe spawning
cmd.exe or powershell.exe on systems where no user is interactively logged on,
or where the network logon (Type 3) precedes the process creation.
references:
- https://attack.mitre.org/techniques/T1021/003/
- https://www.elastic.co/guide/en/security/8.19/incoming-dcom-lateral-movement-with-shellbrowserwindow-or-shellwindows.html
logsource:
category: process_creation
product: windows
detection:
selection:
ParentImage|endswith: '\explorer.exe'
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
- '\mshta.exe'
- '\wscript.exe'
- '\cscript.exe'
filter_interactive:
LogonId: '0x3e7'
condition: selection and not filter_interactive
level: medium
tags:
- attack.lateral_movement
- attack.t1021.003
falsepositives:
- Users launching command prompts from Explorer context menus
- Software installers launching child processes from explorer.exe
# Sigma Rule: Sysmon Network Connection to RPC Endpoint Mapper from DCOM Process
title: DCOM Process Inbound RPC Connection Followed by Process Creation
id: 4d9e2f1a-b3c5-4a7f-8901-2c3d4e5f6a7b
status: experimental
description: >
Correlates Sysmon Event ID 3 (Network Connection) on port 135 with
subsequent Event ID 1 (Process Create) from DCOM parent processes
(mmc.exe, dllhost.exe, explorer.exe) within a short time window.
logsource:
product: windows
service: sysmon
detection:
network_connection:
EventID: 3
DestinationPort: 135
Initiated: 'false'
process_creation:
EventID: 1
ParentImage|endswith:
- '\mmc.exe'
- '\dllhost.exe'
- '\svchost.exe'
timeframe: 30s
condition: network_connection | near process_creation
level: high
tags:
- attack.lateral_movement
- attack.t1021.003
步骤 4:部署 Splunk 和 KQL 检测查询
# Splunk: Detect MMC20.Application DCOM Lateral Movement
# Correlates network logon (4624 Type 3) with mmc.exe process creation
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
EventCode=1 ParentImage="*\\mmc.exe"
(Image="*\\cmd.exe" OR Image="*\\powershell.exe" OR Image="*\\pwsh.exe"
OR Image="*\\wscript.exe" OR Image="*\\cscript.exe" OR Image="*\\mshta.exe")
| eval target_host=ComputerName
| join target_host type=inner
[search index=wineventlog EventCode=4624 LogonType=3
| where AuthenticationPackageName="NTLM" OR AuthenticationPackageName="Kerberos"
| eval target_host=ComputerName
| rename IpAddress as source_ip, TargetUserName as logon_user
| fields target_host source_ip logon_user _time]
| where abs(_time - relative_time(now(), "-5m")) < 300
| table _time target_host Image ParentImage CommandLine source_ip logon_user
| sort -_time
# Splunk: Detect ShellWindows/ShellBrowserWindow DCOM Lateral Movement
# Identifies explorer.exe spawning suspicious child processes on servers
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
EventCode=1 ParentImage="*\\explorer.exe"
(Image="*\\cmd.exe" OR Image="*\\powershell.exe" OR Image="*\\pwsh.exe")
| eval target_host=ComputerName
| join target_host type=inner
[search index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
EventCode=3 DestinationPort=135 Initiated="false"
| eval target_host=ComputerName
| rename SourceIp as dcom_source_ip
| fields target_host dcom_source_ip _time]
| where abs(_time - relative_time(now(), "-2m")) < 120
| stats count values(Image) as child_processes values(CommandLine) as commands
by target_host dcom_source_ip
| where count > 0
| table target_host dcom_source_ip child_processes commands count
# Splunk: DCOM RPC Endpoint Mapper Connection Anomaly
# Identifies hosts receiving unusual volumes of inbound RPC connections
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
EventCode=3 DestinationPort=135 Initiated="false"
| stats dc(SourceIp) as unique_sources count by ComputerName
| where unique_sources > 3 OR count > 10
| sort -unique_sources
| table ComputerName unique_sources count
-- Microsoft Sentinel KQL: DCOM Lateral Movement via MMC20.Application
let dcom_network = SysmonEvent
| where EventID == 3
| where DestinationPort == 135
| where InitiatedConnection == false
| project NetworkTime=TimeGenerated, TargetComputer=Computer,
SourceIP=SourceIp, DestPort=DestinationPort;
let dcom_process = SysmonEvent
| where EventID == 1
| where ParentImage endswith "\\mmc.exe"
or ParentImage endswith "\\dllhost.exe"
| where Image endswith "\\cmd.exe"
or Image endswith "\\powershell.exe"
or Image endswith "\\pwsh.exe"
or Image endswith "\\wscript.exe"
or Image endswith "\\mshta.exe"
| project ProcessTime=TimeGenerated, TargetComputer=Computer,
ParentImage, Image, CommandLine, User;
dcom_network
| join kind=inner (dcom_process) on TargetComputer
| where abs(datetime_diff('second', NetworkTime, ProcessTime)) < 60
| project NetworkTime, ProcessTime, TargetComputer, SourceIP,
ParentImage, Image, CommandLine, User
| sort by NetworkTime desc
-- Microsoft Sentinel KQL: ShellWindows DCOM Lateral Movement
SecurityEvent
| where EventID == 4624 and LogonType == 3
| where AuthenticationPackageName in ("NTLM", "Kerberos")
| project LogonTime=TimeGenerated, TargetComputer=Computer,
SourceIP=IpAddress, LogonUser=TargetUserName
| join kind=inner (
SysmonEvent
| where EventID == 1
| where ParentImage endswith "\\explorer.exe"
| where Image endswith "\\cmd.exe"
or Image endswith "\\powershell.exe"
or Image endswith "\\pwsh.exe"
| project ProcessTime=TimeGenerated, TargetComputer=Computer,
Image, CommandLine, User
) on TargetComputer
| where ProcessTime between (LogonTime .. (LogonTime + 2m))
| project LogonTime, ProcessTime, TargetComputer, SourceIP,
LogonUser, Image, CommandLine
| sort by LogonTime desc
步骤 5:WMI 事件关联以检测 DCOM 活动
# Splunk: Correlate WMI events with DCOM lateral movement
# WMI-Activity operational log captures DCOM-triggered WMI calls
index=wineventlog source="WinEventLog:Microsoft-Windows-WMI-Activity/Operational"
| where EventCode IN (5857, 5858, 5859, 5860, 5861)
| eval event_type=case(
EventCode=5857, "WMI Provider Loaded",
EventCode=5858, "WMI Query Error",
EventCode=5859, "WMI Provider Event",
EventCode=5860, "WMI Temporary Event Registration",
EventCode=5861, "WMI Permanent Event Registration")
| stats count values(event_type) as wmi_events by ComputerName
| where count > 5
| table ComputerName wmi_events count
# PowerShell: Query WMI operational log for DCOM-related activity
# Run on target systems during investigation
Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Operational" -MaxEvents 500 |
Where-Object {
$_.Id -in @(5857, 5858, 5860, 5861) -and
$_.Message -match "DCOM|MMC20|ShellWindows|ShellBrowserWindow"
} |
Select-Object TimeCreated, Id,
@{N='Detail'; E={$_.Message.Substring(0, [Math]::Min(200, $_.Message.Length))}} |
Format-Table -AutoSize
# Query Sysmon for DCOM parent-child process chains
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -FilterXPath @"
*[System[(EventID=1)]] and
*[EventData[
(Data[@Name='ParentImage'] and
(contains(Data[@Name='ParentImage'],'mmc.exe') or
contains(Data[@Name='ParentImage'],'dllhost.exe')))
]]
"@ -MaxEvents 100 |
Select-Object TimeCreated,
@{N='ParentImage'; E={$_.Properties[20].Value}},
@{N='Image'; E={$_.Properties[4].Value}},
@{N='CommandLine'; E={$_.Properties[10].Value}},
@{N='User'; E={$_.Properties[12].Value}} |
Format-Table -AutoSize
第 6 步:使用 Zeek 进行网络层 DCOM 检测
# Zeek script for detecting DCOM lateral movement at the network level
# Monitors RPC Endpoint Mapper (port 135) and subsequent high-port connections
cat > /opt/zeek/share/zeek/site/custom-detections/dcom-lateral-movement.zeek << 'ZEEKEOF'
@load base/frameworks/notice
@load base/frameworks/sumstats
@load base/protocols/dce-rpc
module DCOMLateralMovement;
export {
redef enum Notice::Type += {
DCOM_Lateral_Movement_Suspected,
DCOM_RPC_Scan
};
# Threshold for unique targets receiving RPC connections from single source
const rpc_target_threshold: count = 3 &redef;
const rpc_time_window: interval = 10min &redef;
}
event zeek_init()
{
local r1 = SumStats::Reducer(
$stream="dcom.rpc_targets",
$apply=set(SumStats::UNIQUE)
);
SumStats::create([
$name="detect-dcom-lateral",
$epoch=rpc_time_window,
$reducers=set(r1),
$threshold_val(key: SumStats::Key, result: SumStats::Result) = {
return result["dcom.rpc_targets"]$unique + 0.0;
},
$threshold=rpc_target_threshold + 0.0,
$threshold_crossed(key: SumStats::Key, result: SumStats::Result) = {
NOTICE([
$note=DCOM_RPC_Scan,
$msg=fmt("Host %s connected to %d hosts on RPC/135 in %s - possible DCOM lateral movement",
key$str, result["dcom.rpc_targets"]$unique, rpc_time_window),
$identifier=key$str
]);
}
]);
}
event connection_state_remove(c: connection)
{
if ( c$id$resp_p == 135/tcp && c$id$resp_h in Site::local_nets )
{
SumStats::observe("dcom.rpc_targets",
[$str=cat(c$id$orig_h)],
[$str=cat(c$id$resp_h)]
);
}
}
ZEEKEOF
# Monitor DCE-RPC operations related to DCOM objects
cat /opt/zeek/logs/current/dce_rpc.log | \
zeek-cut ts id.orig_h id.resp_h endpoint operation | \
grep -iE "IDispatch|IRemoteActivation|IRemUnknown|IObjectExporter" | \
sort -t$'\t' -k2 | uniq -c | sort -rn
# Track RPC endpoint mapper connections between internal hosts
cat /opt/zeek/logs/current/conn.log | \
zeek-cut ts id.orig_h id.resp_h id.resp_p duration | \
awk '$4 == 135' | \
awk '{print $2, "->", $3}' | sort | uniq -c | sort -rn | head -20
第 7 步:DCOM 攻击面审计与加固
# Audit DCOM configuration across the domain
# Enumerate remotely accessible DCOM objects
# List DCOM applications registered on local system
Get-CimInstance -ClassName Win32_DCOMApplication |
Select-Object AppID, Name |
Sort-Object Name |
Format-Table -AutoSize
# Check DCOM launch permissions for high-risk objects
$clsids = @{
"MMC20.Application" = "{49B2791A-B1AE-4C90-9B8E-E860BA07F889}"
"ShellWindows" = "{9BA05972-F6A8-11CF-A442-00A0C90A8F39}"
"ShellBrowserWindow" = "{C08AFD90-F2A1-11D1-8455-00A0C91F3880}"
"Excel.Application" = "{00024500-0000-0000-C000-000000000046}"
"Outlook.Application" = "{0006F03A-0000-0000-C000-000000000046}"
}
foreach ($name in $clsids.Keys) {
$clsid = $clsids[$name]
$regPath = "HKLM:\SOFTWARE\Classes\CLSID\$clsid"
if (Test-Path $regPath) {
$launchPermission = (Get-ItemProperty -Path "$regPath" -Name "LaunchPermission" -ErrorAction SilentlyContinue)
Write-Host "[*] $name ($clsid): $(if ($launchPermission) { 'Custom permissions set' } else { 'DEFAULT permissions (potentially exploitable)' })"
} else {
Write-Host "[-] $name ($clsid): Not found on this system"
}
}
# Check if DCOM is enabled (should be restricted on servers that don't need it)
$dcomEnabled = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Ole" -Name "EnableDCOM").EnableDCOM
Write-Host "`n[*] DCOM Enabled: $dcomEnabled"
# Check remote launch and activation permissions
$remoteLaunch = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Ole" -Name "DefaultLaunchPermission" -ErrorAction SilentlyContinue)
Write-Host "[*] Default Launch Permission: $(if ($remoteLaunch) { 'Custom' } else { 'System Default' })"
# Hardening: Restrict DCOM remote access via Group Policy
# These settings should be applied via GPO in production
# Disable DCOM on systems that do not require it
# Computer Configuration > Administrative Templates > System > Distributed COM >
# Application Compatibility > Enable Distributed COM on this computer = Disabled
# Restrict DCOM launch permissions via registry
# Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Ole" -Name "EnableDCOM" -Value "N"
# Block RPC/DCOM at the host firewall for non-admin traffic
# New-NetFirewallRule -DisplayName "Block Inbound DCOM/RPC" `
# -Direction Inbound -LocalPort 135 -Protocol TCP `
# -Action Block -RemoteAddress "Any" `
# -Group "DCOM Hardening"
#
# New-NetFirewallRule -DisplayName "Allow DCOM from Admin Subnets" `
# -Direction Inbound -LocalPort 135 -Protocol TCP `
# -Action Allow -RemoteAddress "10.10.0.0/24" `
# -Group "DCOM Hardening"
# Windows Firewall: Restrict dynamic RPC port range
# netsh int ipv4 set dynamicport tcp start=49152 num=1024
关键概念
| 术语 | 定义 |
|---|---|
| DCOM (T1021.003) | 分布式组件对象模型(Distributed Component Object Model)—— 扩展了 COM,允许通过 RPC 进行远程对象实例化和方法调用,常被滥用于横向移动 |
| MMC20.Application | 控制 MMC 管理单元的 COM 对象(CLSID {49B2791A-B1AE-4C90-9B8E-E860BA07F889});ExecuteShellCommand 方法可实现远程命令执行 |
| ShellWindows | 在现有 explorer.exe 进程内激活的 COM 对象(CLSID {9BA05972-F6A8-11CF-A442-00A0C90A8F39}),无需创建新的 COM 服务进程即可执行命令 |
| ShellBrowserWindow | 与 ShellWindows 类似的 COM 对象(CLSID {C08AFD90-F2A1-11D1-8455-00A0C91F3880}),使用 Document.Application.ShellExecute 进行隐蔽的命令执行 |
| RPC 终结点映射器 | 位于 TCP 端口 135 的服务,将 RPC 接口映射到动态端口;所有 DCOM 通信都以终结点映射器查询开始 |
| Sysmon 事件 ID 1 | 进程创建事件,捕获父子进程关系、命令行和用户上下文 —— 对于识别由 DCOM 生成的进程至关重要 |
| Sysmon 事件 ID 3 | 网络连接事件,捕获源/目标 IP 和端口 —— 用于将 RPC 连接与后续进程创建相关联 |
| DcomLaunch | 管理 DCOM 服务进程激活的 Windows 服务 (svchost.exe -k DcomLaunch);是通过远程 DCOM 调用生成的 COM 服务的父进程 |
| WMI-Activity ETW | 记录 WMI 方法调用、实例创建和查询的 Windows 事件跟踪提供程序 —— 提供对 DCOM 触发的 WMI 操作的可见性 |
工具与系统
| 工具 | 用途 |
|---|---|
| Sysmon | 用于进程创建 (EID 1)、网络连接 (EID 3) 和映像加载 (EID 7) 的终结点遥测,对 DCOM 检测至关重要 |
| Splunk / Elastic SIEM | 用于 DCOM 检测规则和威胁狩猎查询的日志聚合与关联平台 |
| Microsoft Sentinel | 内置 KQL 查询和分析规则的云 SIEM,用于 DCOM 横向移动检测 |
| Sigma | 供应商无关的检测规则格式,用于可移植的 DCOM 检测规则 |
| Zeek | 用于 DCE-RPC 协议分析和 RPC 终结点映射器流量监控的网络安全监视器 |
| Atomic Red Team | 带有 T1021.003 atomics 的 MITRE ATT&CK 测试框架,用于验证 DCOM 检测覆盖范围 |
| Impacket (dcomexec.py) | 基于 Python 的 DCOM 执行工具,被攻击者和红队用于测试 DCOM 横向移动 |
| CIMSession / PowerShell | 用于 DCOM 对象实例化的原生 Windows 工具,既用于合法管理也用于攻击 |
常见场景
场景 1:MMC20.Application 横向移动到文件服务器
背景:SOC 分析师收到告警,03:22 UTC 在文件服务器(10.10.20.50)上 mmc.exe 启动了 cmd.exe。该时段没有安排管理员活动。
方法:
- 查询 10.10.20.50 上的 Sysmon 事件 ID 1:确认 mmc.exe(父进程:svchost.exe -k DcomLaunch)启动了 cmd.exe,命令行是
/c net user /domain > C:\temp\users.txt - 查询 10.10.20.50 上的 Sysmon 事件 ID 3:识别 03:22:01 来自 10.10.5.30 的入站 TCP 135 端口连接,随后在 03:22:02 有一个高位端口连接
- 关联 10.10.20.50 上的事件 ID 4624:发现 03:22:00 来自 10.10.5.30 的 LogonType 3 并使用管理员凭据
- 调查 10.10.5.30:检查失陷指标——发现内存中的 Mimikatz 痕迹,03:15 有凭据转储的证据
- 追踪攻击链:02:45 初始钓鱼失陷,03:15 凭据窃取,03:22 DCOM 横向移动
- 遏制:隔离 10.10.5.30 和 10.10.20.50,强制重置失陷管理员账户的密码,阻止来自非管理员子网的入站 RPC
易错点:
- 未检查父进程和命令行,就将 mmc.exe 活动当作正常 MMC 管理而忽略
- 未将网络登录(4624)与进程创建进行关联,从而未能识别真正的源主机
- 未调查源主机以发现初始失陷指标
场景 2:ShellWindows 隐蔽横向移动
背景:在一次威胁狩猎中,分析师在域控制器上查询 explorer.exe 启动 cmd.exe 的情况,并在 DC01 上发现若干实例,且没有交互式登录会话。
方法:
- 确认没有交互式会话:查询 DC01 上的事件 ID 4624 LogonType 2 或 10——时间窗口内未发现任何记录
- 查询 Sysmon 事件 ID 1:explorer.exe 在 14:05、14:12 和 14:18 启动了带有编码 PowerShell 命令的 cmd.exe
- 解码 PowerShell:发现侦察命令(Get-ADUser、Get-ADGroup、Get-ADComputer)
- 查询 Sysmon 事件 ID 3:每次进程创建前都有来自 10.10.3.15 的入站 RPC 连接
- 识别 ShellWindows 模式:没有创建新的 mmc.exe 或 dllhost.exe 进程——命令通过现有 explorer.exe 执行,符合 ShellWindows/ShellBrowserWindow DCOM 滥用
- 调查 10.10.3.15:失陷工作站,带有 Cobalt Strike beacon 痕迹
易错点:
- 因为 ShellWindows 不会创建单独的 COM 服务进程而漏掉攻击——需要监控 explorer.exe 子进程
- 未配置 Sysmon 事件 ID 3 来捕获来自 explorer.exe 的网络连接
- 将 explorer.exe 作为正常父进程过滤掉,而未考虑服务器上下文
输出格式
Hunt ID: TH-DCOM-[DATE]-[SEQ]
Alert Severity: High
MITRE Technique: T1021.003 (Remote Services: DCOM)
Source Host: [IP/Hostname of attacker's machine]
Target Host: [IP/Hostname where DCOM executed]
DCOM Object: [MMC20.Application | ShellWindows | ShellBrowserWindow]
CLSID: [COM object class identifier]
Process Chain:
Parent: [svchost.exe -k DcomLaunch | explorer.exe | mmc.exe]
Child: [cmd.exe | powershell.exe | ...]
Command Line: [Full command executed]
Network Indicators:
RPC Connection: [Source IP]:port -> [Target IP]:135 at [timestamp]
DCOM Port: [Source IP]:port -> [Target IP]:[high-port] at [timestamp]
Authentication Context:
Event 4624: LogonType 3 from [Source IP] at [timestamp]
Account: [Domain\Username]
Logon ID: [Logon session identifier]
Risk Assessment: [Critical/High/Medium]
Recommended Action: [Isolate, investigate source, reset credentials, restrict DCOM]