| name | detecting-lateral-movement-in-network |
| description | 通过分析身份验证日志、网络流量、SMB 流量和 RDP 会话,使用 Zeek、Velociraptor 和 SIEM 关联规则,识别企业网络中的横向移动技术,检测攻击者在系统间的移动行为。
|
| domain | cybersecurity |
| subdomain | network-security |
| tags | ["network-security","lateral-movement","threat-detection","siem","pass-the-hash"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
检测网络中的横向移动
适用场景
- 监控企业网络中的入侵后横向移动(lateral movement)模式(哈希传递(pass-the-hash)、RDP 跳转、PSExec)
- 为 MITRE ATT&CK 横向移动技术(T1021、T1570)构建 SIEM 检测规则和告警
- 通过分析身份验证模式和内部主机间的网络连接,调查疑似入侵事件
- 狩猎异常的东西向流量(east-west traffic)模式,识别攻击者在网络中的横穿行为
- 验证网络分段和访问控制是否有效限制横向移动路径
不适用场景:替代终端检测与响应(EDR)工具;仅监控南北向流量而忽略内部流量;在没有正常内部通信模式基线的情况下使用。
前置条件
- 在内部关键节点部署了网络安全监控(Zeek、Suricata 或网络 TAP)
- SIEM 平台(Splunk、Elastic、Microsoft Sentinel)收集 Windows 安全事件日志、DNS 和流量数据
- 配置了 Windows 事件日志转发,收集安全事件(4624、4625、4648、4672、4768、4769)
- 建立了正常内部身份验证和连接模式的基线
- 了解 MITRE ATT&CK 横向移动战术(TA0008)
工作流程
步骤 1:配置横向移动检测的日志收集
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
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:为常见横向移动技术构建检测规则
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
sigma convert -t splunk lateral_movement_pth.yml
sigma convert -t elasticsearch lateral_movement_pth.yml
步骤 3:使用 Zeek 进行网络层检测
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
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
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
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
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
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()
{
r1 = SumStats::Reducer(
=,
=(SumStats::UNIQUE)
);
SumStats::create([
=,
=smb_time_window,
=(r1),
(key: SumStats::Key, result: SumStats::Result) = {
result[] + 0.0;
},
=smb_host_threshold + 0.0,
(key: SumStats::Key, result: SumStats::Result) = {
NOTICE([
=SMB_Lateral_Spread,
=(,
key, result[], smb_time_window),
=key
]);
}
]);
}
event connection_state_remove(c: connection)
{
( c$ == 445/tcp && c$ Site::local_nets )
{
SumStats::observe(,
[=(c$)],
[=(c$)]
);
}
}
ZEEKEOF
zeekctl deploy
步骤 4:威胁狩猎横向移动指标
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
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
步骤 5:自动响应与遏制
sudo iptables -I FORWARD -s 10.10.5.23 -j DROP
步骤 6:构建检测仪表板
核心概念
| 术语 | 定义 |
|---|
| 横向移动(Lateral Movement) | MITRE ATT&CK 战术(TA0008),描述攻击者在网络中从一个被入侵系统移动到另一个系统的技术 |
| 哈希传递(Pass-the-Hash,T1550.002) | 使用捕获的 NTLM 密码哈希向远程系统进行身份验证,无需知道明文密码 |
| PsExec(T1569.002) | 远程服务执行工具,在目标系统上创建临时服务,可通过事件 ID 7045 检测 |
| 东西向流量(East-West Traffic) | 内部系统间的网络通信(相对于内外部网络间的南北向流量) |
| 身份验证异常 | 偏离基线身份验证模式的行为,例如用户登录到以前从未访问过的系统 |
| Kerberoasting(T1558.003) | 请求服务账户的 Kerberos 服务票证并离线破解,可通过事件 ID 4769 异常检测 |
工具与系统
- Zeek:网络安全监控器,生成 SMB、Kerberos、DCE-RPC 和连接日志,用于横向移动分析
- Splunk/Elastic SIEM:日志聚合平台,用于关联企业内的身份验证事件、网络流量和服务创建
- Sigma:厂商无关的检测规则格式,用于编写可跨 SIEM 平台移植的横向移动检测规则
- Velociraptor:终端取证工具,用于从横向移动链中涉及的主机收集证据
- BloodHound:活动目录攻击路径分析工具,在攻击者利用前识别潜在的横向移动路径
常见场景
场景:检测勒索软件操作员的横向移动
背景:SOC 在凌晨 2:00 收到文件服务器(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 登录,发现该主机在过去一小时内使用 NTLM 向 8 台服务器进行了身份验证(哈希传递模式)
- 检查 10.10.5.23 的 Zeek conn.log:识别出到 12 台内部主机的 SMB 连接(端口 445)以及到外部 IP 的大量文件传输
- 构建攻击时间线:凌晨 1:15 通过网络钓鱼完成初始入侵,1:25 转储凭据,1:30-2:00 横向移动到 8 台服务器
- 通过追踪身份验证链识别所有被入侵主机:10.10.5.23 -> 10.10.20.15 -> 10.10.20.16 -> 10.10.20.17
- 将所有识别出的主机隔离到 VLAN 999、禁用被入侵账户、封锁外部 C2 IP
- 报告完整的攻击链,包括时间线、受影响主机和检测盲点
常见陷阱:
- 只调查单一告警,而不追踪所有主机上完整的横向移动链
- 在宣布遏制完成前,不检查每台被入侵主机上的持久化机制
- 仅依赖 Windows 事件日志,不关联网络流数据,导致遗漏通过不产生 Windows 事件的工具进行的横向移动
- 未建立正常内部身份验证模式的基线,导致无法进行异常检测
输出格式
## 横向移动调查报告
**案例 ID**:IR-2024-0312
**初始告警**:10.10.20.15 上的 PsExec,时间 02:00 UTC
**调查周期**:2024-03-15 01:00 至 03:00 UTC
### 攻击时间线
| 时间(UTC) | 来源 | 目标 | 技术 | 证据 |
|------------|--------|-------------|-----------|----------|
| 01:15 | 外部 | 10.10.5.23 | 初始访问(网络钓鱼) | 邮件日志 + HTTP 下载 |
| 01:25 | 10.10.5.23 | 本地 | 凭据转储 | LSASS 访问(Sysmon EID 10) |
| 01:32 | 10.10.5.23 | 10.10.20.15 | 哈希传递(SMB) | EID 4624 类型 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 类型 10 |
| 02:00 | 10.10.20.17 | 10.10.20.15 | PsExec(触发告警) | EID 7045 |
| 02:10 | 10.10.5.23 | 203.0.113.50 | 数据渗出 | Zeek conn.log 2.3 GB |
### 受影响系统
- 10.10.5.23(workstation-045)- 初始入侵
- 10.10.20.15(file-server-01)- 数据被访问
- 10.10.20.16(app-server-02)- 横穿节点
- 10.10.20.17(db-server-01)- 最终目标
### 检测盲点
1. 初始网络钓鱼邮件未被邮件网关拦截
2. 凭据转储未被检测(无 LSASS 监控)
3. 首次横向移动到告警之间存在 30 分钟间隔