detecting-lateral-movement-in-network について
SOC分析者やネットワーク防御チーム向けのラテラルムーブメント検知スキルです。Windows認証ログ、ネットワーク通信、SIEMルールを相関させ、内部ホスト間の攻撃活動を調査する手順を示します。
主な機能
- 01Windowsセキュリティログ収集の設定
- 02SIEMおよびSigma検知ルールの作成
- 03ZeekによるSMBなどの通信分析
- 04認証と接続の異常の相関
- 05調査タイムラインとダッシュボードの作成
活用シーン
- 01PsExecやパス・ザ・ハッシュ活動の調査
- 02内部ホスト間の異常な接続の追跡
- 03ネットワーク分割とアクセス制御の検証
- 04ランサムウェアの横展開経路の把握
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill detecting-lateral-movement-in-networkインストール後、Claude Code で/detecting-lateral-movement-in-networkを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
ネットワーク内のラテラルムーブメントの検知
使用する場面
- 侵害後のラテラルムーブメントのパターン(Pass-the-Hash、RDP ホッピング、PsExec)を把握するために、企業ネットワークを監視する場合
- 一般的な MITRE ATT&CK のラテラルムーブメント手法(T1021、T1570)に対する SIEM の検知ルールとアラートを作成する場合
- 内部ホスト間の認証パターンとネットワーク接続を分析して、侵害の疑いを調査する場合
- 攻撃者がネットワーク内をピボットしていることを示す、異常な東西トラフィックのパターンをハンティングする場合
- ネットワークのセグメンテーションとアクセス制御によって、ラテラルムーブメントの経路が効果的に制限されていることを検証する場合
エンドポイント検知・対応(EDR)ツールの代替として、内部トラフィックを無視して南北トラフィックのみを監視する場合、または通常の内部通信パターンに関するベースラインの知識がない場合は、使用しないでください。
前提条件
- 内部のチョークポイントにネットワークセキュリティ監視が導入されていること(Zeek、Suricata、またはネットワーク TAP)
- Windows Security Event Logs、DNS、フローデータを収集する SIEM プラットフォーム(Splunk、Elastic、Microsoft Sentinel)
- Security イベント(4624、4625、4648、4672、4768、4769)の Windows Event Log 転送が設定されていること
- 通常の内部認証および接続パターンのベースライン
- MITRE ATT&CK のラテラルムーブメント戦術(TA0008)に関する理解
ワークフロー
ステップ 1:ラテラルムーブメント検知用のログ収集を設定する
# Windows Event Logs to collect (via WEF or agent):
# Security Log:
# 4624 - Successful logon (Type 3=Network, Type 10=RemoteInteractive)
# 4625 - Failed logon
# 4648 - Logon using explicit credentials (RunAs, PsExec)
# 4672 - Special privileges assigned (admin logon)
# 4768 - Kerberos TGT request
# 4769 - Kerberos service ticket request
# 4776 - NTLM authentication (credential validation)
# System Log:
# 7045 - New service installed (PsExec indicator)
# 7036 - Service started/stopped
# Configure Windows Event Forwarding (WEF) subscription
# On the collector server (PowerShell):
# wecutil cs lateral-movement-subscription.xml
# Filebeat configuration for Windows Event Log shipping
cat > /etc/filebeat/modules.d/security.yml << 'EOF'
- module: system
auth:
enabled: true
var.paths: ["/var/log/auth.log"]
syslog:
enabled: true
- module: zeek
connection:
enabled: true
var.paths: ["/opt/zeek/logs/current/conn.log"]
dns:
enabled: true
var.paths: ["/opt/zeek/logs/current/dns.log"]
smb_mapping:
enabled: true
var.paths: ["/opt/zeek/logs/current/smb_mapping.log"]
dce_rpc:
enabled: true
var.paths: ["/opt/zeek/logs/current/dce_rpc.log"]
EOF
# Zeek configuration for lateral movement detection
# Enable SMB, DCE-RPC, and Kerberos logging
cat >> /opt/zeek/share/zeek/site/local.zeek << 'EOF'
@load policy/protocols/smb
@load policy/protocols/conn/known-hosts
@load policy/protocols/conn/known-services
@load frameworks/intel/seen
EOF
sudo zeekctl deploy
ステップ 2:一般的なラテラルムーブメント手法の検知ルールを作成する
# Splunk SPL queries for lateral movement detection
# 1. Detect PsExec usage (new service creation on remote hosts)
# index=wineventlog EventCode=7045 ServiceName="PSEXESVC" OR ServiceName="*psexec*"
# | stats count by ComputerName, ServiceName, ImagePath
# | where count > 0
# 2. Detect Pass-the-Hash (Type 3 logon with NTLM)
# index=wineventlog EventCode=4624 LogonType=3 AuthenticationPackageName="NTLM"
# | where TargetUserName!="ANONYMOUS LOGON" AND TargetUserName!="$"
# | stats count dc(ComputerName) as unique_hosts by TargetUserName, IpAddress
# | where unique_hosts > 3
# 3. Detect RDP lateral movement (Type 10 logon from internal IPs)
# index=wineventlog EventCode=4624 LogonType=10
# | where cidrmatch("10.0.0.0/8", IpAddress) OR cidrmatch("192.168.0.0/16", IpAddress)
# | stats count dc(ComputerName) as rdp_hosts by TargetUserName, IpAddress
# | where rdp_hosts > 2
# Elastic SIEM detection rules (KQL)
# event.code: "4624" and winlog.event_data.LogonType: "3"
# and winlog.event_data.AuthenticationPackageName: "NTLM"
# and not winlog.event_data.TargetUserName: *$
# and source.ip: (10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)
# Sigma rules for lateral movement detection
# Install sigma and convert to target SIEM format
pip3 install sigma-cli
cat > lateral_movement_pth.yml << 'EOF'
title: Pass-the-Hash Lateral Movement Detection
id: f8d98d6c-7a07-4d74-b064-dd4a3c244528
status: experimental
description: Detects network logon with NTLM authentication to multiple hosts
logsource:
product: windows
service: security
detection:
selection:
EventID: 4624
LogonType: 3
AuthenticationPackageName: NTLM
filter:
TargetUserName|endswith: '$'
condition: selection and not filter
timeframe: 15m
count:
field: ComputerName
min: 3
group-by: TargetUserName
level: high
tags:
- attack.lateral_movement
- attack.t1550.002
EOF
# Convert Sigma rule to Splunk SPL
sigma convert -t splunk lateral_movement_pth.yml
# Convert to Elastic query
sigma convert -t elasticsearch lateral_movement_pth.yml
ステップ 3:Zeek によるネットワークレベルの検知
# Detect SMB lateral movement (admin$ and c$ share access)
cat /opt/zeek/logs/current/smb_mapping.log | \
zeek-cut ts id.orig_h id.resp_h path | \
grep -iE "(admin\$|c\$|ipc\$)" | \
sort -t$'\t' -k2 | uniq -c | sort -rn
# Detect hosts connecting to many internal hosts on port 445 (SMB spreading)
cat /opt/zeek/logs/current/conn.log | \
zeek-cut ts id.orig_h id.resp_h id.resp_p | \
awk '$4 == 445' | \
awk '{print $2}' | sort | uniq -c | sort -rn | head -10
# Detect WMI lateral movement (DCE-RPC to IWbemServices)
cat /opt/zeek/logs/current/dce_rpc.log | \
zeek-cut ts id.orig_h id.resp_h operation | \
grep -i "wbem\|wmi" | sort | uniq -c | sort -rn
# Detect RDP 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 == 3389 && $5 > 60' | \
sort -t$'\t' -k2 | head -20
# Detect Kerberos ticket-granting anomalies
cat /opt/zeek/logs/current/kerberos.log | \
zeek-cut ts id.orig_h id.resp_h client service success error_msg | \
grep -v "true" | head -20
# Custom Zeek script for lateral movement detection
sudo tee /opt/zeek/share/zeek/site/custom-detections/lateral-movement.zeek << 'ZEEKEOF'
@load base/frameworks/notice
@load base/frameworks/sumstats
module LateralMovement;
export {
redef enum Notice::Type += {
SMB_Lateral_Spread,
RDP_Lateral_Chain
};
const smb_host_threshold: count = 5 &redef;
const smb_time_window: interval = 15min &redef;
}
event zeek_init()
{
local r1 = SumStats::Reducer(
$stream="lateral.smb",
$apply=set(SumStats::UNIQUE)
);
SumStats::create([
$name="detect-smb-lateral",
$epoch=smb_time_window,
$reducers=set(r1),
$threshold_val(key: SumStats::Key, result: SumStats::Result) = {
return result["lateral.smb"]$unique + 0.0;
},
$threshold=smb_host_threshold + 0.0,
$threshold_crossed(key: SumStats::Key, result: SumStats::Result) = {
NOTICE([
$note=SMB_Lateral_Spread,
$msg=fmt("Host %s connected to %d SMB hosts in %s",
key$str, result["lateral.smb"]$unique, smb_time_window),
$identifier=key$str
]);
}
]);
}
event connection_state_remove(c: connection)
{
if ( c$id$resp_p == 445/tcp && c$id$resp_h in Site::local_nets )
{
SumStats::observe("lateral.smb",
[$str=cat(c$id$orig_h)],
[$str=cat(c$id$resp_h)]
);
}
}
ZEEKEOF
sudo zeekctl deploy
ステップ 4:ラテラルムーブメントの兆候を脅威ハンティングする
# Hunt for authentication anomalies in Windows logs
# Splunk query: Users authenticating from unusual source hosts
# index=wineventlog EventCode=4624 LogonType=3
# | stats values(IpAddress) as source_ips dc(IpAddress) as source_count by TargetUserName
# | where source_count > 5
# | sort -source_count
# Hunt for service accounts used interactively
# index=wineventlog EventCode=4624 (LogonType=2 OR LogonType=10)
# | where match(TargetUserName, "^svc-.*")
# | table _time ComputerName TargetUserName IpAddress LogonType
# Network flow analysis for lateral movement patterns
# Look for hosts that suddenly start communicating with many internal hosts
cat /opt/zeek/logs/current/conn.log | \
zeek-cut ts id.orig_h id.resp_h | \
awk '{
key = $2
targets[key][$3] = 1
}
END {
for (src in targets) {
count = 0
for (dst in targets[src]) count++
if (count > 20) print src, count
}
}' | sort -k2 -rn
# Detect credential dumping artifacts (large LSASS reads)
# Look for connections from hosts that suddenly pivot
cat /opt/zeek/logs/current/conn.log | \
zeek-cut ts id.orig_h id.resp_h id.resp_p orig_bytes | \
awk '$4 == 445 && $5 > 10000000' | sort -t$'\t' -k5 -rn
# Timeline analysis: map the attack path
# index=wineventlog (EventCode=4624 OR EventCode=7045)
# | eval stage=case(
# EventCode=4624 AND LogonType=3, "Network Logon",
# EventCode=4624 AND LogonType=10, "RDP Logon",
# EventCode=7045, "Service Creation"
# )
# | timechart span=5m count by stage
ステップ 5:自動対応と封じ込め
# SOAR playbook for lateral movement response (pseudocode)
# When lateral movement alert triggers:
# 1. Enrich the alert with context
# - Query AD for user group membership and role
# - Check if source IP is a known admin workstation
# - Look up recent vulnerability scan results for affected hosts
# 2. Automated containment actions
# Option A: Isolate the host via switch port shutdown
# ssh admin@switch "conf t; interface Gi1/0/5; shutdown"
# Option B: Quarantine via VLAN change (less disruptive)
# ssh admin@switch "conf t; interface Gi1/0/5; switchport access vlan 999"
# Option C: Block at firewall
sudo iptables -I FORWARD -s 10.10.5.23 -j DROP
# 3. Disable the compromised account
# PowerShell: Disable-ADAccount -Identity compromised_user
# 4. Force password reset
# PowerShell: Set-ADAccountPassword -Identity compromised_user -Reset
# 5. Collect forensic evidence before full containment
# velociraptor artifact collect Windows.KapeFiles.Targets --target BasicCollection
ステップ 6:検知ダッシュボードを作成する
# Elastic Kibana dashboard queries for lateral movement monitoring
# Panel 1: Authentication heatmap (source vs destination)
# Aggregation: Terms on source.ip (rows) and destination.ip (columns)
# Metric: Count of event.code:4624
# Panel 2: SMB connections between internal hosts
# Filter: destination.port:445 and source.ip:10.0.0.0/8
# Aggregation: Top 20 source IPs by unique destination count
# Panel 3: RDP sessions timeline
# Filter: destination.port:3389 and event.code:4624 and winlog.event_data.LogonType:10
# Visualization: Timeline by source.ip
# Panel 4: New service installations
# Filter: event.code:7045
# Aggregation: Terms on winlog.event_data.ServiceName
# Panel 5: Failed authentication spike detection
# Filter: event.code:4625
# Aggregation: Date histogram with anomaly detection
# Export Kibana dashboard
# curl -X GET "elastic-siem:5601/api/saved_objects/_export" \
# -H "kbn-xsrf: true" \
# -d '{"type":"dashboard","objects":[{"id":"lateral-movement-dashboard","type":"dashboard"}]}' \
# > lateral_movement_dashboard.ndjson
主な概念
| 用語 | 定義 |
|---|---|
| ラテラルムーブメント | 侵害されたシステムから別のシステムへネットワーク内を移動するために攻撃者が使用する手法を説明する MITRE ATT&CK の戦術(TA0008) |
| Pass-the-Hash(T1550.002) | 取得した NTLM パスワードハッシュを使用し、平文パスワードを知らずにリモートシステムへ認証すること |
| PsExec(T1569.002) | ターゲットシステム上に一時的なサービスを作成するリモートサービス実行ツール。イベント ID 7045 で検知可能 |
| 東西トラフィック | 内部システム間のネットワーク通信(内部ネットワークと外部ネットワーク間の南北トラフィックとは対照的) |
| 認証異常 | これまでアクセスしたことのないシステムにユーザーがログインするなど、認証パターンのベースラインからの逸脱 |
| Kerberoasting(T1558.003) | サービスアカウントの Kerberos サービスチケットを要求してオフラインで解読すること。イベント ID 4769 の異常から検知可能 |
ツールとシステム
- Zeek:ラテラルムーブメント分析用に SMB、Kerberos、DCE-RPC、接続ログを生成するネットワークセキュリティモニター
- Splunk/Elastic SIEM:企業全体の認証イベント、ネットワークフロー、サービス作成を相関分析するログ集約プラットフォーム
- Sigma:SIEM プラットフォーム間で移植可能なラテラルムーブメント検知ルールを記述するための、ベンダーに依存しない検知ルール形式
- Velociraptor:ラテラルムーブメントの連鎖に関与したホストから証拠を収集するエンドポイントフォレンジックツール
- BloodHound:攻撃者に悪用される前に、ラテラルムーブメントの潜在的な経路を特定する Active Directory 攻撃経路分析ツール
一般的なシナリオ
シナリオ:ランサムウェア攻撃者のラテラルムーブメントを検出する
コンテキスト:SOC が、午前 2 時にファイルサーバー(10.10.20.15)で PsExec サービスが作成されたというアラートを受信しました。このアラートを受けて、ラテラルムーブメントの調査が開始されます。組織では、Zeek によるネットワーク監視と、Windows イベントログの Splunk への転送を実施しています。
アプローチ:
- Splunk で 10.10.20.15 のイベント ID 7045(サービス作成)を検索し、PsExec の実行を確認して、送信元 IP(10.10.5.23)を特定する
- 10.10.5.23 の認証履歴を追跡する:イベント ID 4624、ログオンタイプ 3 を検索し、このホストが過去 1 時間に NTLM を使って 8 台のサーバーで認証されたことを確認する(Pass-the-Hash のパターン)
- 10.10.5.23 の Zeek conn.log を確認する:12 台の内部ホストへの SMB 接続(ポート 445)と、外部 IP への大容量ファイル転送を特定する
- 攻撃タイムラインを作成する:午前 1 時 15 分にフィッシングで最初の侵害、午前 1 時 25 分に認証情報をダンプ、午前 1 時 30 分から 2 時までに 8 台のサーバーへラテラルムーブメント
- 認証チェーンを追跡して、侵害されたすべてのホストを特定する:10.10.5.23 -> 10.10.20.15 -> 10.10.20.16 -> 10.10.20.17
- 特定したすべてのホストを VLAN 999 に隔離し、侵害されたアカウントを無効化して、外部 C2 IP をブロックすることで封じ込める
- タイムライン、影響を受けたホスト、検出のギャップを含む攻撃チェーン全体を報告する
注意点:
- 単一のアラートだけを調査し、すべてのホストにまたがるラテラルムーブメントの全経路を追跡しない
- 封じ込めを宣言する前に、侵害された各ホスト上の永続化の仕組みを確認しない
- ネットワークフローデータとの相関分析をせず、Windows イベントログだけに依存することで、Windows イベントを生成しないツールによるラテラルムーブメントを見逃す
- 通常の内部認証パターンのベースラインを確立せず、異常検出を不可能にする
出力形式
## Lateral Movement Investigation Report
**Case ID**: IR-2024-0312
**Initial Alert**: PsExec on 10.10.20.15 at 02:00 UTC
**Investigation Period**: 2024-03-15 01:00 to 03:00 UTC
### Attack Timeline
| Time (UTC) | Source | Destination | Technique | Evidence |
|------------|--------|-------------|-----------|----------|
| 01:15 | External | 10.10.5.23 | Initial Access (Phishing) | Email log + HTTP download |
| 01:25 | 10.10.5.23 | Local | Credential Dumping | LSASS access (Sysmon EID 10) |
| 01:32 | 10.10.5.23 | 10.10.20.15 | Pass-the-Hash (SMB) | EID 4624 Type 3 NTLM |
| 01:38 | 10.10.5.23 | 10.10.20.16 | PsExec | EID 7045 + Zeek SMB |
| 01:45 | 10.10.20.16 | 10.10.20.17 | RDP | EID 4624 Type 10 |
| 02:00 | 10.10.20.17 | 10.10.20.15 | PsExec (triggered alert) | EID 7045 |
| 02:10 | 10.10.5.23 | 203.0.113.50 | Data Exfiltration | Zeek conn.log 2.3 GB |
### Affected Systems
- 10.10.5.23 (workstation-045) - Initial compromise
- 10.10.20.15 (file-server-01) - Data accessed
- 10.10.20.16 (app-server-02) - Pivoted through
- 10.10.20.17 (db-server-01) - Final target
### Detection Gaps
1. Initial phishing email not blocked by email gateway
2. Credential dumping not detected (no LSASS monitoring)
3. 30-minute gap between first lateral movement and alert
コメント
Markdown 対応