文件系统取证总览

拿到一块镜像,问"里面有什么"表面上是文件恢复,实际拆开是三层:镜像 → 卷(分区 / LVM / RAID)→ 文件系统。只有第三层才决定"文件叫什么、多大、什么时候改过、删到哪里去了"。

最后更新 2026-10-09版本 v1.0维护 DigiForensics查看历史 0

关键词:文件系统、NTFS、ext4、APFS、FAT、卷识别、多分区、inode、MFT 难度:入门 前置知识:磁盘镜像与仿真、分区表基本概念 相关文章:磁盘镜像与仿真 — 只读挂载与安全接入


一、概述

拿到一块镜像,问"里面有什么"表面上是文件恢复,实际拆开是三层:镜像 → 卷(分区 / LVM / RAID)→ 文件系统。只有第三层才决定"文件叫什么、多大、什么时候改过、删到哪里去了"。

文件系统是数据在磁盘上的组织约定。它规定字节如何被解释成目录、文件、簇、inode,也决定了空间何时被复用——删除痕迹之所以能残留,根源就在这里。反取证软件的藏身点几乎都建立在"复用的时机"上,而那个时机由文件系统定义。

同一块磁盘,用 NTFS 解析和用 ext4 解析,得到的目录树可以完全不同。选错文件系统等于全部结论作废,不是"效果差一点",是归零。

这一层判定落在分析环节的最前端。上游输入是卷层:镜像格式(E01 还是 raw,转换见证据格式与转换)与接入方式(见只读挂载与安全接入)。判定完成后按类型分流——NTFS 进 NTFS 结构与 MFT 解析、NTFS 数据流与隐藏数据、Steady-State 与 LogFile 还原,ext4 进 ext4 结构与 inode,FAT 进 FAT 系列结构,APFS 进 APFS 容器与快照,F2FS 进 F2FS 结构,内容识别进 文件头与文件签名。这一层负责判定"这是什么",各分支负责"把它读透"。

判定依据是有确定偏移的特征字段,不是抽象分类:

  • NTFS 在卷起始偏移 3 —— Boot sector 的 OEM ID(55 4F 46 53 20 20 20)
  • 0xEF53 在卷起始偏移 1024(0x400) —— ext2/3/4 超级块的 s_magic。前面 1024 字节是引导区,所以偏移是 1024 不是 0,这是最常记错的一个
  • NXSB 在分区 + 32(0x20) —— APFS 容器头。注意是分区偏移,不是卷偏移
  • APSB 在卷首偏移 0 —— 每个 APFS 卷各自一份
  • FAT12 / FAT16 / FAT32 文本 preceded by 跳转指令 0xE9 / 0xEB —— FAT 家族
  • EXFAT 在偏移 3 —— exFAT。它没有标准 BPB,别按 FAT32 的 BPB 去读
  • H+(0x482B)在偏移 1024 —— HFS+(嵌入式场景 +18)
  • SWAPSPACE2 / SWAP-SPACE —— Linux swap,swap 也要单独 dump
  • LABELONE —— LVM2 元数据区
  • mmls 的 Unallocated 行 vs blkls 的未分配簇 —— 卷层的"未分配"与文件系统层的"未分配"是两回事,前者是分区表没占的区间,后者是文件系统内部还没分配的簇。反取证软件最常见的藏身点就是这两处
  • 第三章 3.6 的熵检测 —— ent -b 的 Shannon 熵接近 8.0 几乎必然是加密或已随机化填充。读不出文件名但熵很高,说明是加密而不是空白

判定之后能回答的是这些:卷上跑的是什么文件系统(靠魔数、靠结构区,不靠扩展名也不靠体积)、一块盘上有多套系统该怎么逐卷处理,以及——最关键的——怎么判断自己是不是解析错了。

最后一条来自 2.5 那句"部分正确、部分错误最危险":判断标准应是目录数量和文件数量是否合理,而不是"命令有没有报错"。偏移少加一个扇区时,工具偶尔仍能出目录名,这种"看起来成功"比明确报错危害大得多——它让人以为已经检查过了。

