L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Productivité · SKILL.md

detecting-lateral-movement-in-network

detecting-lateral-movement-in-network

通过分析身份验证日志、网络流量、SMB 流量和 RDP 会话,使用 Zeek、Velociraptor 和 SIEM 关联规则,识别企业网络中的横向移动技术,检测攻击者在系统间的移动行为。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

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:配置横向移动检测的日志收集

# 需收集的 Windows 事件日志(通过 WEF 或代理):
# 安全日志:
#   4624 - 成功登录(类型 3=网络,类型 10=远程交互)
#   4625 - 登录失败
#   4648 - 使用显式凭据登录(RunAs、PsExec)
#   4672 - 分配了特殊权限(管理员登录)
#   4768 - Kerberos TGT 请求
#   4769 - Kerberos 服务票证请求
#   4776 - NTLM 身份验证(凭据验证)
# 系统日志:
#   7045 - 安装了新服务(PsExec 指标)
#   7036 - 服务启动/停止

# 配置 Windows 事件转发(WEF)订阅
# 在收集服务器上(PowerShell):
# wecutil cs lateral-movement-subscription.xml

# 用于 Windows 事件日志传输的 Filebeat 配置
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 横向移动检测配置
# 启用 SMB、DCE-RPC 和 Kerberos 日志
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 查询

# 1. 检测 PsExec 使用(在远程主机上创建新服务)
# index=wineventlog EventCode=7045 ServiceName="PSEXESVC" OR ServiceName="*psexec*"
# | stats count by ComputerName, ServiceName, ImagePath
# | where count > 0

# 2. 检测哈希传递(NTLM 类型 3 登录)
# index=wineventlog EventCode=4624 LogonType=3 AuthenticationPackageName="NTLM"
# | where TargetUserName!="ANONYMOUS LOGON" AND TargetUserName!="quot;
# | stats count dc(ComputerName) as unique_hosts by TargetUserName, IpAddress
# | where unique_hosts > 3

# 3. 检测 RDP 横向移动(内网 IP 的类型 10 登录)
# 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 检测规则(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 规则
# 安装 sigma-cli 并转换为目标 SIEM 格式
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: '#x27;
    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 规则转换为 Splunk SPL
sigma convert -t splunk lateral_movement_pth.yml

# 转换为 Elastic 查询
sigma convert -t elasticsearch lateral_movement_pth.yml

步骤 3:使用 Zeek 进行网络层检测

# 检测 SMB 横向移动(访问 admin$ 和 c$ 共享)
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#x27;\t' -k2 | uniq -c | sort -rn

# 检测在端口 445 上连接大量内部主机的主机(SMB 扩散)
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

# 检测 WMI 横向移动(DCE-RPC 到 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

# 检测内部主机间的 RDP 连接
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#x27;\t' -k2 | head -20

# 检测 Kerberos 票证授予异常
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

# 用于横向移动检测的自定义 Zeek 脚本
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:威胁狩猎横向移动指标

# 狩猎 Windows 日志中的身份验证异常
# Splunk 查询:从异常源主机进行身份验证的用户
# 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

# 狩猎以交互方式使用的服务账户
# index=wineventlog EventCode=4624 (LogonType=2 OR LogonType=10)
# | where match(TargetUserName, "^svc-.*")
# | table _time ComputerName TargetUserName IpAddress LogonType

# 横向移动模式的网络流分析
# 查找突然与大量内部主机通信的主机
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

# 检测凭据转储痕迹(大量 LSASS 读取)
# 查找突然横穿的主机的连接
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#x27;\t' -k5 -rn

# 时间线分析:绘制攻击路径
# 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 剧本(伪代码)
# 当横向移动告警触发时:

# 1. 用上下文信息丰富告警
# - 查询 AD 获取用户组成员资格和角色
# - 检查源 IP 是否为已知管理员工作站
# - 查找受影响主机的近期漏洞扫描结果

# 2. 自动遏制操作
# 选项 A:通过交换机端口关闭隔离主机
# ssh admin@switch "conf t; interface Gi1/0/5; shutdown"

# 选项 B:通过 VLAN 变更隔离(影响较小)
# ssh admin@switch "conf t; interface Gi1/0/5; switchport access vlan 999"

# 选项 C:在防火墙层面封锁
sudo iptables -I FORWARD -s 10.10.5.23 -j DROP

# 3. 禁用被入侵账户
# PowerShell: Disable-ADAccount -Identity compromised_user

# 4. 强制重置密码
# PowerShell: Set-ADAccountPassword -Identity compromised_user -Reset

# 5. 完全遏制前收集取证证据
# velociraptor artifact collect Windows.KapeFiles.Targets --target BasicCollection

步骤 6:构建检测仪表板

# Elastic Kibana 横向移动监控仪表板查询

# 面板 1:身份验证热图(源与目标)
# 聚合:源 IP(行)和目标 IP(列)的 Terms 聚合
# 指标:event.code:4624 的计数

# 面板 2:内部主机间的 SMB 连接
# 过滤:destination.port:445 and source.ip:10.0.0.0/8
# 聚合:按唯一目标数排序的前 20 个源 IP

# 面板 3:RDP 会话时间线
# 过滤:destination.port:3389 and event.code:4624 and winlog.event_data.LogonType:10
# 可视化:按 source.ip 的时间线

# 面板 4:新服务安装
# 过滤:event.code:7045
# 聚合:winlog.event_data.ServiceName 的 Terms 聚合

# 面板 5:登录失败峰值检测
# 过滤:event.code:4625
# 聚合:带异常检测的日期直方图

# 导出 Kibana 仪表板
# 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

核心概念

术语定义
横向移动(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。

方法:

  1. 在 Splunk 中查询 10.10.20.15 上的事件 ID 7045(服务创建),确认 PsExec 执行并识别源 IP(10.10.5.23)
  2. 追踪 10.10.5.23 的身份验证历史:查找事件 ID 4624 类型 3 登录,发现该主机在过去一小时内使用 NTLM 向 8 台服务器进行了身份验证(哈希传递模式)
  3. 检查 10.10.5.23 的 Zeek conn.log:识别出到 12 台内部主机的 SMB 连接(端口 445)以及到外部 IP 的大量文件传输
  4. 构建攻击时间线:凌晨 1:15 通过网络钓鱼完成初始入侵,1:25 转储凭据,1:30-2:00 横向移动到 8 台服务器
  5. 通过追踪身份验证链识别所有被入侵主机:10.10.5.23 -> 10.10.20.15 -> 10.10.20.16 -> 10.10.20.17
  6. 将所有识别出的主机隔离到 VLAN 999、禁用被入侵账户、封锁外部 C2 IP
  7. 报告完整的攻击链,包括时间线、受影响主机和检测盲点

常见陷阱:

  • 只调查单一告警,而不追踪所有主机上完整的横向移动链
  • 在宣布遏制完成前,不检查每台被入侵主机上的持久化机制
  • 仅依赖 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 分钟间隔
Skills enregistrées