SecurityRonin/forensic-carve

GitHub: SecurityRonin/forensic-carve

一个介质无关的数字取证 carving 框架,通过单趟签名扫描引擎从磁盘未分配空间或内存镜像中按格式恢复已删除的数据构件。

Stars: 0 | Forks: 0

# forensic-carve [![Crates.io](https://img.shields.io/crates/v/forensic-carve.svg)](https://crates.io/crates/forensic-carve) [![Docs.rs](https://docs.rs/forensic-carve/badge.svg)](https://docs.rs/forensic-carve) [![Rust 1.75+](https://img.shields.io/badge/rust-1.75%2B-blue.svg)](https://www.rust-lang.org) [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/SecurityRonin/forensic-carve/actions/workflows/ci.yml) [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) [![fuzzed](https://img.shields.io/badge/fuzzed-libFuzzer-orange.svg)](fuzz/) **一个 carving 契约,一个单趟扫描引擎 —— 同一个 carver 既可以从未分配的磁盘中恢复已删除的 artifact,也可以从内存镜像中恢复。** `forensic-carve` 是 SecurityRonin 舰队的 carving 基础。基于格式的 **carver** 只能看到 `&[u8]` 窗口,因此从构造上来说它是与介质无关的;**扫描引擎** 对提供的区域(磁盘未分配区或内存 VAD 区域)运行一次 aho-corasick 检测,仅实例化每次命中所需的窗口(检测 ≠ 实例化 —— 大型 artifact 永远不会被截断为扫描块),并将其交给匹配的 carver。 ## Carver 非常小巧 ``` use forensic_carve::{Carver, Signature, CarveContext, CarvedItem, RecoveryMethod}; struct SqliteCarver; impl Carver for SqliteCarver { fn format(&self) -> &'static str { "sqlite" } fn signatures(&self) -> &[Signature] { const S: &[Signature] = &[Signature::new(b"SQLite format 3\0", 0)]; S } fn max_window(&self) -> u64 { 1 << 30 } fn carve(&self, window: &[u8], ctx: &CarveContext) -> Vec { // validate the header, bound the DB, then: vec![CarvedItem::artifact_bytes( "sqlite", ctx.base_offset(), 0.9, ctx.recovery_method(), // echoed — UnallocatedCarve on disk, MemoryCarve in RAM window.to_vec(), )] } } ``` ## 一次扫描,任意介质 ``` use forensic_carve::{sweep, Region, CarveOptions, RecoveryMethod, registered_carvers}; let opts = CarveOptions { recovery_method: RecoveryMethod::UnallocatedCarve, ..Default::default() }; let items = sweep(&source, unallocated_regions, ®istered_carvers(), &opts); // each item: the medium-neutral CarvedItem + its source offset + the region's attribution tag ``` `source` 可以是任何 `RegionSource`(一个带位置的 `read_at`):一个磁盘 `ImageSource`,或者是一个内存 `VirtualAddressSpace`,其 `read_virt` 可以将物理上不连续的页进行反离散化收集。Carver 通过 `inventory::submit!` 注册自己,因此强制链接它们的二进制文件可以通过 `registered_carvers()` 收集整个集合 —— 消费者永远不会依赖于解析器 crate。 ## 恢复术语表 每个恢复出的 item 都带有一个 `RecoveryMethod` —— 指明它是 *如何* 被恢复的,这由运行了哪种扫描来设定(carving 本身 **就是** 一种恢复方法): | 变体 | 来源 | |---|---| | `Tombstone` | 文件系统记录的删除操作 (`--deleted`) | | `FileInternalCarve` | 定位到的 artifact 自身的 slack(freelist/WAL/`ElfChnk`) | | `UnallocatedCarve` | 全盘未分配空间 carving (`--unallocated`) | | `MemoryCarve` | 内存镜像(进程 VA 区域或物理页帧) | ## 信任,但需验证 - **输入已 fuzz。** `fuzz_sweep` 驱动任意字节、越界/零长度区域以及任意块大小通过引擎(超过 13.8 万次执行,0 次崩溃)。 - **通过 lint 保证无 panic。** 生产环境中严禁使用 `unwrap_used`/`expect_used`;引擎在任何格式错误的输入下都会返回 *空 items*,而不是触发 panic。 - **`#![forbid(unsafe_code)]`** —— 在任何地方都不使用 `unsafe`。 指导设计:SecurityRonin 舰队 ADR 0001(*carving —— 一个 flag 分类法,一个扫描引擎,一个契约*)。
标签:可视化界面, 通知系统