Sysmon 与 Windows 日志聚合

自带事件日志撑不起入侵检测。缺陷有两头:

最后更新 2026-10-09版本 v1.0维护 DigiForensics查看历史 0

关键词:Sysmon、事件聚合、Windows Event Forwarding、进程创建、配置驱动 难度:进阶 前置知识:事件日志结构(03)、注册表取证(02)

一、概述

自带事件日志撑不起入侵检测。缺陷有两头:

  1. 默认什么都不记。4688(进程创建)要先开「审计进程创建」,而 Windows 默认不开。命令行、哈希、父子链,一样都没有。
  2. 记了就留不住。日志定长循环覆盖,Security 默认 20 MB,活动多的机器几小时就冲干净。

Sysmon(Sysinternals 的工具)以驱动形式常驻内核,把进程创建(带完整命令行与哈希)、网络连接、DLL 加载、注册表操作写进独立通道 Microsoft-Windows-Sysmon/Operational。

这一篇解决三件事:它记什么、怎么配(配错等于没开)、怎么集中采集(把易覆盖的日志变成远端副本)。

维度 原生事件日志 Sysmon
进程命令行 4688 需开启审计,且参数可能截断 默认记录,完整命令行
进程哈希 无 SHA-1/SHA-256/MD5/IMPHASH
父子关系 需交叉查询 每条自带 ParentImage/ParentCommandLine
网络连接 需开启审计防火墙规则 默认记录(IPv4/IPv6/DNS)
持久化位置 无对应事件 服务、计划任务、启动项、驱动
保留策略 20 MB 循环 可配置,且支持远程转发

在取证流程中的位置:本篇横跨部署期与取证期两个阶段,这一点和同板块其他文章不同。取证期它是一次性证据解析(导出 .evtx 后离线分析,与 事件日志深度分析 的方法完全一致);部署期它是一套需要提前落地的采集设施,错过事发时点就永远补不回来。所以如果检材上没有 Sysmon 通道,本篇第三章第 3 步(确认是否部署)会在 30 秒内给出阴性结论,然后你在第四章第 1 组里找替代路径——这时 Sysmon 相关的所有结论都不成立,必须换成原生日志加 MFT 加 Prefetch 的组合。上游依赖是事件日志的解析基础与注册表持久化位置(注册表取证),Sysmon 事件 12/13/14 的判读直接建立在 Run 键与服务键的知识上。

本篇处理的证据形态,是一个通道加一份 XML 配置:

证据 位置或字段 说明
事件通道 Microsoft-Windows-Sysmon/Operational 默认不启用,要先装 Sysmon 再用 -i 写入注册表
单条事件 EventData 里的 RuleName、UtcTime、ProcessGuid、Image、CommandLine、Hashes、ParentImage、ParentCommandLine、User、LogonId ProcessGuid 是把同一进程的多条事件串起来的关键
配置文件 Sysmon64.xml 或 Sysmon.xml 决定 <EventFiltering> 里哪些 <ProcessCreate onmatch="include"> 生效
转发配置 订阅管理器里的 WEF 订阅,落地在 .evtx 汇聚文件 MaxSize、MaxEventTime、是否启用
版本标识 事件里的 Version 字段与配置里的 schemaVersion 报告里必须写明,不同版本事件集不同

配置文件是本篇最容易出事的地方:一个 <ProcessCreate> 里既能写 <Image path="...">,也能写 <CommandLine condition="contains"> 和 <ParentImage>,条件之间是与关系,<Image> 支持 is / contains / begin with / end with 及 exclude 变体。排除项写错一个进程名,就等于给它开了一扇免检门——第二章会把这套匹配语义讲透。

本篇能回答什么:某个时间窗内系统上执行过哪些程序、命令行与哈希是什么、父子链是否合理、DNS 与出站连接指向哪里、注册表持久化位置被写过什么、文件创建时间是否被篡改、某个进程是否被远程线程注入。

本篇不能回答什么:Sysmon 没有部署就是没有,此时所有阴性结论都不成立,而且原生日志无法补上缺失的部分——4688 不带哈希,SRUM 的粒度与保留期都不同。Sysmon 是存在性日志:它只记录"配置范围内发生过的事件",配置里被 <exclude> 掉的对象等于不存在,而且被排除的记录不会留痕,你事后无法判断某类事件是没发生还是被过滤了。日志被清空或被配置改成不记录后,仍会继续产生"正常"的新事件——只有时间戳断层,没有"清空"这个事件本身。另外命令行与哈希证明的是"这样一件程序跑起来了",证明不了它做了什么,后续行为要看文件、注册表、网络三类事件;GrantedAccess 判读也不能替代对目标进程内存的实际分析。

读者前提:需要先掌握 .evtx 的导出与字段解析(能读 EventData 的 XML 结构、知道 Properties 集合只给值不给字段名这件事),否则拿到 Sysmon 日志也只能干瞪眼;需要理解 LogonId 与 ProcessGuid 这两个关联字段的含义——前者把事件挂到登录会话上,后者把同一进程的多条事件串起来,这一步做不对,父子链和注入结论全部断裂;还需要知道审计策略与 Sysmon 过滤器是两套独立的开关,前者管原生日志,后者管 Sysmon,两者不通。

