NTFS 的 Update Sequence Number 日志 — 通常被称为 USN 日志 或者就叫 $UsnJrnl:$J — 是 Windows 取证中最被低估的痕迹之一。每当 NTFS 在一个卷上创建、删除、重命名、截断或以任何方式触及一个文件时,都会向这个日志追加一条记录。记录非常小 (每条几十字节),日志以固定大小的环形缓冲区方式滚动,因此一台活跃的机器通常会保存大约最近数百万次的文件操作。
日志位于哪里
日志不是普通文件。它是一个 替代数据流,名为 $J,附在卷根目录下的 \$Extend\$UsnJrnl 文件上。从取证镜像中,你通常用懂 NTFS 元数据流的工具 (FTK Imager、X-Ways、Sleuth Kit 的 icat 等) 把它取出来。得到的 $J 字节块,正是本站的 WebAssembly 解析器或 usnrs 这类工具所消费的输入。
记录结构 (USN_RECORD_V2)
每条记录都是一个 USN_RECORD_V2 结构:
| 字段 | 字节 | 含义 |
|---|---|---|
| RecordLength | 4 | 包含文件名在内的记录总大小 |
| Major / Minor version | 2 + 2 | 当前为 2.0 |
| FileReferenceNumber | 8 | 文件的 MFT 表项 + 序列号 |
| ParentFileReferenceNumber | 8 | 父目录的 MFT 表项 + 序列号 |
| USN | 8 | 该记录在日志中的位置 |
| Timestamp | 8 | Windows FILETIME (自 1601-01-01 起的 100ns 计数) |
| Reason | 4 | 描述发生何种变更的位掩码 (FileCreate、Close 等) |
| SourceInfo | 4 | 提示信息 (例如 DATA_MANAGEMENT 表示由操作系统发起的变更) |
| SecurityId | 4 | 指向 $Secure:$SII 的索引 |
| FileAttributes | 4 | 标准 NTFS 属性 |
| FilenameLength / Offset | 2 + 2 | 记录内 UTF-16 文件名的位置 |
| Filename | n | UTF-16 LE,无空终止符 |
最具信息量的字段是 "reason":它是位掩码,而一个文件典型的生命周期会产生类似 FileCreate | DataExtend → DataExtend | Close → BasicInfoChange | Close → FileDelete | Close 的序列。重建这个序列,正是事后讲清楚某个文件到底发生了什么的方式。
为何在 DFIR 中重要
两条理由:
- 跨越删除而存活。 即使文件已经从文件系统 (以及回收站) 中消失,它的操作历史仍留存在日志中,直到环形缓冲区将其覆盖。
- 查询成本低。 一个 100 MB 的
$J通常包含覆盖数天至数周活动的数百万条记录,而每条记录都是自描述的。
当把日志与 $MFT 关联时,可以为几乎每条记录解析出完整路径 — $MFT 通过每个表项的 $FILE_NAME 属性提供父级链。本站「拖入你的 $MFT」选项做的正是这件事。
接下来读什么
如果你从未看过 USN 日志,最简单的上手方式就是从一台测试机上取一份,然后把它拖进本页顶部的方框。本系列接下来的文章会深入剖析 reason 标志、日志雕刻 (carving) 的取舍,以及日志与 Windows 其他时间线痕迹 ($LogFile、Prefetch、ShimCache) 的相互定位。