有几件事不归这一层管:任何一种文件系统的具体结构,解析在分支篇里;LVM / 动态磁盘 / RAID 的重组,2.4 表格里写了"需 mmstat 或专有工具重组";加密卷的内容,识别出 BitLocker 之后怎么解是加密篇的事;时间戳怎么读,这里只判定"这是 NTFS",$STANDARD_INFORMATION 里四个时间戳的语义在时间戳篇。

往下读之前,需要分区表(MBR / GPT)与卷层概念,以及基本的十六进制读取能力——全程都在"相对卷起始的偏移"上计算,而最容易出的错就是偏移的基址搞混(分区起始 vs 卷起始 vs 磁盘起始)。

另外强烈建议先读一遍取证流程与原则的检验阶段:这里的全部命令都是在工作副本上跑的,不是原始介质。 第三章步骤 5 那个"卷清单"登记表之所以要记 Slot、起始扇区、文件系统类型、目录条目数四项,就是为了让复核者能重走一遍——登记格式本身就是可追溯性。

二、核心原理

2.1 三层结构与工具对应

层 回答的问题 Sleuth Kit 工具 典型失败模式
Image 镜像格式、扇区大小 img_stat E01 当 raw 读,全盘乱码
Volume 分区表、LVM、RAID mmls / mmstat 把分区间隙当数据
File System 目录树、元数据、内容 fsstat / fls / icat 偏移错位、类型误判

关键点:卷层的"未分配"和文件系统层的"未分配"是两回事。前者是分区表没占用的区间(mmls 的 Unallocated 行),后者是文件系统内部还没分配的簇/块(需 blkls)。

反取证软件最常见的藏身点就是这两处。

2.2 三大主流系统对比

维度 NTFS ext4 APFS
平台 Windows / Linux 双系统 Linux macOS / iOS
核心数据库 $MFT(每文件一条 1024 字节记录) inode 表(分散于块组) APFS B-tree(对象容器)
元数据集中度 极高,几乎全在 $MFT 中,inode + 目录散落 极高,单一 B-tree
删除痕迹 $FILE_NAME 保留原名+父引用 inode 保留时间戳+大小,文件名易丢 B-tree 中对象可残留
内建版本机制 卷影副本(快照) 无(日志 + 备份工具) 原生快照 + checkpoint
加密支持 BitLocker / EFS(卷级/文件级) LUKS/dm-crypt(卷级) 原生整容器加密
时间戳 4 个(创建/修改/访问/变更) 常见 3–4 个(纳秒精度) created / modified
日志/日志还原 $LogFile(可回放元数据) journal(可回放) checkpoint 映射 + B-tree 事务
取证友好度 ★★★★★ 工具最全 ★★★★ 工具成熟 ★★★ 工具少、加密普遍
恢复难度 低(有明确元数据记录) 中 高(加密 + 工具少)

一个反直觉但重要的点:APFS 在"元数据集中度"上比 NTFS 更高——它把所有文件、目录、符号链接的属性统一塞进 B-tree 节点。

这理论上更利于完整解析,实际却因为加密默认开启 + 公开解析工具少而更难取证。

2.3 文件系统识别:靠魔数,不靠扩展名或体积

判别顺序永远是先看结构区,再看特征字段。以下为各系统在卷起始处的签名(偏移均相对卷/文件系统起始,不是磁盘起始):

文件系统 相对偏移 签名/特征 备注
NTFS 偏移 3 NTFS (55 4F 46 53 20 20 20) Boot sector OEM ID
ext2/3/4 偏移 1024(0x400) 超级块 s_magic = 0xEF53 前面 1024 字节是引导区
APFS 容器 偏移 32(0x20) NXSB 容器头 magic;APSB 是卷超级块
APFS 超级块 偏移 0(卷首) APSB 每个 APFS 卷各自一份
FAT12/16/32 偏移 0 跳转指令 + FAT12/FAT16/FAT32 文本 0xE9/0xEB 开头
exFAT 偏移 3 EXFAT Boot sector
HFS+ 偏移 1024(0x400) H+ (0x482B) 嵌入式场景 +18
swap 偏移 0/页尾 SWAPSPACE2 / SWAP-SPACE Linux swap
LVM2 元数据区 LABELONE 卷组元数据区