二、核心原理

2.1 Sysmon 的工作方式

sysmon.exe(用户态 CLI) → 发送配置 XML → SysmonDrv.sys(内核驱动)
                                              ↓ ETW
                        Microsoft-Windows-Sysmon/Operational.evtx
  • 驱动在系统调用层捕获行为;用户态进程本身是攻击面(rootkit 可挂钩它)。
  • 配置是 XML,经 sysmon.exe -c config.xml 下发。配置变更通常需要重启(是否支持热重载以实际版本为准)。
  • 日志落在 C:\Windows\System32\winevt\Logs\Microsoft-Windows-Sysmon%4Operational.evtx(注意 %4 是通道分隔符的编码,勿漏)。

推论只有一条,但很实用:Sysmon 日志和 Security 是两个独立文件。wevtutil cl Security 清不掉 Sysmon 日志。只清了 Security 的攻击者若没意识到 Sysmon 存在,就等于把最高质量的那份证据留在了原地。

2.2 ★ 事件 ID 清单

Sysmon 沿用 WMI 事件编号(1–25),但不是每个编号都会产生数据,集合还随版本变。下面按取证价值分类。

报告中必须写明所用的 Sysmon 版本与 schemaVersion。

A. 进程与线程(最核心)

ID 事件 关键字段 取证价值
1 进程创建 Image、CommandLine、ParentImage、ParentCommandLine、User、Hashes、LogonId ★★★ 一切执行的完整记录,含命令行与哈希
2 文件创建时间被修改 Image、NewTime、PreviousTime ★★★ 时间戳篡改的直接证据(timestomp)
3 网络连接 Image、DestinationIp/Port/Hostname、Protocol、Initiated ★★★ 出站历史,含 Initiated=false 的入站
8 CreateRemoteThread SourceImage、TargetImage、StartModule ★★★ 进程注入(DLL 注入、进程镂空)
10 ProcessAccess SourceImage、TargetImage、GrantedAccess、CallTrace ★★ 凭据窃取:LSASS 被 PROCESS_VM_READ 打开
15 进程流哈希 Image、Hashes、Length ★★★ 内存加载 PE(fileless)
22 DNS 查询 QueryName、QueryResults、Image ★★ 域名级 C2 证据

B. 文件、镜像与内核

ID 事件 取证价值
7 映像加载 ★★★ DLL 注入/侧载;Signed=false + 位于 Temp 是强信号
11 / 23 文件创建 / 文件删除 ★★ 落地与清理痕迹(TargetFilename)
12 / 13 / 14 注册表对象创建 / 值设置 / 键重命名 ★★★ 持久化检测(Run 键、服务注册)
6 驱动加载 ★★★ 加载未签名驱动 = rootkit 强信号
5 进程终止 ★ 存活时长(短命进程可能是一次性利用)
17 / 18 / 19 / 20 / 21 WMI 事件 / 命名管道 / 永久事件订阅 ★★ 域内横向与隐蔽信道
24 剪贴板内容更改 ★ 密码搬运行为

2.3 与原生日志的互补关系

没有任何单一工件能证明入侵。Sysmon 的价值在与原生日志互补:

场景 只有原生日志 只有 Sysmon 两者结合
进程执行 4688 未开启则无;开启也缺哈希 完整命令行 + 哈希 可哈希比对威胁库
登录 4624 有 TargetLogonId 事件 1 也带 LogonId 用 LogonId 把进程归属到具体登录会话
服务持久化 7045(安装时) 事件 12/13(注册表写入时) 两条独立时间线互证
文件落地 无 事件 11 与 Prefetch(05)交叉
时间戳篡改 MFT 可见但无上下文 事件 2 直接报告新旧时间 强证据
网络外联 需开审计 事件 3 + 22 与防火墙、SRUM(09)对照

LogonId 是整篇的关联枢纽。4624 告诉你「用户 X 在 23:12 以类型 3 登录,LogonId=0x3E7」,Sysmon 事件 1 告诉你「这个 LogonId 下启动了哪些进程」。把两者按 LogonId 串起来,得到的是一条完整的攻击会话。

2.4 集中化采集:为什么必须转发

单机 Sysmon 日志照样会被覆盖——上限有限,而攻击者只要知道通道名就能清。

所以企业环境的做法是双写:

Sysmon 驱动
    ├─→ 本地 .evtx(缓冲,便于单机取证)
    └─→ Windows Event Forwarding(WEF)→ 远程订阅源(日志服务器 / SIEM)

WEF 是 Windows 内置的转发机制:日志通道订阅 Microsoft-Windows-Sysmon/Operational,经 WinRM 推给远程 Collector,终端上不用装 EDR agent。

取证上的意义很直接:只要日志已经推到远端,本地被清空也不影响结论。


