← 返回博客

在 USN 日志中识破 timestomping 与反取证

改 MFT 时间戳的攻击者,藏不过 change journal。$STANDARD_INFORMATION 与 $FILE_NAME 的不一致,以及意外的 BasicInfoChange 记录,如何揭穿反取证行为。

阅读约 2 分钟

精明的攻击者不仅会抹去证据,还会试图伪装他们留下的东西。最常见的手法是 timestomping:编辑文件的 NTFS 时间戳,让它看起来无害(或者退出调查时间窗)。它曾经管用。打开 USN 日志后,它会留下清晰的信号。

本文走过 timestomping 对磁盘做了什么、日志如何把它暴露出来,以及用同一个痕迹能抓住哪些其他反取证动作。

NTFS 时间戳速复

每条 MFT 表项在两个属性中保存时间戳:

  • $STANDARD_INFORMATION(SI):用户态工具和大多数 API 能改的时间戳。dir、资源管理器和 Get-ChildItem 显示的就是这些。格式见 Microsoft 的 NTFS 参考
  • $FILE_NAME(FN):NTFS 内部在每个 $FILE_NAME 属性上设置的时间戳。一个名字对应一个(若文件有硬链接,文件可有多个名字)。这些 远远 更难改 — 需要内核级访问或专门工具。

Timestomping 工具(SetMACE、来自历史性 Metasploit 反取证模块的 timestomp.exe,以及多种定制植入)通常瞄准 SI。某些现在也瞄准 FN。无论哪种,都会触动 MFT — 这一触动就把日志点亮了。

时间戳编辑会被日志记录成什么

写 SI 时间戳时,NTFS 会发出一条 BasicInfoChange | Close 记录。这条记录就是铁证,因为:

  • 合法的 “touch” 会同时产生 BasicInfoChange | Close 和触发时间戳更新的真实写入对应的 DataExtendDataOverwrite
  • Timestomp 会在同一 FileReferenceNumber 上产生 一条裸的 BasicInfoChange | Close,前面没有任何写入

当你看到同一句柄会话内有 BasicInfoChange | Close,但没有 DataOverwriteDataExtendFileCreate,就是在看元数据操控 — 几乎一定是 timestomping 或属性变更(只读/隐藏)。

经典比较:SI vs FN

最有权威的 timestomping 检测是逐文件比较 $STANDARD_INFORMATION$FILE_NAME 的时间戳。Mandiant 的调查员多年来一直就此撰文;Mandiant 关于 timestomping 的历史白皮书 是经典参考,Brian Carrier 在 File System Forensic Analysis 中也有覆盖。

日志是对比较的补充,而非替代:

  • MFT 比较告诉你 timestomping 发生过,但说不出何时。
  • 日志的 BasicInfoChange | Close 记录告诉你 SI 写入 究竟何时 发生,以及它发生时的进程上下文(配合 Security.evtx4663)。

因此一个被 timestomp 的文件在数据中长这样:

  1. MFT 比较标记 SI < FN(或 SI 在 FN 的未来等)。
  2. 日志在比如 2026-04-12 03:08:14 有一条 BasicInfoChange | Close,周围没有写入。
  3. 这个时间戳就是你在报告里写的那个时间。

关于 MFT 写入,$LogFile 与日志意见不合

日志在文件级别记录写入;$LogFile 记录底层的 MFT 事务。一次 timestomp 会产生:

  • $LogFile 中一条 MFT 写入事务(修改目标表项的 $STANDARD_INFORMATION)。
  • 日志中一条 BasicInfoChange | Close

$LogFile 有 MFT 更新事务但日志没有对应的 BasicInfoChange | Close,攻击者可能 删除了日志记录 — 可通过 fsutil usn deletejournal 后跟 createjournal 做到,这本身又会留下痕迹。

日志能抓到的其他反取证动作

关闭日志

fsutil usn deletejournal /D /N C: 会移除日志。调用之后:

  • 日志文件被重建为空。之前的记录消失。
  • $UsnJrnl 的 MFT 表项被重新写入 — $LogFile 记录这次事务。
  • 如果配置了 SACL,Security.evtx 会记录 SeRestorePrivilegeSeManageVolumePrivilege 的 Sensitive Privilege Use。

日志说不出它原本装着什么,但「关闭」这个动作本身就是反取证的强信号。管理命令及其权限要求见 Microsoft 的 fsutil usn 参考

替代数据流

ADS 隐藏比我还老,日志对此记录干净利落:替代数据流的添加或移除会触发 StreamChange 这个 reason 位。过滤 StreamChange,卷上每一个 ADS 创建/修改事件都会冒出来。误报包括浏览器下载留下的合法 Zone.Identifier 流 — 也会产生 StreamChange,与原文件的 FileCreate 成对出现。

硬链接花招

HardLinkChange 在硬链接被加入或移除时触发。攻击者有时用硬链接让同一个文件可通过两个父级访问 — 便于绕过基于路径的控制。追踪 HardLinkChange,并在 FileReferenceNumber 上做透视看所有父级。

重解析点滥用

重解析点(junction、符号链接、挂载点)可以把一条路径重定向到别处。ReparsePointChange 在添加或修改时亮起。在 $Recycle.Bin\Users\Default 等「本不该被碰」的位置找重解析点。

这条路抓不到的事

绕开日志的反取证动作短清单:

  • 从外部介质引导并改写磁盘 — 从未触及在运行的 OS。
  • 保持原内容大小的用户态改写(同 offset 覆写,且未更新 SI)。会产生 DataOverwrite 记录,但原内容已丢。日志看到写入,但看不到此前的内容。
  • 在攻击者做任何其他事之前就关闭日志。日志只能记录它打开时发生的事。

这些情况,需要 $LogFile、卷影副本,或宿主之外的遥测来补。日志是有力的证人,但不是唯一的。

一个实用扫描

在解析过的日志上,做 timestomping 的最快筛查:

  1. 过滤 reason 恰好为 BasicInfoChange | Close 的记录。
  2. 对每条记录,在同一 FileReferenceNumber 上向前看 5 分钟的记录。若没有 DataOverwriteDataExtendFileCreate 或 rename,就把它标出来。
  3. 对被标出的条目,在 MFT 中计算 SI-vs-FN 的差值。按差值由大到小排序。

榜首通常就是你的 timestomping。剩下的是诸如资源管理器切换「隐藏」属性,或脚本动了属性这类操作 — 看上下文,但典型调查里不太有意思。