SecurityRonin/trash-forensic

GitHub: SecurityRonin/trash-forensic

跨平台回收站取证分析库,从五大操作系统的已删除文件工件中恢复删除记录并对篡改痕迹进行自动分级。

Stars: 0 | Forks: 0

# trash-forensic [![trash-core](https://img.shields.io/crates/v/trash-core.svg?label=trash-core)](https://crates.io/crates/trash-core) [![trash-forensic](https://img.shields.io/crates/v/trash-forensic.svg?label=trash-forensic)](https://crates.io/crates/trash-forensic) [![Docs.rs](https://img.shields.io/docsrs/trash-forensic)](https://docs.rs/trash-forensic) [![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE) [![Sponsor](https://img.shields.io/badge/sponsor-h4x0r-ea4aaa?logo=github-sponsors)](https://github.com/sponsors/h4x0r) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/d4d0cc7928200600.svg)](https://github.com/SecurityRonin/trash-forensic/actions/workflows/ci.yml) [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance) [![security advisories](https://img.shields.io/badge/security-cargo--deny-success.svg)](deny.toml) **谁在何时删除了什么 —— 从每个主流操作系统的回收站中恢复,并已为您对可疑条目进行了分级。** 将其指向 Windows 的 `$Recycle.Bin`、Linux 的 XDG 回收站、macOS 的 Trash `.DS_Store`、Android 的 `.trashed-` 文件,或是从镜像中提取出的 iOS `Photos.sqlite`,即可针对每个已删除的项目获取:它来自哪里、何时被删除,以及针对任何看似遭到篡改内容的严重性分级发现结果。 ## 结果展示,只需 12 行代码 ``` [dependencies] trash-forensic = "0.2" # pulls in trash-core; all five OS readers on by default ``` ``` use trash_core::{parse_index, scan_pairs}; use trash_forensic::audit_pair; for pair in scan_pairs(recycle_bin_dir)? { // $Recycle.Bin\\ let bytes = std::fs::read(&pair.index_path)?; if let Ok(index) = parse_index(&bytes) { // what was deleted, and when println!("{} ({} bytes) deleted {:?}", index.original_path, index.original_size, index.deleted_at); // …and anything suspicious about it, already graded for finding in audit_pair(&index, &pair) { println!(" [{:?}] {} — {}", finding.severity, finding.code, finding.note); } } } # Ok::<(), std::io::Error>(()) ``` ``` C:\Users\victim\Documents\secret plan.docx (1234 bytes) deleted Some(2024-01-15T10:30:00Z) [High] RECYCLEBIN-PATH-TRAVERSAL — stored original path ..\..\Windows\… contains parent-directory ('..') components — consistent with a crafted name rather than a normal deletion ``` 每个读取器都遵循相同的模式 —— 将工件解码为已删除项目记录,然后对其进行分级。正常的记录只打印自身信息,不产生任何发现结果。 ## 五种操作系统,一套术语 “Trash”是统称;每个平台都保留其原生的工件与入口点。每个读取器模块都由同名的 Cargo feature 控制(默认全部开启),因此单平台使用者可以通过 `--no-default-features --features ` 来剔除其他平台的依赖。 | OS | 工件 | 读取器 | |---|---|---| | **Windows** | `$Recycle.Bin\\` `$I` 索引 ⇄ `$R` 内容 | [`windows::parse_index`] + [`scan_pairs`] | | **Linux** | freedesktop.org / XDG `Trash/info/*.trashinfo` ⇄ `files/` | [`linux::parse_trashinfo`] + [`scan_trash`] | | **macOS** | Trash `.DS_Store` 还原记录 (`ptbN`/`ptbL`) | [`macos::parse_put_back`] | | **Android** | `MediaStore` `.trashed--` 文件名编解码器 | [`android::parse_trashed_name`] | | **iOS** | `Photos.sqlite` 最近删除 (`ZASSET.ZTRASHEDSTATE`) | [`ios::parse_trashed_assets`] | ## 标记内容 每项发现都是一个**观测结果**(“与……一致”);由检验人员得出结论。这些代码是一项稳定、公开的契约。 | 代码 | 类别 | 严重性 | 平台 | 观测内容 | |---|---|---|---|---| | `RECYCLEBIN-CONTENT-PURGED` | 残留 | 中 | Windows | `$I` 元数据尚存,但 `$R` 内容文件已丢失 | | `RECYCLEBIN-PATH-TRAVERSAL` | 隐藏 | 高 | Windows | 存储的路径通过 `..` 组件逃逸出了其所在目录 | | `RECYCLEBIN-DELETION-TIME-MISSING` | 完整性 | 低 | Windows | 删除的 `FILETIME` 为零 —— 从未设置或已被清除 | | `TRASH-CONTENT-PURGED` | 残留 | 中 | Linux | `.trashinfo` 尚存,但其 `files/` 内容已丢失 | | `TRASH-PATH-TRAVERSAL` | 隐藏 | 高 | Linux | 存储的 `Path=` 包含规范禁止的 `..` | | `TRASH-DELETION-TIME-MISSING` | 完整性 | 中 | Linux, iOS | 删除时间戳缺失或无法解析 | | `TRASH-ORPHAN-METADATA` | 残留 | 中 | macOS | `.DS_Store` 还原记录尚存,但其对应项目已丢失 | | `TRASH-PUTBACK-TRAVERSAL` | 隐藏 | 高 | macOS | 存储的 `ptbN`/`ptbL` 通过 `..` 逃逸出了其所在目录 | | `TRASH-EXPIRED-RESIDUE` | 残留 | 低 | Android, iOS | 项目在超过其保留/过期窗口后依然存在 | | `TRASH-MALFORMED-NAME` | 结构 | 低 | Android | 无法解析为 token 的 `trashed`/`pending` 名称 | 发现结果将违规值作为证据携带,并标有分析器名称、版本号以及单项作用域,因此它们能够与系统中所有其他 [`forensicnomicon`](https://crates.io/crates/forensicnomicon) 分析器的结果统一汇总。 ## 无需 Rust 的路径 这两个 crate 是基础构建块;为了实现将回收站证据与镜像其余部分相关联的端到端时间线,它们将数据接入 [`issen`](https://github.com/SecurityRonin/issen) —— SecurityRonin 的检验前端 —— 这样您无需编写任何 Rust 代码即可获得发现结果。 ## 双 crate 架构分离 - **[`trash-core`](https://crates.io/crates/trash-core)** —— 读取器。每个 OS(`windows`、`linux`、`macos`、`android`、`ios`)各有一个模块,分别将其原生工件解码为类型化记录,并将元数据与内容配对。不产生发现结果。iOS 读取器基于纯 Rust 实现的 [`sqlite-core`](https://crates.io/crates/sqlite-core) 引擎构建(无需 `libsqlite3`)。 - **[`trash-forensic`](https://crates.io/crates/trash-forensic)** —— 分析器。将解析出的记录及其配对内容评定为标准的 `forensicnomicon` 发现结果。这种分离镜像了 `ntfs-core`/`ntfs-forensic`。 ## 信任,但要验证 每个读取器都将其输入视为由攻击者控制。二进制解析器(`$I`、`.DS_Store`)使用边界检查读取,针对恶意长度字段限制内存分配,在遍历 macOS B-tree 时带有循环防护,并返回携带违规值的类型化错误,而不是直接 panic。在整个工作区中,`unsafe` 是被**严格禁止**的。每个处理不可信输入的读取器都有一个 `cargo fuzz` 目标,并保持着*绝不 panic*(must-not-panic)的不变性。 正确性是对照**独立的基准实现(oracles)**进行检查的,而不仅仅是自我一致的往返验证: - **Windows** —— 基于构建的 libyal [*Windows Recycle.Bin file formats*](https://github.com/libyal/dtformats/blob/main/documentation/Windows%20Recycle.Bin%20file%20formats.asciidoc) 规范测试固件,并使用 [rifiuti2](https://github.com/abelcheung/rifiuti2) 进行交叉解码。 - **Linux** —— freedesktop.org [Trash Specification v1.0](https://specifications.freedesktop.org/trash/latest/);百分号解码和日期解析已与 Python 的 `urllib`/`datetime` 交叉核对。 - **macOS** —— 由 al45tair 的 [`ds_store`](https://pypi.org/project/ds_store/) 库生成的 `.DS_Store`;对真实 `~/.Trash/.DS_Store` 的解码与该基准引擎**在 62 条还原记录上逐字节一致**。 - **Android** —— 编解码器的匹配/拆分决策与作为正则表达式基准运行的 AOSP `FileUtils.java` 中的 `PATTERN_EXPIRES_FILE` 保持一致。 - **iOS** —— 由本读取器和 `sqlite3` CLI 共同解码的真实 `Photos.sqlite`,在文件名和 `ZTRASHEDDATE` 上保持一致。 请参阅 [`docs/validation.md`](docs/validation.md)。 [隐私政策](https://securityronin.github.io/trash-forensic/privacy/) · [服务条款](https://securityronin.github.io/trash-forensic/terms/) · © 2026 Security Ronin Ltd
标签:Rust, 可视化界面, 回收站分析, 数字取证, 数据恢复, 网络流量审计, 自动化脚本, 通知系统