Fleet 实战技巧:用 osquery 检测已接受 ProcDump EULA 的 Windows 主机
【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet
2021 年 3 月爆发的 Microsoft Exchange 0-day 漏洞事件(后被称为 Hafnium 攻击)中,攻击者被观察到利用 Sysinternals 工具 ProcDump 转储 LSASS 进程内存以窃取凭据。本文基于 Fleet 仓库中的 技术指南,讲解如何用一条针对 Windows 注册表的 osquery 查询,在全组织范围内快速定位那些注册表中留下"已接受 ProcDump EULA"痕迹的主机,并说明该检测背后的取证原理、Fleet 中registry表的工作机制,以及如何在 Fleet 策略(Policy)中落地这条检测。
背景:为什么 ProcDump 出现在 Exchange 漏洞利用链里
2021 年初,攻击者利用当时尚未公开补丁的 Microsoft Exchange 邮件软件漏洞进行大规模入侵。虽然初始入侵手段一度隐蔽,但安全公司 Volexity 在事后分析中记录了攻击者驻留(post-exploitation)阶段使用的一批工具与手法——其中就有 ProcDump。ProcDump 是 Sysinternals 套件中的进程内存转储工具,攻击者用它 dump LSASS(Local Security Authority Subsystem Service)进程内存,从而提取登录凭据。
这类事件的排查难点在于:如果攻击者用完即删,磁盘上可能不会留下 ProcDump 可执行文件本身。但攻击者运行 ProcDump 的过程会在系统里留下更耐久的痕迹,这正是下一条检测思路的基础。
检测原理:EULA 接受记录是"半永久"的注册表工件
ProcDump 首次运行时要求用户接受其 EULA(最终用户许可协议),接受后会写入一个注册表值:
HKEY_USERS\<用户>\Software\Sysinternals\ProcDump\EulaAccepted只要该值存在,就说明这台机器上的某个用户账户曾经成功运行过 ProcDump。这个工件的价值在于:
- 可清除的少:即使攻击者删除了 ProcDump 的 exe 文件,注册表值仍会保留;
- 带时间戳:该键值的
mtime(修改时间)近似等于 EULA 被接受的时间,可与攻击窗口做时间关联分析。
Fleet 仓库收录的检测查询(源自社区检测方案 Recon InfoSec)就是围绕这个注册表工件设计的。
核心检测查询:查找已接受 ProcDump EULA 的主机
以下查询在 Fleet 的查询编辑器(或 osquery 环境)中直接执行即可:
SELECT datetime(mtime, 'unixepoch', 'localtime') AS EULA_accepted, path FROM registry WHERE path LIKE 'HKEY_USERS\%\Software\Sysinternals\ProcDump\EulaAccepted';逐部分解读:
| 片段 | 说明 |
|---|---|
FROM registry | osquery 的 Windows 注册表表,逐键导出注册表内容 |
WHERE path LIKE 'HKEY_USERS\%\Software\Sysinternals\ProcDump\EulaAccepted' | 通配符%匹配HKEY_USERS下任意用户前缀,覆盖所有用户(包括已登录和缓存的用户配置单元) |
datetime(mtime, 'unixepoch', 'localtime') AS EULA_accepted | 把注册表值的mtime(Unix 时间戳)格式化为本地时间,即为EULA 被接受的时间 |
path输出 | 保留完整路径,可从路径中的用户前缀判断是哪个账户运行过 ProcDump |
返回的每一行对应一台主机上的一条命中:EULA_accepted给出接受 EULA 的时间,path给出对应的用户注册表路径。若在查询结果中看到了本不该使用 Sysinternals 工具的用户路径,或时间点与 Exchange 服务器受攻击窗口吻合,就值得进一步取证。
深入一层:Fleet 中registry表是怎么工作的
这条查询依赖 osquery 的registry表。Fleet 仓库的表定义文档 registry.yml 对该表有明确说明:Windows 注册表是存储应用程序数据和系统底层配置(驱动、安全、服务、用户信息)的数据库,而registry表正是把注册表数据以 SQL 形式暴露出来,主要列包括path(键的完整路径)、name(值名)、data(值内容)和mtime(值的时间戳)。文档同时指出,registry表"非常适合用于 Fleet 策略和查询"。
从 Fleet 内置查询库的实际用法可以印证这一点。例如 standard-query-library.yml 中大量合规检查都基于同一张表:
- 屏保/锁屏检查:
SELECT 1 FROM registry WHERE path = 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\InactivityTimeoutSecs' AND CAST(data as INTEGER) <= 1800; - 防火墙域策略检查:
SELECT 1 FROM registry WHERE path LIKE 'HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\EnableFirewall' AND CAST(data as integer) = 1; - 自动更新检查:
SELECT 1 FROM registry WHERE path LIKE 'HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU\NoAutoUpdate' AND CAST(data as integer) = 0;
这些查询与本文的 ProcDump 检测共用同一套模式:以注册表键路径为线索、用LIKE做通配、用data断言具体值。区别只在于,合规检查看的是"策略键是否符合基线",而安全狩猎看的是"某个敏感工具是否被运行过"。
另外,registry表是 Windows 专属表。在 Fleet 中把这类查询编排为策略时,应标注platform: windows,避免在 macOS/Linux 主机上执行后报"表不存在"类错误——Fleet 内置查询库中的 Windows 策略同样遵循这一约定(见 queries.yml 中标注platform: windows的条目)。
落地为 Fleet 策略:把一次性查询变成持续监控
上述查询作为一次性排查很有价值,但威胁狩猎更好的做法是将其固化为 Fleet 策略,让 Fleet 按周期自动在所有 Windows 主机上执行并对未通过的主机告警。参考 Fleet 策略规格文件的通用结构(apiVersion: v1/kind: policy/spec,可对照 standard-query-library.yml 中的既有策略条目),可以这样编写:
apiVersion: v1 kind: policy spec: name: ProcDump EULA accepted (credential access hunting) query: | SELECT 1 FROM registry WHERE path LIKE 'HKEY_USERS\%\Software\Sysinternals\ProcDump\EulaAccepted' LIMIT 1; description: "检测注册表中是否存在已接受 Sysinternals ProcDump EULA 的痕迹。ProcDump 曾被用于 Exchange 0-day 攻击后 dump LSASS 内存窃取凭据,该工件提示主机上曾运行过 ProcDump。" resolution: "核对该用户是否有合法的 Sysinternals 使用需求;若属异常,检查 mtime 时间窗口内的主机活动并考虑隔离主机。" platform: windows tags: hunting, malware, credential-access注意策略版将SELECT精简为返回单行SELECT 1 ... LIMIT 1——策略只需要判断"通过/未通过",而排查用的完整版仍保留EULA_accepted时间列供取证。若某台主机此前已因合法运维目的使用过 ProcDump(EULA 痕迹早已存在),可在策略结果中结合mtime时间列做豁免判断,而不必删除注册表值。
检测局限与误报考量
把这条检测加入日常监控前,需要理解它的证据边界:
- 它是"运行过"的证据,不是"恶意使用"的证据。EULA 只在接受时写入一次,
mtime之后的任何 ProcDump 使用都不会更新该时间戳。因此EULA_accepted是"不早于此时间"的下界,不能精确定位每次使用。 - 合法使用会造成误报。DBA 排查数据库死锁、内核工程师排查内存问题时都会正常使用 ProcDump。建议结合路径中的用户前缀(
HKEY_USERS\<用户>)判断使用身份——例如 Exchange/MSSQL 服务器上出现普通应用池账户运行过 ProcDump,就明显反常。 - 攻击者可清除该工件。删除
EulaAccepted值或整个Sysinternals\ProcDump键即可消除痕迹,因此该检测属于"高价值但有绕过空间"的信号,应与进程监控、LSASS 访问审计等手段组合使用。
小结
本文的核心方法论可以概括为:把工具的首次运行副作用(如 EULA 注册表键)当作持久化取证工件,用 osqueryregistry表将其变成可全组织扫描的 SQL 条件,再固化为 Fleet 策略持续运行。这一模式并不限于 ProcDump——任何会在注册表留下"曾经运行"痕迹的敏感工具,都可以按同样的思路从 standard-query-library.yml 中学习写法并扩展成自己的狩猎规则。
【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考