三、操作步骤

3.1 第 1 步:先确认系统是否部署了 Sysmon

这一步必须最先做。绝大多数终端默认没有 Sysmon,查不到不是异常。

# 活系统:查通道是否存在及其上限
Get-WinEvent -ListLog 'Microsoft-Windows-Sysmon/Operational' -ErrorAction SilentlyContinue |
  Select LogName, RecordCount, FileSize, MaximumSizeInBytes, LogMode
# 离线:从镜像定位日志、驱动与用户态程序
fls -o 2048 -r -p /work/DigiForensics.dd | grep -i 'Sysmon'
# → /Windows/System32/sysmon64.exe            (Win8+ 无 32 位版)
# → /Windows/System32/drivers/SysmonDrv.sys
# → /Windows/System32/winevt/Logs/Microsoft-Windows-Sysmon%4Operational.evtx
检查结果 结论
.evtx + 驱动 + 服务注册项齐全 已部署,继续 3.3
只有 .evtx 无驱动文件 曾部署后卸载,日志残留仍可分析
全无 该机从未部署 Sysmon,改用 4688 / EDR / 其他工件

3.2 第 2 步:配置 Sysmon(现场部署的正确做法)

配置不当等于白开:默认配置只记事件 1 和 6,网络、注册表、DNS 全无。

<Sysmon schemaVersion="4.60">
  <EventFiltering>
    <ProcessCreate onmatch="include">
      <CommandLine condition="is not contains">\WmiPrvSE.exe</CommandLine>
    </ProcessCreate>
    <NetworkConnect onmatch="exclude">
      <DestinationIp condition="is any of">127.0.0.1;192.168.0.0/16;10.0.0.0/8;172.16.0.0/12;fe80::/10;::1</DestinationIp>
    </NetworkConnect>
    <FileCreate onmatch="exclude">
      <TargetFilename condition="is any of">%SystemRoot%\Prefetch\*;%SystemRoot%\Temp\*</TargetFilename>
    </FileCreate>
    <RegistryEvent onmatch="exclude">
      <TargetObject condition="is any of">\REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\*</TargetObject>
    </RegistryEvent>
  </EventFiltering>
  <Hashes>sha256,sha1,md5,imphash</Hashes>
  <ProcessAccess onmatch="exclude">
    <GrantedAccess condition="is any of">0x1000;0x1010;0x100000;0x100010;0x100020;0x100038</GrantedAccess>
  </ProcessAccess>
  <FileCreateStreamHash>on</FileCreateStreamHash>
  <DNSQuery onmatch="exclude">
    <QueryName condition="is any of">\*.microsoft.com;*.windowsupdate.com;*.msftconnecttest.com</QueryName>
  </DNSQuery>
</Sysmon>
字段 作用 建议
EventFiltering 各事件类型的包含/排除规则 必配。不配则全是系统噪声,硬盘几天就满
Hashes 记录哪些哈希 sha256,sha1,md5,imphash 全开,匹配不同威胁库
ProcessAccess 的 GrantedAccess 排除正常查询权限 排除 0x1010(VM_READ|QUERY)之类,否则真信号被淹没
FileCreateStreamHash 计算内存流哈希 on —— fileless 只能靠这个抓
DNSQuery DNS 查询日志 开,但排除微软域名降噪
sysmon64.exe -accepteula -i Sysmon.xml     # 安装并加载配置
sysmon64.exe -c Sysmon.xml                 # 更改配置(部分版本需重启)
sysmon64.exe -d                            # 卸载(先归档日志!)
sysmon64.exe -h                            # 版本与支持的 schema
sysmon64.exe -z                            # 检查配置是否被 hash 锁定
wevtutil sl Microsoft-Windows-Sysmon/Operational /ms:268435456   # 调大到 256 MB

⚠️ 不调大日志上限,繁忙终端的 Sysmon 日志同样会被循环覆盖。

3.3 第 3 步:解析 Sysmon 日志

# 3.3.1 转 CSV:EventData 字段名成列,便于统计
EvtxECmd.exe -f C:\evidence\Sysmon.evtx --csv C:\evidence\sysmon_out
# → Sysmon_Operational.csv,列为 TimeCreated / Id / Image / CommandLine /
#   ParentImage / User / Hashes / TargetFilename / DestinationIp ...

# 3.3.2 活系统直查:★ 用 ToXml 按字段名取(见第 03 篇)
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1} -MaxEvents 5000 |
  ForEach-Object {
    [xml]$x = $_.ToXml(); $d=@{}; $x.Event.EventData.Data | %{ $d[$_.Name]=$_.'#text' }
    [pscustomobject]@{ Time=$_.TimeCreated; Image=$d['Image']; Cmd=$d['CommandLine'];
                       Parent=$d['ParentImage']; Hashes=$d['Hashes'] }
  } | Format-Table -AutoSize -Wrap

核心查询场景(CSV 版,列号以实际表头为准):

安全验证 当前请求需要先完成一次滑块验证。