精明的攻击者不仅会抹去证据,还会试图伪装他们留下的东西。最常见的手法是 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和触发时间戳更新的真实写入对应的DataExtend或DataOverwrite。 - Timestomp 会在同一
FileReferenceNumber上产生 一条裸的BasicInfoChange | Close,前面没有任何写入。
当你看到同一句柄会话内有 BasicInfoChange | Close,但没有 DataOverwrite、DataExtend 或 FileCreate,就是在看元数据操控 — 几乎一定是 timestomping 或属性变更(只读/隐藏)。
经典比较:SI vs FN
最有权威的 timestomping 检测是逐文件比较 $STANDARD_INFORMATION 与 $FILE_NAME 的时间戳。Mandiant 的调查员多年来一直就此撰文;Mandiant 关于 timestomping 的历史白皮书 是经典参考,Brian Carrier 在 File System Forensic Analysis 中也有覆盖。
日志是对比较的补充,而非替代:
- MFT 比较告诉你 timestomping 发生过,但说不出何时。
- 日志的
BasicInfoChange | Close记录告诉你 SI 写入 究竟何时 发生,以及它发生时的进程上下文(配合Security.evtx的4663)。
因此一个被 timestomp 的文件在数据中长这样:
- MFT 比较标记 SI < FN(或 SI 在 FN 的未来等)。
- 日志在比如
2026-04-12 03:08:14有一条BasicInfoChange | Close,周围没有写入。 - 这个时间戳就是你在报告里写的那个时间。
关于 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会记录SeRestorePrivilege或SeManageVolumePrivilege的 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 的最快筛查:
- 过滤 reason 恰好为
BasicInfoChange | Close的记录。 - 对每条记录,在同一
FileReferenceNumber上向前看 5 分钟的记录。若没有DataOverwrite、DataExtend、FileCreate或 rename,就把它标出来。 - 对被标出的条目,在 MFT 中计算 SI-vs-FN 的差值。按差值由大到小排序。
榜首通常就是你的 timestomping。剩下的是诸如资源管理器切换「隐藏」属性,或脚本动了属性这类操作 — 看上下文,但典型调查里不太有意思。