mcpField
H
hunting-for-dcom-lateral-movement

hunting-for-dcom-lateral-movement

github.com/mukul975セキュリティ35.2k46 回インストール8 週間前に更新
リポジトリ

hunting-for-dcom-lateral-movement について

企業のセキュリティチーム向けに、ホスト、ネットワーク、SIEMのテレメトリを使ったDCOMラテラルムーブメントの検出と攻撃面の監査方法を説明します。MMC20.Application、ShellWindows、ShellBrowserWindowの検出ルールと調査手順を扱います。

主な機能

  1. 01Sysmonのプロセス・ネットワークイベント監視
  2. 02Windowsセキュリティログの相関
  3. 03SplunkとKQLの検出クエリ
  4. 04WMIとRPCアクティビティの分析
  5. 05DCOM設定の監査と強化

活用シーン

  1. 01不審なDCOMコマンド実行の調査
  2. 02T1021.003検出ルールの作成
  3. 03紫チーム演習での検出範囲の検証
  4. 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 と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
scripts/
agent.py
detect_dcom_lateral_movement.py

詳細

DCOM ラテラルムーブメントのハンティング

許可されたテストに関する免責事項: このスキルで説明する攻撃手法およびアタックシミュレーションは、システム所有者からの明示的な書面による許可を得た、認可された侵入テスト、レッドチーム演習、パープルチーム演習、およびセキュリティ研究にのみ使用することを目的としています。所有していない、またはテストの許可を得ていないシステムに対してこれらの手法を無断で使用することは違法であり、非倫理的です。必ず業務の範囲内で作業し、適用される法律および規制を遵守してください。

概要

