分析MFT实现已删除文件恢复 是做什么的?
概述
NTFS主文件表($MFT)是NTFS卷上每个文件和目录的核心元数据存储库。每个文件至少由一个1024字节的MFT记录表示,其中包含$STANDARD_INFORMATION(时间戳、权限)、$FILE_NAME(文件名、父目录、时间戳)和$DATA(文件内容或簇运行指针)等属性。当文件被删除时,其MFT记录被标记为非活动(InUse标志清零),但元数据会保留,直到该条目被新文件重新分配。这种持久性使得MFT分析成为恢复已删除文件证据、重建文件系统时间线以及检测时间戳篡改等反取证活动的主要技术。
何时使用
- 调查需要分析MFT以恢复已删除文件的安全事件时
- 为此领域构建检测规则或威胁狩猎查询时
- SOC分析师需要此类分析的结构化流程时
- 验证相关攻击技术的安全监控覆盖范围时
前提条件
- 取证磁盘镜像(E01、raw/dd、VMDK或VHDX格式)
- MFTECmd(Eric Zimmerman)或analyzeMFT(基于Python)
- FTK Imager、Arsenal Image Mounter或类似工具用于镜像挂载
- Timeline Explorer或Excel用于CSV分析
- Python 3.8+用于自定义分析脚本
- 理解NTFS文件系统内部机制
MFT结构和记录布局
MFT记录头
每个MFT记录以签名"FILE"(0x46494C45)开头,并包含:
| 偏移量 | 大小 | 字段 |
|---|---|---|
| 0x00 | 4字节 | 签名("FILE") |
| 0x04 | 2字节 | 更新序列偏移量 |
| 0x06 | 2字节 | 更新序列大小 |
| 0x08 | 8字节 | $LogFile序列号 |
| 0x10 | 2字节 | 序列号 |
| 0x12 | 2字节 | 硬链接计数 |
| 0x14 | 2字节 | 第一个属性偏移量 |
| 0x16 | 2字节 | 标志(0x01 = InUse,0x02 = 目录) |
| 0x18 | 4字节 | MFT记录已使用大小 |
| 0x1C | 4字节 | MFT记录分配大小 |
| 0x20 | 8字节 | 基本文件记录引用 |
| 0x28 | 2字节 | 下一个属性ID |
关键MFT属性
| 类型ID | 名称 | 描述 |
|---|---|---|
| 0x10 | $STANDARD_INFORMATION | 时间戳、标志、所有者ID、安全ID |
| 0x30 | $FILE_NAME | 文件名、父MFT引用、时间戳 |
| 0x40 | $OBJECT_ID | 文件的唯一GUID |
| 0x50 | $SECURITY_DESCRIPTOR | ACL权限 |
| 0x60 | $VOLUME_NAME | 卷标(仅卷元数据文件) |
| 0x80 | $DATA | 文件内容(小于700字节时为常驻)或簇运行列表 |
| 0x90 | $INDEX_ROOT | 目录的B-tree索引根 |
| 0xA0 | $INDEX_ALLOCATION | 大型目录的B-tree索引条目 |
| 0xB0 | $BITMAP | 索引或MFT的分配位图 |
已删除文件恢复技术
技术1:使用MFTECmd分析MFT记录
# 使用KAPE或FTK Imager从取证镜像提取$MFT
# 使用MFTECmd解析$MFT
MFTECmd.exe -f "C:\Evidence\$MFT" --csv C:\Output --csvf mft_full.csv
# 在Timeline Explorer中过滤已删除文件(InUse = FALSE)
# 查找InUse列为False的条目
在CSV输出中识别已删除文件:
InUse= False 表示已删除或重新分配的记录ParentPath显示删除前的原始文件位置FileSize显示原始大小(仍可能可恢复)$STANDARD_INFORMATION和$FILE_NAME属性中的时间戳会保留
技术2:USN日志($UsnJrnl:$J)分析
USN日志记录NTFS卷上所有文件更改,包括创建、删除、重命名和数据修改事件。
# 使用MFTECmd解析USN日志
MFTECmd.exe -f "C:\Evidence\$J" --csv C:\Output --csvf usn_journal.csv
# 用于删除证据的关键USN原因代码:
# USN_REASON_FILE_DELETE = 0x00000200
# USN_REASON_CLOSE = 0x80000000
# USN_REASON_RENAME_OLD_NAME = 0x00001000
# USN_REASON_RENAME_NEW_NAME = 0x00002000
技术3:$LogFile事务分析
$LogFile存储NTFS事务记录,即使在USN日志被循环覆盖后,仍能揭示文件操作。
# 使用LogFileParser解析$LogFile
LogFileParser.exe -l "C:\Evidence\$LogFile" -o C:\Output
# 查找指示文件删除的REDO和UNDO操作:
# - DeallocateFileRecordSegment
# - DeleteAttribute
# - UpdateResidentValue(清除InUse标志)
技术4:MFT Slack空间分析
MFT slack空间存在于MFT记录已使用部分末尾与1024字节分配空间末尾之间。该区域可能包含以前文件记录的残留。
import struct
def parse_mft_slack(mft_path: str, output_path: str):
"""提取并分析MFT slack空间中已删除文件的残留。"""
with open(mft_path, "rb") as f:
record_size = 1024
record_num = 0
slack_findings = []
while True:
record = f.read(record_size)
if len(record) < record_size:
break
# 验证FILE签名
if record[:4] != b"FILE":
record_num += 1
continue
# 从偏移量0x18处获取已使用大小
used_size = struct.unpack("<I", record[0x18:0x1C])[0]
if used_size < record_size:
slack = record[used_size:]
# 检查slack是否包含可读字符串或属性头
if any(c > 0x20 and c < 0x7F for c in slack[:50]):
slack_findings.append({
"record": record_num,
"used_size": used_size,
"slack_size": record_size - used_size,
"slack_preview": slack[:100].hex()
})
record_num += 1
return slack_findings
与辅助证据的关联
将MFT与$Recycle.Bin交叉引用
# 使用RBCmd解析回收站
RBCmd.exe -d "C:\Evidence\$Recycle.Bin" --csv C:\Output --csvf recycle_bin.csv
# 关联:$I文件包含原始路径和删除时间戳
# 将$R文件中的MFT条目号匹配回原始MFT记录
将MFT与卷影副本交叉引用
# 列出卷影副本
vssadmin list shadows
# 挂载卷影副本并从每个副本提取$MFT
# 比较卷影副本之间的MFT记录以追踪文件随时间的变化
取证价值
- 已删除文件元数据恢复:原始文件名、路径、大小和时间戳
- 时间线重建:文件创建、修改、访问和删除事件
- 时间戳篡改检测:比较$SI与$FN时间戳
- 数据雕刻指引:MFT簇运行指向磁盘上的文件内容
- 反取证检测:识别被擦除或篡改的MFT记录
参考资料
- NTFS MFT高级取证分析:https://www.deaddisk.com/posts/ntfs-mft-advanced-forensic-analysis-guide/
- MFT Slack空间取证价值:https://www.sygnia.co/blog/the-forensic-value-of-mft-slack-space/
- MFTECmd文档:https://ericzimmerman.github.io/
- SANS FOR500:Windows取证分析
示例输出
$ MFTECmd.exe -f "C:\Evidence\$MFT" --csv /analysis/mft_output
MFTECmd v1.2.2 - MFT解析器
==============================
输入:C:\Evidence\$MFT(大小:384 MB)
MFT条目总数:395,264
正在解析MFT条目... 完成(12.4秒)
--- 已删除文件恢复摘要 ---
总条目: 395,264
活动文件: 245,832
已删除文件: 149,432
可恢复: 87,234(常驻数据或尚未重新分配的簇)
部分可恢复: 31,456(部分簇被覆盖)
不可恢复: 30,742(所有簇已被重新分配)
--- 最近删除的文件(事件窗口:2024-01-15 至 2024-01-18)---
MFT条目 | 文件名 | 路径 | 大小 | 删除时间(UTC) | 可恢复
----------|-----------------------------------|------------------------------------|-----------|-----------------------|------------
148923 | exfil_tool.exe | C:\ProgramData\Updates\ | 1,258,496 | 2024-01-17 02:45:12 | 是
148924 | exfil_tool.log | C:\ProgramData\Updates\ | 45,312 | 2024-01-17 02:45:14 | 是
149001 | passwords.txt | C:\Users\jsmith\Desktop\ | 2,048 | 2024-01-17 02:50:33 | 是
149150 | scan_results.csv | C:\Users\jsmith\AppData\Local\Temp | 892,416 | 2024-01-17 03:00:01 | 部分
149200 | mimikatz.exe | C:\Windows\Temp\ | 1,250,816 | 2024-01-18 01:15:22 | 是
149201 | sekurlsa.log | C:\Windows\Temp\ | 32,768 | 2024-01-18 01:15:25 | 是
149302 | .bash_history | C:\Users\jsmith\ | 4,096 | 2024-01-18 03:00:00 | 否
149400 | ClearEventLogs.ps1 | C:\Windows\Temp\ | 1,536 | 2024-01-18 03:01:12 | 是
--- $STANDARD_INFORMATION与$FILE_NAME时间戳分析(时间戳篡改检测)---
MFT条目 | 文件名 | $SI创建时间 | $FN创建时间 | 差异 | 结论
----------|---------------------|----------------------|----------------------|----------|----------
148923 | exfil_tool.exe | 2023-06-15 10:00:00 | 2024-01-15 14:34:02 | -214天 | 时间戳篡改
149200 | mimikatz.exe | 2022-01-01 00:00:00 | 2024-01-16 02:30:15 | -745天 | 时间戳篡改
已恢复文件导出至:/analysis/mft_output/recovered/
完整CSV报告:/analysis/mft_output/mft_analysis.csv(395,264行)
时间线CSV:/analysis/mft_output/mft_timeline.csv