判别用命令:

mmls /evidence/DigiForensics.dd              # ① 卷层:TSK 直接给出类型判断
fsstat -o 63 /evidence/DigiForensics.dd      # ② 文件系统层:读超级块
xxd -l 1024 -s $((63*512)) /evidence/DigiForensics.dd | head -20   # ③ 兜底:看魔数
sudo blkid -p -o full /evidence/DigiForensics.dd                   # ④ Linux 侧独立判定

注意区分:file 只能识别整个镜像文件,不能识别镜像内的分区。要判断分区类型必须用 blkid -p(探测模式)或 TSK 的 fsstat。

2.4 多卷 / 多分区场景

布局 典型来源 处理要点
EFI + 系统 + 数据(3 分区) Windows 现代安装 每个分区独立 fsstat/fls
共享 + 家庭 + 恢复(3 分区) Windows OEM 恢复分区可能是 FAT32 小卷
GPT + ESP(FAT32) + root(ext4) + swap Linux swap 也要单独 dump
APFS 容器(1 分区内多卷) macOS 见 06
LVM 逻辑卷 / 动态磁盘 / RAID 服务器 需 mmstat 或专有工具重组

处理原则:逐卷独立解析,结果用「卷标识 + 元数据坐标」双重引用。

例如"卷 2(NTFS)MFT 条目 11443"比"某文件"精确得多,且可复核。

2.5 为什么"选错文件系统"是灾难性错误

误判 表现 危害
把 APFS 容器当 ext4 目录树全空 + 大量 I/O 错误 误判为"已擦除"而结案
把 BitLocker 卷当 NTFS 文件名全乱码 误判"文件已损坏"
偏移少加一个扇区 偶尔能出目录名 最危险:部分正确、部分错误,结论互相矛盾
用 FAT 解析器读 exFAT 只能列出根目录 漏掉深层数据

最后一条最危险:部分解析成功会给人"已经检查过"的错觉。判断依据应是目录数量和文件数量是否合理,而不是"命令有没有报错"。


三、操作步骤

3.1 第 1 步:确认镜像本身

# 镜像格式、扇区大小、总容量
img_stat /evidence/DigiForensics.dd

# 分配 E01 → raw
ewfverify /evidence/DigiForensics.E01        # 先验证完整性
ewfexport -t raw -u /tmp/ewf1 /evidence/DigiForensics.E01 -f /work/DigiForensics.dd
img_stat /work/DigiForensics.dd

3.2 第 2 步:解析分区表(卷层)

# MBR/GPT 通吃
mmls /work/DigiForensics.dd

# 输出示例(务必逐列记录)
# Slot      Start        End          Length       Description
# 00: Meta  0000000000   0000000000   0000000001   Primary Table (#0)
# 01: ----- 0000000000   0000000062   0000000063   Unallocated
# 02: 00:00 0000000063   0009510479   0009510417   NTFS (0x07)
# 03: ----- 0009510480   0009514259   0000003780   Unallocated

记录规范:把 mmls 完整输出作为附件存档,后续所有操作都引用 Slot 与起始扇区。

3.3 第 3 步:逐卷判定文件系统类型

对每个非 Unallocated 的 Slot 逐一执行:

# 以 Slot 02(起始扇区 63)为例
fsstat -o 63 /work/DigiForensics.dd

# 关键字段:
#   NTFS  → File System Type: NTFS / MFT Cluster / Boot Sector Cluster
#   ext4  → File System Type: Ext4 / Block Size / Inode Size / Journal Inode
#   FAT   → File System Type: FAT / Cluster Size / Root Directory Sector
#   APFS  → APFS 容器需用专门工具(见 06 篇)

若 fsstat 报"Cannot determine file system type",按下列顺序排查: