captainx-dcode/digital-forensics

GitHub: captainx-dcode/digital-forensics

一个数字取证实战作品集,通过基于文件系统元数据和原始磁盘文件签名两种路径,实现从磁盘镜像中自动恢复和雕刻文件。

Stars: 0 | Forks: 0

# 数字取证 —— 文件恢复与雕刻 一份涵盖了两种互补证据恢复学科的实战数字取证作品集,其内容基于引导式技术课程和评分实验构建,并以一个实现了全流程自动化的程序作为总结。 该工作分为两个分支,对应了从磁盘镜像中恢复文件的两种方式: | 分支 | 适用场景 | 文件查找方式 | | --- | --- | --- | | **基于文件系统** | 文件系统完好(NTFS / FAT32) | 使用 The Sleuth Kit 读取文件系统自身的簿记(MFT / FAT) | | **原始磁盘与文件签名** | 文件系统丢失、被格式化、损坏或被擦除 | 在原始字节中搜索文件*签名*并直接雕刻出文件 | 连接两者的决定性理念在于:**雕刻引擎是相同的** — `seek(start)` 然后 `read(end − start)`。变化的是*偏移量从何而来*。在基于文件系统的恢复中,偏移量是**从元数据中读取**的;而在原始磁盘恢复中,偏移量是**通过签名搜索发现的**。 ## 仓库结构 ``` digital-forensics/ ├── README.md ← you are here (overview + formula reference) ├── LICENSE ├── .gitignore ├── docs/ │ ├── FORMULAS.md ← every calculation, derived and worked │ ├── WORKFLOW.md ← the end-to-end forensic workflows │ └── GLOSSARY.md ← forensic terms used throughout │ ├── file-system-based/ ← Branch 1: metadata-driven recovery │ ├── README.md │ ├── notes/ │ │ ├── technical-lesson-ntfs.md ← NTFS recovery walkthrough + evidence │ │ └── lab-fat32.md ← FAT32 lab write-up + evidence │ ├── pseudocode/ │ │ └── file_system_recovery.txt │ └── scripts/ │ └── file_carver.py ← offset-driven carver (offsets from istat) │ ├── raw-disk-and-file-signatures/ ← Branch 2: signature-driven recovery │ ├── README.md │ ├── notes/ │ │ ├── technical-lesson-png-carving.md │ │ └── lab-jpeg-carving.md │ ├── pseudocode/ │ │ └── raw_disk_recovery.txt │ └── scripts/ │ ├── carvepng.py ← single-PNG carver (technical lesson) │ └── carve_jpg.py ← multi-JPEG carver (lab solution) │ └── forensic-recovery-suite/ ← the unified automation program ├── README.md ├── pseudocode/ │ └── recovery_suite.txt └── forensic_recovery.py ← staged, interactive end-to-end tool ``` ## 统一工具:Forensic Recovery Suite `forensic-recovery-suite/forensic_recovery.py` 将两个分支整合为一个分阶段的交互式程序。它会: 1. **检查工具链**(`file`、`fdisk`、`xxd`、`foremost`、`binwalk`、The Sleuth Kit、`md5sum`)并提供通过 `apt` 安装缺失组件的选项。 2. **检查镜像**并判断其是否包含可读的文件系统(→ 基于文件系统的恢复)或是非结构化的(→ 原始磁盘恢复)。 3. 沿着正确的路径**恢复**文件。 4. **验证**每个恢复的文件(`file` + MD5)。 在每个阶段之间,它会打印*刚刚发生了什么*以及*接下来要做什么*,然后等待单次按键 —— `y` 继续,其他按键停止。 ``` # 引导式运行(在阶段之间询问 y/N) python3 forensic_recovery.py evidence.dd -o recovered/ # 无人值守运行(自动确认每个阶段) python3 forensic_recovery.py evidence.dd -o recovered/ --yes # 代码质量检查门禁(通过 pycodestyle 检查 PEP 8,仅忽略 E501) python3 forensic_recovery.py --lint forensic_recovery.py ``` 请参阅 [`forensic-recovery-suite/README.md`](forensic-recovery-suite/README.md) 以获取完整设计和分阶段行为说明。 ## 取证数学参考 涵盖了两个分支中使用的每一项计算,并附带了取自本仓库中实际证据的演算示例。更完整的推导过程位于 [`docs/FORMULAS.md`](docs/FORMULAS.md) 中;相同的数学逻辑在 `forensic_recovery.py` 中被实现为命名函数。 贯穿全文,此处使用的镜像**扇区大小 = 512 字节**。 ### 1. 文件占用的扇区数 ``` total_sectors = ceil(file_size_bytes / sector_size) ``` 末尾不完整的扇区也会被完整分配,因此需要向上取整。 ### 2. 第一个和最后一个扇区 ``` first_sector = (from istat metadata) last_sector = first_sector + total_sectors − 1 ``` ### 3. 文件起始偏移量 (SOF) ``` SOF = first_allocation_unit × allocation_unit_size ``` 分配单元**因文件系统而异** —— 这是最需要弄对的关键区别: | 文件系统 | 分配单元 | 单元大小 | SOF 公式 | | --- | --- | --- | --- | | **FAT32**(此处) | 扇区 | 512 B | `first_sector × 512` | | **NTFS** | 簇 | 4096 B(= 8 个扇区) | `first_cluster × 4096` | 应用错误的单元(例如将簇大小应用于 FAT32 扇区镜像)会在不报错的情况下静默偏移**每一个**偏移量 —— 因此必须使用 `fsstat` 从文件系统中读取单元,绝不能假设。 ### 4. 文件结束偏移量 (EOF) ``` EOF = SOF + file_size ``` 使用**逻辑**大小(NTFS 上真实的 `$DATA` 大小),*而不是*按簇取整的*已分配*大小。 ### 5. 雕刻长度 ``` bytes_to_read = EOF − SOF (metadata path) bytes_to_read = (footer + footer_len) − header (signature path) ``` ### 6. 十进制 ↔ 十六进制 取证工具以十六进制报告偏移量。 ``` hex(16,890,880) = 0x101bc00 int("0x101bc00", 16) = 16,890,880 ``` ### 7. 读取 `xxd` 偏移量(原始磁盘) 每一行 `xxd` 显示 16 个字节,并以其第一个字节的偏移量作为标签。签名通常位于该行内部几个字节处: ``` true_offset = line_offset + byte_position_within_line ``` 因为行偏移量总是以 `0` 结尾(16 字节边界),所以加上 `0–15` 的位置只是将最后一个数字替换为 `0–F`(`A=10 … F=15`)。 ### 8. 字节 → MB 与 MiB(以及它们为何不同) ``` MiB (binary) = bytes / 1024² (1,048,576) MB (decimal) = bytes / 1000² (1,000,000) ``` 这两者**并不**相同,这就是为什么对于同一块磁盘,`fdisk` 显示为 "50 MiB",而厂商可能会说是 "52 MB": 这种区别也是证明*覆盖*的关键。在原始磁盘课程中,PNG 头部位于 `0x21C612A`,而下一个文件(一张 JPEG)位于 `0x255F9EF`: 一张 3024×4032 的 PNG 远大于 3.6 MiB,因此它不可能在 JPEG 之前容纳下 —— 证明该 JPEG 被写入**在** PNG 的尾部之上(覆盖)。 ### 9. 簇 ↔ 扇区关系(NTFS) ``` cluster_size = sector_size × sectors_per_cluster (4096 = 512 × 8) ``` ### 10. 覆盖与碎片化(通过偏移量进行诊断) 两者都会产生*部分*文件,但它们是不同的问题: | | 覆盖 | 碎片化 | | --- | --- | --- | | 发生了什么 | 空间被回收;新数据覆盖写入其上 | 文件被拆分在不连续的区域中 | | 偏移量特征 | 一个**外部文件的头**落在了你文件的跨度内 | 你文件自身的页脚/续接部分存在于**其他地方** | | 可恢复? | 否 —— 数据已被销毁 | 是 —— 碎片依然存在 | ## 如何使用本仓库 每个分支都是独立的。从其 `README.md` 开始,阅读 `notes/` 获取完整的案例推演和证据,研究 `pseudocode/`,然后运行 `scripts/`。当你想要实现全流程自动化时,请使用 `forensic-recovery-suite/`。 本仓库中的所有 Python 代码均**符合 PEP 8 规范**(已通过 `pycodestyle --ignore=E501` 验证,符合实验室评分标准)。 ## 开发阶段 本仓库是**逐阶段**构建并提交的,因此开发历史本身就是作品集的一部分: - **阶段 1** — 基于文件系统分支(笔记、伪代码、`file_carver.py`) - **阶段 2** — 原始磁盘分支(笔记、伪代码、`carvepng.py`、`carve_jpg.py`) - **阶段 3** — Forensic Recovery Suite(统一自动化工具) - **阶段 4** — 文档(`docs/`)、公式参考、质量门禁 - **未来** — 扩展到其他文件系统和签名类型 ## 免责声明 这些工具和笔记仅用于**授权的取证检查和教育目的**。从你不拥有或没有明确许可进行检查的系统中恢复数据可能是非法的。
标签:Python, Sleuth Kit, 数字取证, 数据雕刻, 文件恢复, 无后门, 磁盘分析, 自动化脚本, 逆向工具