每个 NTFS 文件都有一个承载其内容的 $DATA 属性(类型 0x80)。对多数文件,$DATA 是非常驻:属性头携带一份 runlist,指向卷上别处的簇 run。对小文件,字节就内联在 MFT 记录本身。后者是 NTFS 取证中最有用的工件之一,也是我反复看到分析师们忘记的那一类。
多小才算够小
一条 MFT 记录是 1,024 字节。从中减去 56 字节的头、fixup 数组、$STANDARD_INFORMATION(约 72 字节)、至少一个 $FILE_NAME(可变,典型名称约 90 字节)、对齐填充以及属性结尾哨兵。剩下的就是留给常驻 $DATA 与其它常驻属性的可用预算。
实务上,阈值在 约 700 字节 上下。一些资料说对名字极短且没有其它常驻属性的文件可达约 750 字节;另一些资料对名字较长或带其它属性的文件给出约 580 字节。阈值不是常量,取决于记录里还有什么。
我反复看到能装进去的文件:
- 小文本文件:笔记、待办、草稿。
- 小配置文件:
.ini、.cfg、小.json、小.xml。 - PowerShell 单行命令与短脚本。
- 小
.lnk快捷方式(多数 LNK 都够小;它们承载什么见 LNK forensics)。 - 注册表导出片段与
.reg文件。 - 小
.bat与.cmd。 - PEM 格式较短的证书文件。
- 空文件与零字节占位符。"数据"是零字节,
$DATA平凡地常驻。 - 许多小目录的
$INDEX_ROOT属性。
这为什么重要
一个常驻 $DATA 属性,不必读取磁盘其余部分就能恢复。如果你有 $MFT 副本,你已经拥有:
- 小文本文件的完整内容。
- 目录的大量
$INDEX_ROOT数据(目录条目内联列出)。 - 较短的备用数据流(内容很小的命名
$DATA属性)。 - Reparse points 与符号链接目标(目标路径在
$REPARSE_POINT中,通常也是常驻)。
在一份 200 MB 到 2 GB 的单一 MFT 抽取中,这就是一份令人意外的证据量。对小文件的删除而言,即使数据区已被覆盖,常驻字节也会幸存——因为数据区根本没被碰过;字节一直住在 MFT 里。
我恢复过:
- 一份 320 字节的 PowerShell loader,来自一条数据簇从未存在的已删除记录。
- 一份 480 字节的
.lnk,指向攻击者的暂存目录,采集前三周已被删除。 - 一份 700 字节的
.config,属于已被卸载的服务。目录已不在,但 MFT 记录在 412,000 号槽位完好无损。
MFT 是这些文件唯一仍存在的地方。
常驻并不稳定
当常驻文件增长到超出记录中的空闲空间时,NTFS 会把它转换为非常驻。数据搬到簇上,$DATA 变成一份 runlist。这个转换在发生时会记录到 $LogFile。
反过来理论上也可能发生(缩回阈值以下的文件可能重新常驻),但 Windows 很少主动这么做。一旦 $DATA 非常驻,它倾向于一直保持非常驻。如果你看到某条记录的 $DATA 是常驻、但你已知该文件曾经更大,那就不寻常,值得调查;它可能暗示有意的操纵,或者一种不常见的把文件原地缩小的代码路径。
解析时如何检测常驻数据
每个 MFT 解析器都在 $DATA 属性头上暴露一个"residence"标志。MFTECmd 的 CSV 输出中把它作为布尔列。mft_dump 的 JSON 里是 header.is_resident。libmft 在属性对象上暴露它。Sleuth Kit 的 istat 也会在属性清单中显示它。
本站浏览器解析器在两次点击内就能把过滤条件设为 IN_USE=0 且 $DATA 常驻。在任何重视小文件恢复的抽取 MFT 上,我第一个跑的就是这个过滤器。
字节长什么样
对常驻 $DATA,属性头后跟着一个 16 字节的常驻头(内容大小、内容偏移、indexed 标志、对齐),然后才是原始字节。这些字节就是磁盘上文件中曾经的样子:文件使用的编码下的文本、原生形式的二进制内容。没有任何转换。
对一份 UTF-8 编码的小文本文件,把字节拷出来用任何编辑器都能打开。对二进制内容(一个小 PE、编译过的 .pyc、一个序列化对象),字节同样可用,把它们当作从卷里抽取出来的文件即可。
限制
多数文件不是常驻。 在普通 Windows 安装中,远少于 5% 的用户文件是常驻的。其余的——所有 Office、所有浏览器缓存、\Program Files\ 里的所有程序、所有下载——都不是。常驻恢复是一个高价值的细分领域,而不是默认模式。
阈值并不精确。 不要假设"小于 700 字节的文件都可恢复"。真实阈值取决于该记录里其他属性的情况。请在你正在分析的那份 MFT 上具体测试。
常驻无法在加密或压缩到足够大时幸存。 EFS 加密的文件用 $LOGGED_UTILITY_STREAM 存放加密元数据,$DATA 就是密文。若密文小到能常驻,你确实拿到了加密字节;但要读它仍需 EFS 密钥。
用上这个性质的工作流程
下次遇到已删除文件恢复的案子、且你关心的文件不大时:
- 从主机(或最近的 VSS 快照,如果有)采集
$MFT。 - 解析它。拉出所有
IN_USE=0且主$DATA是常驻的记录。 - 如果你知道文件名,按
$FILE_NAME正则过滤。如果你知道目录,按父引用过滤。 - 直接内联检视常驻
$DATA字节。文件就在那儿。
只要五分钟。签名 carving 可能要数小时,且对碎片化的小文件大概率失败。
延伸阅读
- linux-ntfs 项目的 常驻属性笔记。常驻头布局的清晰解释。
- Microsoft,NTFS allocation algorithm。常驻/非常驻决策的官方参考。
- Sleuth Kit 的
istat。用来检视单条记录,并在上下文中查看常驻标志。