Distributed Component Object Model (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 (Remote Services: Distributed Component Object Model) の検知ルールを作成するとき
  • Sysmon イベント ID 1 (Process Create) とイベント ID 3 (Network Connection) を相関させ、DCOM ベースのコマンド実行チェーンを追跡するとき
  • ドメイン全体の DCOM の公開状況を監査し、ラテラルムーブメントの攻撃対象領域を縮小するとき
  • パープルチーム演習中に、DCOM ベースの手法に対する検知カバレッジを検証するとき

次の場合は使用しないでください: エンドポイントに Sysmon または同等のプロセステレメトリが導入されていない場合、EDR によるラテラルムーブメント検知の代替として使う場合、またはネットワークレベルとホストレベルの指標を相関させずに単独で使う場合です。

前提条件

  • エンドポイントに Sysmon が導入され、イベント ID 1 (Process Create)、イベント ID 3 (Network Connection)、イベント ID 7 (Image Loaded)、イベント ID 10 (Process Access) を取得する構成になっていること
  • 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 によるラテラルムーブメントでは、主に 3 つの COM オブジェクトが悪用されます。それぞれに固有のフォレンジックアーティファクトがあります。

MMC20.Application -- 攻撃者はリモートで MMC スナップインをインスタンス化し、ExecuteShellCommand を呼び出して、ターゲット上で任意のコマンドを実行します。これにより、ターゲット上で svchost.exe (DcomLaunch サービス) の子プロセスとして mmc.exe が生成されます。

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: DCOM 検知のために Sysmon を構成する



<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: DCOM アクティビティに対する WMI イベントの相関分析
# 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
Step 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
Step 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.ApplicationMMC スナップインを制御する COM オブジェクト(CLSID {49B2791A-B1AE-4C90-9B8E-E860BA07F889})。ExecuteShellCommand メソッドによりリモートでのコマンド実行が可能になる
ShellWindows既存の explorer.exe プロセス内でアクティブ化される COM オブジェクト(CLSID {9BA05972-F6A8-11CF-A442-00A0C90A8F39})。新しい COM サーバープロセスを作成せずにコマンドを実行する
ShellBrowserWindowShellWindows に類似した COM オブジェクト(CLSID {C08AFD90-F2A1-11D1-8455-00A0C91F3880})。Document.Application.ShellExecute を使用して、目立たない形でコマンドを実行する
RPC Endpoint MapperTCP ポート 135 で動作するサービスで、RPC インターフェースを動的ポートに対応付ける。すべての DCOM 通信は、エンドポイントマッパーへの問い合わせから始まる
Sysmon Event ID 1親子プロセスの関係、コマンドライン、ユーザーコンテキストを取得するプロセス作成イベント。DCOM によって生成されたプロセスの特定に欠かせない
Sysmon Event ID 3送信元/宛先の IP アドレスとポートを取得するネットワーク接続イベント。RPC 接続と、その後のプロセス作成を関連付けるために使用する
DcomLaunchDCOM サーバープロセスのアクティブ化を管理する Windows サービス(svchost.exe -k DcomLaunch)。リモート DCOM 呼び出しによって生成された COM サーバーの親プロセスとなる
WMI-Activity ETWWMI メソッド呼び出し、インスタンス作成、クエリを記録する Event Tracing for Windows プロバイダー。DCOM によってトリガーされた WMI 操作を可視化する

ツールとシステム

ツール用途
Sysmonプロセス作成(EID 1)、ネットワーク接続(EID 3)、イメージロード(EID 7)のエンドポイントテレメトリを取得する。DCOM 検知に不可欠
Splunk / Elastic SIEMDCOM 検知ルールおよびスレットハンティングクエリのためのログ集約・相関分析プラットフォーム
Microsoft Sentinel組み込みの KQL クエリと分析ルールを備えたクラウド SIEM。DCOM によるラテラルムーブメントの検知に使用する
Sigmaベンダーに依存しない検知ルール形式。移植性の高い DCOM 検知ルールを作成できる
ZeekDCE-RPC プロトコル解析と RPC エンドポイントマッパーのトラフィック監視を行うネットワークセキュリティモニター
Atomic Red TeamMITRE ATT&CK のテストフレームワーク。T1021.003 のアトミックテストにより DCOM 検知のカバレッジを検証する
Impacket (dcomexec.py)攻撃者およびレッドチームが DCOM によるラテラルムーブメントをテストするために使用する Python ベースの DCOM 実行ツール
CIMSession / PowerShell正規の管理作業と攻撃の両方で使われる、DCOM オブジェクトのインスタンス化のための Windows ネイティブツール

一般的なシナリオ

シナリオ 1: MMC20.Application によるファイルサーバーへの横展開

状況: SOC アナリストが、03:22 UTC にファイルサーバー(10.10.20.50)上で mmc.exe が cmd.exe を起動したというアラートを受け取りました。この時間帯に管理者による作業の予定はありません。

手順:

  1. 10.10.20.50 の Sysmon Event ID 1 を照会し、mmc.exe(親プロセス: svchost.exe -k DcomLaunch)が、コマンドライン /c net user /domain > C:\temp\users.txt を指定して cmd.exe を起動したことを確認します
  2. 10.10.20.50 の Sysmon Event ID 3 を照会し、03:22:01 に 10.10.5.30 からポート 135 への受信 TCP 接続があり、その直後の 03:22:02 にハイポートへの接続があったことを特定します
  3. 10.10.20.50 の Event ID 4624 と相関させ、03:22:00 に 10.10.5.30 から管理者資格情報による LogonType 3 のログオンがあったことを確認します
  4. 10.10.5.30 を調査し、侵害の痕跡を確認します。メモリ上に Mimikatz の痕跡があり、03:15 に資格情報ダンプが行われた形跡を見つけます
  5. 攻撃の連鎖をたどります。02:45 にフィッシングによる初期侵害、03:15 に資格情報窃取、03:22 に DCOM による横展開が行われています
  6. 封じ込めを行います。10.10.5.30 と 10.10.20.50 を隔離し、侵害された管理者アカウントのパスワードを強制的にリセットし、非管理者サブネットからの受信 RPC をブロックします

よくある落とし穴:

  • 親プロセスとコマンドラインを確認せずに、mmc.exe の活動を正規の MMC による管理作業として片付けてしまう
  • ネットワークログオン(4624)をプロセス作成イベントと相関させず、真の接続元ホストを特定できない
  • 送信元ホストに対して初期侵害の痕跡があるかを調査しない
シナリオ 2: ShellWindows によるステルス横展開

状況: 脅威ハンティング中、アナリストがドメインコントローラー上で explorer.exe が cmd.exe を起動している事例を検索したところ、DC01 で、対話型ログオンセッションがないにもかかわらず複数の事例を発見しました。

手順:

  1. 対話型セッションがないことを確認します。DC01 で Event ID 4624 の LogonType 2 または 10 を照会しましたが、該当時間帯には見つかりませんでした
  2. Sysmon Event ID 1 を照会します。explorer.exe が、エンコードされた PowerShell コマンドを伴って cmd.exe を起動しており、14:05、14:12、14:18 に発生しています
  3. PowerShell をデコードすると、偵察コマンド(Get-ADUser、Get-ADGroup、Get-ADComputer)であることがわかります
  4. Sysmon Event ID 3 を照会します。各プロセス作成の直前に、10.10.3.15 からの受信 RPC 接続があります
  5. ShellWindows のパターンを特定します。新しい mmc.exe や dllhost.exe は作成されておらず、コマンドは既存の explorer.exe を経由して実行されています。これは ShellWindows/ShellBrowserWindow の DCOM 悪用と一致します
  6. 10.10.3.15 を調査します。Cobalt Strike ビーコンの痕跡がある、侵害されたワークステーションです

よくある落とし穴:

  • ShellWindows は別個の COM サーバープロセスを作成しないため、攻撃を見逃してしまう。explorer.exe の子プロセスを監視する必要があります
  • explorer.exe からのネットワーク接続を取得するように Sysmon Event ID 3 が設定されていない
  • サーバーの文脈を考慮せずに、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]

コメント