1. 为什么偏偏是这三件套:组合逻辑先说清楚
做恶意软件分析这行的人,工具箱里多少都攒过一堆所谓“神器”。可真正到了应急响应现场,你会发现大部分花里胡哨的扫描器根本救不了你,反而微软官方这套免费的 Sysinternals 工具,才是被反复验证过的硬通货。尤其当你把 Process Monitor、Autoruns、Process Explorer 这三样组合起来用,几乎可以覆盖 Windows 恶意样本分析 80% 以上的日常需求。这篇文章就是我整理 Sysinternals 学习笔记和实战复盘时,觉得最值得先讲透的几个核心思路。
先别急着下工具,我们把“恶意软件分析”这五个字拆开看。一个样本落地到 Windows 系统上,无非要回答三个问题:它是什么?它干了什么?它靠什么活下来?静态工具比如杀软引擎、PE 分析器能回答第一个问题,但行为层面的“干了什么”和持久化层面的“怎么活下来”,恰恰是静态分析很难触及的盲区。Sysinternals 三件套的价值就在这里,它们分别盯着行为、启动项和运行中进程这三个维度,正好把“干了什么”和“怎么活下来”补全了。
有朋友可能会说,个把工具不也能看行为吗?确实,很多终端产品自带行为监控,但它们的问题是“黑盒输出”——告诉你发现了可疑行为,却不告诉你为什么。Sysinternals 的工具全部是“白盒”的,你能看到每一次文件操作、注册表写入、网络连接、线程栈调用,甚至可以精确到哪个进程拉起了哪个进程、哪个 DLL 被加载到了哪块内存。对一个想把样本分析明白、而不是只想知道“中没中毒”的人来说,这种颗粒度的信息几乎是不可替代的。
组合使用还有一个容易被忽略的好处:互证。单独看 Process Monitor 抓到的注册表写入,你可能无法判断这是样本行为还是正常软件行为;但把 Autoruns 的启动项列表拉出来对照,发现 Run 键下多了一条指向 Temp 目录的可执行文件,证据链就闭环了。这就是我理解的“组合拳”含义,不是三个工具轮流用一遍,而是让它们互相补充、互相验证。
这一篇笔记,我会按“先看行为、再查持久化、最后深挖进程”的顺序来写,每个工具讲清楚关键配置、读数据的思路和容易踩坑的地方,最后用一个完整流程把三件套串起来。
2. Process Monitor:给恶意程序装一个行车记录仪
2.1 学会的第一件事:过滤规则先于捕获
Process Monitor(简称 Procmon)的底层原理是借助内核态驱动实时监听文件系统、注册表、网络、进程与线程的活动。它的强项不是“记录得多”,而是“让你能在海量事件里快速锁定一条可疑链路”。很多初学者第一次打开 Procmon,点一下 Capture,几十秒就能攒下几十万条事件,然后整个人就懵了。这是 Procmon 最经典的新手陷阱。
正确做法是:先设计过滤规则,再开始捕获。比如我拿到一个可疑样本,通常会先把进程名和路径写进过滤条件。操作路径在菜单栏的 Filter -> Filter,弹出的对话框里可以组合多条条件。我常用的第一组规则是:
- Process Name 是 样本进程名(或者 Path 包含样本所在目录)
- Operation 是 CreateFile、RegSetValue、RegCreateKey、TCP Send、TCP Receive 这类能反映“行为意图”的操作
- Result 排除 SUCCESS,只看 ACCESS DENIED 和 BUFFER OVERFLOW 这类失败事件
为什么不直接全量抓?因为捕获事件数量太大会导致 Procmon 在内存里丢事件,尤其是高 IO 场景下,丢的往往正是关键操作。过滤之后的日志量小一个数量级,分析起来轻松得多。
Procmon 还有个细节我每次都会提醒自己:系统自带的 svchost.exe、lsass.exe 这类进程在捕获里会大量制造噪音。如果样本没有明显的进程注入行为,可以先在过滤里把这几个进程名排除掉,等主线跑完再针对性补看。
2.2 读日志的三个重要字段和两个细微线索
一旦捕获完成,Procmon 主界面就是一个实时刷新的表格,默认列包括 Time of Day、Process Name、PID、Operation、Path、Result、Detail。分析时我最关注三个字段:Operation、Path、Result。
Path 是灵魂。如果看到 CreateFile 指向 C:\Users\Public\Temp\a.exe,紧接着 RegSetValue 写到 HKCU\Software\Microsoft\Windows\CurrentVersion\Run,那么行为路径已经很清楚:释放文件、写自启动,典型的恶意软件执行链。
Result 也很有讲究。很多人只看 SUCCESS,忽略 ACCESS DENIED。实际上恶意软件经常会在不拥有管理员权限时尝试写入只读位置,然后降级到用户目录继续写。这种“尝试->失败->换路径”的过程,往往能揭示样本的权限判断逻辑,对判断样本是否尝试提权或者是否具备 UAC 绕过意图很有帮助。
两个细微线索容易被忽略。第一个是 Detail 列里的 Stack 按钮,选中任意事件后工具栏的 Stack 按钮会亮起,点击后可以看到这个操作是由哪个模块发起的。如果 CreateFile 的调用栈里出现了一个非系统 DLL,那就说明这个“文件操作”不是进程主程序发起的,而是某个被注入的模块在操作,这是一个非常强烈的可疑信号。第二个是进程树视图,Procmon 菜单栏里 Tools -> Process Tree(快捷键 Ctrl+T),这个视图会按父子关系展示所有进程,并且左侧可以直接缩放到某条事件链对应的进程和父进程。
2.3 Boot Logging:捕获开机早期的行为
有些恶意软件存活在系统启动早期,普通登录后再开 Procmon 已经来不及。Procmon 内置的 Boot Logging 功能就是为这种场景准备的。勾选 Options -> Enable Boot Logging,设置好日志路径,重启后 Procmon 驱动程序会在系统启动阶段就开始记录事件,再次登录后 Procmon 会提示你保存本轮启动日志。
这里我要特别说一个实际经验:Boot Logging 生成的日志文件默认放在 C:\Windows\System32 下,文件格式是 .pml,通常体积非常巨大。分析这类日志时,别忘了先用过滤把系统 PID 4(System 进程)产生的初始化噪音去掉。很多恶意服务在启动阶段的动作,在过滤掉 System 噪音后,剩下的条目其实非常有限,一眼就能看出异常。
另外,Procmon 有一个偏向实操的选项:Options -> Filter -> 启用 “Enable Advanced Output”。打开之后日志会额外记录操作发生时的线程 ID、会话 ID、用户名称和加载图片路径等信息,取证分析阶段这些字段能帮你快速定位样本是在哪个用户会话下执行的。
3. Autoruns:揪出恶意软件的“起床闹钟”
3.1 别只盯 Run 键:Autoruns 到底扫了哪些位置
持久化机制是恶意软件能不能在重启后存活的关键。很多人第一反应是看注册表 Run 键,但真实世界的恶意软件早就不满足于只写 Run 键了。Autoruns 这个工具的价值,在于它把所有可能的自启动位置全部枚举出来,并且按类型分页签展示。
全量扫描后,你会看到这些页签(我按实际排查频率排个序):
- Logon:登录相关的启动项,包括 HKLM/HKCU 下的 Run、RunOnce、启动文件夹,以及 Winlogon Shell、Userinit 等位置
- Services:服务注册和当前加载的服务,恶意驱动和服务大多藏在这里
- Scheduled Tasks:计划任务,越来越多的攻击者选择这种方式,因为计划任务可以指定系统启动时或特定时间触发
- Explorer:资源管理器相关扩展,包括 Context Menu Handlers、Toolbars、Shell Execute Hooks 等
- Drivers:内核驱动加载,Rootkit 最常出没的位置
- WMI:WMI 事件订阅,这个位置隐蔽性极强,常规杀软扫描很少覆盖
Autoruns 默认启动后会做一次全量扫描,主界面按“Everything”页签聚合展示。实际分析时我很少直接在 Everything 里翻,更习惯一个个页签看过去,尤其是 Logon、Services、Scheduled Tasks 这三个页签,是九成恶意软件持久化的重灾区。
3.2 如何“一眼”揪出异常项:排序、签名与 VT 校验
Autoruns 每一条启动项的旁边都有几个关键列:Publisher(签名发布者)、Description(描述)、Image Path(映像路径)、Launch String(启动字符串)。我的排查顺序是这样的:
第一步,先把官方签名项过滤掉。Autoruns 顶部的 Options 里勾上 “Hide Microsoft Entries”和“Hide Windows Entries”。这两个选项开启后,微软和 Windows 自带条目会直接隐藏。剩下的条目数量通常能降到两位数以内,这才是真正需要逐条人工审核的部分。
第二步,看 Image Path 和 Launch String 的路径位置。如果启动项指向的是 %AppData%、%Temp%、C:\ProgramData、Public 目录下的随机命名 exe,基本可以判定问题;如果路径写的是 %systemroot%\system32\config\systemprofile 这种绕弯子写法,更要提高警惕。
第三步,右键可疑条目,选择 Check VirusTotal。Autoruns 会把该文件的哈希值提交给 VirusTotal 查询,并在 Last VT Detection 列显示查杀率。查杀率高不一定代表它是恶意样本,但结合路径和行为日志,已经足够支撑判断。实际排查时我会把 VT 检测率 > 5 的条目全部导出到 CSV 里,作为后续分析的候选清单。
这里有个细节:如果 Autoruns 扫描时提示某个条目“File not found”(映像路径文件不存在),这也是重要线索。很多恶意软件清理工具会删除文件但遗留启动项,这种残留痕迹往往是攻击发生过的直接证据,我在应急报告里经常拿它作为“历史入侵痕迹”的依据。
3.3 Autorunsc:以后做批量排查我更常用它
Autoruns 图形界面虽好,但批量排查多台机器时效率太低。Sysinternals 还提供了命令行版本 Autorunsc,它的输出可以导出成 CSV,配合脚本做批量分析非常方便。我在处置多台服务器同时中招的场景下,基本不打开 GUI,而是直接执行:
autorunsc.exe -a "*" -c -h -s -v | Out-File autoruns_report.csv这里的参数含义:-a 指定扫描所有启动位置,-c 输出为 CSV 格式,-h 显示文件哈希值,-s 验证签名,-v 包含 VirusTotal 查询结果。导出的 CSV 可以直接用 Excel 透视,也可以交给脚本二次匹配。
但有一点必须提醒:Autorunsc 的 -v 参数是每一条都要发起 VT 查询,全量扫描时速度很慢,还会受 VirusTotal API 频率限制。建议先用 -s 做签名过滤,把剩下的可疑条目再用 -v 做逐条查询。
4. Process Explorer:解剖当前正在运行的嫌疑人
4.1 从进程树看父子关系,谁拉起了谁
如果说 Procmon 告诉你“恶意软件做过什么”,那么 Process Explorer(简称 Procexp)告诉你“恶意软件正在干什么”。它的主界面默认按进程树展示,父进程在上、子进程在下,这比单纯的进程列表有用得多,因为“谁拉起了谁”是判断攻击链最直接的信息。
分析时我首先看的是父子关系是否异常。举个例子,正常的 explorer.exe 双击运行程序,子进程是用户程序,合理。但如果你看到 svchost.exe 下面挂着一个 cmd.exe,cmd.exe 又拉起了 powershell.exe,这个链条就非常可疑,因为系统服务宿主进程通常不会主动拉起交互式命令行。这种父子关系异常是 Process Explorer 给我印象最深的能力之一,比任何 hash 匹配都更快暴露问题。
Process Explorer 每一行默认显示的列包括进程名、PID、CPU、私有字节、用户名、Session 等。右键任意进程选择 Properties,可以看到更详细的属性页。我重点看的几个页签是:
- Image:可执行文件路径、版本信息、签名验证状态
- TCP/IP:该进程的所有活动网络连接,连接目标 IP 和端口一目了然
- Strings:进程内存中可打印的 ASCII 和 Unicode 字符串,不需要拆内存文件就能快速浏览
其中 Image 页签里的 “Verified Signer” 字段特别重要。如果签名为 “(无法验证)”或者显示未知发布者,这个进程优先级会立刻提高到最前。
4.2 线程栈、句柄与 DLL:三个勾连线索
进程属性页的 Threads 页签里有一个 Stack 按钮,点击后能看到该线程当前的内核态和用户态调用栈。恶意软件在运行过程中往往会在某个线程里执行核心恶意逻辑,线程栈里出现的模块名和函数名,经常会直接指向注入来源。我见过不少混淆得很好的样本,PE 文件本身看不出任何恶意特征,但线程栈里某个模块路径是在 Temp 目录下释放的 DLL,问题一下子就暴露了。
Process Explorer 的句柄视图(Ctrl+H)也很值得养成习惯。切换到 handle 模式后,能看到进程当前打开的每一个文件、注册表键、事件对象等。恶意软件为了反分析,经常会独占某个日志文件或者互斥体(Mutex),这些句柄信息在排查“某个文件为什么删不掉”“某个服务为什么停不下来”时非常管用。
DLL 视图(Ctrl+D)则展示进程加载的所有 DLL 列表,配合 “Verified Signer” 列可以快速筛出无签名且路径异常的模块。实际分析时我会按“模块路径不含 Windows 目录 + 无签名”这两个条件做筛选,命中项几乎全是问题点。另外,如果发现某个 DLL 位于 Temp、Public、Downloads 这类目录,基本可以断定存在 DLL 劫持或者反射式注入。
4.3 直接转储内存,为后续逆向留证据
Process Explorer 有一个经常被低估的功能:进程内存转储。右键进程 -> Create Dump -> 选择 Create Full Dump,它会生成一个包含进程完整虚拟内存的 .dmp 文件。这个文件可以交给后续的逆向工具(比如 Volatility、Mimikatz 提取、Ghidra 导入)做更深入的分析。
我的习惯是:分析一个可疑进程前,先做一次全量转储,再做其他操作。因为很多行为是有时间窗口的,进程一结束,内存证据就没了。转储文件虽然大(一般几百 MB 到几个 GB),但硬盘空间换取证时机的价值,这笔账怎么算都划算。
另一个实用小技巧:如果恶意进程持续运行,但你已经通过 Procmon 锁定了它写入了某个恶意 DLL,不要急着结束进程,先在 Process Explorer 中右键进程选择 Restart(重启进程),让它在你的监控环境下重新跑一遍完整启动链,往往能把静态分析漏掉的步骤重新补捉一遍。
5. 实战串场:三个工具如何打一套组合拳
5.1 一个真实的告警场景,从接入到定位
纸上谈兵没意思,我举个例子。某次处置一台 Windows Server,值班同事反馈:服务器 CPU 偶发飙高,终端防护弹了两次可疑 PowerShell 执行告警,但连续两次全盘扫描都没有检出威胁。
我的接入流程是这样的:先打开 Process Explorer,按 CPU 使用率排序,观察哪个进程在飙高的瞬间占据 CPU。抓到一个 PowerShell 进程,父进程却是 WmiPrvSE.exe——这就是典型的 WMI 远程调用或者 WMI 事件订阅触发。继续看这个 PowerShell 的启动参数和当前目录,确认它在执行一段经过 Base64 编码的脚本。
随后切到 Autoruns,WMI 页签下果然看到一条指向这段脚本的事件订阅,CommandLine 是 powershell -enc 开头的编码指令。这时候恶意软件为什么要编码执行、为什么会重启后持续存活,答案已经拼上了一半。
5.2 联动排查的步骤拆解
不要急着删除 WMI 订阅就收工。完整流程是:先把 Process Explorer 里那个 PowerShell 进程做全量内存转储,再把 Autoruns 里命中的恶意启动项导出,接着用 Process Monitor 挂上过滤条件,只监控该 PowerShell 进程及其子进程的活动,让它再跑一轮,捕获它写入文件、修改注册表、外联地址的完整行为链路。
Procmon 跑完一轮之后,日志里出现了两次关键操作:一次是 CreateFile 写入 C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\s.dll,另一次是 TCP Connect 到一个境外 IP 的 443 端口。到这一步,整个“WMI 订阅 -> PowerShell 拉取载荷 -> 释放 DLL -> 外联回连”的链条已经闭环。
到这里,三个工具的配合已经有了清晰的分工:
- Process Explorer 定位“正在执行的恶意进程是谁”
- Autoruns 回答“恶意进程靠什么活下来的”
- Process Monitor 还原“恶意进程这段时间到底干了什么”
5.3 三个工具的“互相印证”环节
这种联动分析里最有价值的部分是“互相印证”。比如 Autoruns 里出现的启动项,单独看可能是误报,但当 Procmon 日志里出现了与之完全一致的注册表写入和文件释放动作时,证据链就不再依赖单一信息来源了。
我习惯在最后把三个工具的关键发现拼成一个时间线表格:Process Explorer 记录的是进程诞生时间和父进程,Autoruns 记录的是持久化注册时间和触发条件,Procmon 记录的是每一次文件、注册表、网络操作的发生顺序。时间线一出来,恶意软件从落地到存活到外联的完整攻击路径就全部可视化了。
6. 走过的弯路:常见问题与排查心得
6.1 高频问题与排查速查
| 症状 | 可能原因 | 排查方向 |
|---|---|---|
| Procmon 日志量太大,关键事件丢失 | 过滤条件设置过晚或过宽 | 先设过滤再启动捕获,按进程名 + 关键 Operation 过滤 |
| Autoruns 里找不到异常启动项 | 恶意软件以服务或无文件方式运行 | 单独检查 Services、Scheduled Tasks、WMI 三个页签 |
| Process Explorer 无法查看某个进程的详情 | 权限不足,进程属于 SYSTEM 或其他用户 | 用管理员权限重新启动 Process Explorer |
| 转储文件过大,分析工具无法打开 | 全量转储包含大量共享内存页 | 改用 Create Mini Dump,或对特定进程页做针对性转储 |
| VT 查询显示 0 检测,但行为异常 | 刚出现的新样本或高度混淆 | 不要依赖查杀率,结合行为证据链判断 |
| Procmon 捕获不到网络连接 | 默认操作集未包含网络事件 | 确认 Options 里选中了网络监控选项,必要时按 TCP Connect 过滤 |
排查的时候永远不要只盯着一个工具下结论。单点线索可能是巧合、可能是误报,但多个工具指向同一个模式时,误判的概率会大幅下降。
6.2 三条我在实战中沉淀的个人心得
第一条:先把系统快照做出来,再动手清理。Sysinternals 工具全都打开并收集一轮信息之后,无论结论多明显,先把这个“三件套证据包”完整留存归档。很多时候你以为找到的 root cause 并不是全貌,后面复盘时如果没有一手数据,所有分析都得推倒重来。
第二条:不要在客户环境里直接用 Procmon 全量捕获。生产服务器上跑全量 Procmon,日志量大到能瞬间把磁盘写满,既影响业务又可能破坏证据。实战中我都是先用小过滤集跑 30 秒快速定位,确认进程后再精准跟进,而不是一上来就开着大网到处捞。
第三条:三件套以外的 Sysinternals 工具别急着学。很多新人喜欢把整个工具包背一遍,但真正形成战斗力的是先把核心工具练到形成本能。我的建议是,用 Process Monitor、Autoruns、Process Explorer 这三个工具反复分析同一个干净系统和同一个测试样本,直到你不看文档也能说出每个按钮的位置和每个核心视图的含义,再去接触 TCPView、Strings、Sigcheck 这些周边工具,这样基础会扎实得多。
从 Sysinternals 工具本身来说,这套三件套面世已经很多年,但至今仍然是我处理恶意软件事件时的第一选择。不是因为它们有什么高深莫测的黑科技,而是因为它们足够底层、足够真实、足够克制——没有令人胆寒的误报率,没有隐藏判断逻辑的黑盒决策,也不会三天两头改版到让你怀疑人生。分析恶意软件这行,最怕的不是工具不够多,而是数据不够真。Sysinternals 给你的恰恰就是最原始、最真实、可追溯的系统行为数据。把这三件套用透,你的恶意软件分析之路就已经站在一个非常坚实的起点上了。