SecurityRonin/useract-forensic

GitHub: SecurityRonin/useract-forensic

useract-forensic 是一款纯 Rust 数字取证关联引擎,将 shell 历史、设备连接、SRUM、注册表痕迹和 LNK 等多源证据标准化为统一用户活动时间线,并自动检测跨源异常行为。

Stars: 0 | Forks: 0

# useract-forensic [![useract-forensic](https://img.shields.io/crates/v/useract-forensic.svg?label=useract-forensic)](https://crates.io/crates/useract-forensic) [![Docs.rs](https://img.shields.io/docsrs/useract-forensic)](https://docs.rs/useract-forensic) [![Rust 1.81+](https://img.shields.io/badge/rust-1.81%2B-orange.svg)](https://www.rust-lang.org) [![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/9e212fa62e034814.svg)](https://github.com/SecurityRonin/useract-forensic/actions) [![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/advisories-clean-success.svg)](deny.toml) **将众多痕迹文件整合为单一的用户时间线 —— `useract-forensic` 将 shell 历史记录、设备连接、SRUM、注册表痕迹以及 LNK 目标合并为一个统一的 `UserActivity` 数据流,并揭示单一痕迹文件无法展现的跨源信号:从刚插入的 USB 闪存盘中打开文件、在闪存盘挂载时运行命令、在 payload 执行后立即擦除历史记录,或是用户/应用程序向外传输了千兆字节的数据。** 它是**关联层**,而不是另一个解析器。它调用取证工具链中已构建好的读取器 crate,并将其输出标准化为统一的事件格式——因此“谁在何时对哪个文件 / 程序 / 文件夹 / 设备做了什么”都可以在单个排序好的列表中直接读取,并附带分级后的分析发现。 ## 30 秒:合并两个数据源,获取跨源分析发现 ``` use useract_forensic::{build_timeline, audit, ShellHistorySource, DeviceSource}; // Decode each source with its own published reader crate … let entries = shellhist_core::parse_auto(history_bytes, Some(".bash_history")); let devices = peripheral_core::setupapi::parse(setupapi_bytes); // … then correlate them here. let shell = ShellHistorySource::new(&entries); let usb = DeviceSource::new(&devices); let timeline = build_timeline(&[&shell, &usb]); // merged, sorted by epoch for finding in audit(&timeline) { println!("[{:?}] {} — {}", finding.severity, finding.code, finding.note); // [Some(Low)] USERACT-EXEC-DURING-REMOVABLE-MEDIA — the command "tar … /media/usb" ran within … // [Some(Medium)] USERACT-HISTORY-TAMPERED — user activity "unset HISTFILE" disables … } ``` ## 标准化后的目标结构 每个数据源最终都会收敛为一种事件类型: ``` pub struct UserActivity { pub timestamp: Option, // Unix epoch, when the source records it pub actor: Option,// user / SID, when the source attributes it pub action: Action, // Executed | Accessed | Connected | Searched | Typed | HistoryTampered pub subject: Subject, // Command | File | Folder | Device{id, volume_serial} | Query pub source: SourceKind, // which reader produced it pub detail: String, } ``` 接入一个新数据源只需实现一个 `impl ActivitySource { fn activities(&self) -> Vec }` —— 它可以直接插入 `build_timeline`,无需更改任何 API。 ## 数据源 | 数据源 | Crate | 动作 | 状态 | |---|---|---|---| | Shell 命令历史 (bash/zsh/fish/PowerShell) | [`shellhist-core`](https://crates.io/crates/shellhist-core) | `Executed` / `HistoryTampered` | ✅ v0.1 | | 外部设备连接 (`setupapi.dev.log`) | [`peripheral-core`](https://crates.io/crates/peripheral-core) | `Connected` (+ 卷序列号) | ✅ v0.1 | | 基于 **SID** 的用户应用程序执行及网络字节数 | [`srum-parser`](https://crates.io/crates/srum-parser) / [`srum-core`](https://crates.io/crates/srum-core) | `Executed` (行为者!) | ✅ v0.2 | | UserAssist / TypedURLs / ShellBags | [`winreg-artifacts`](https://crates.io/crates/winreg-artifacts) | `Executed` / `Typed` / `Accessed` | ✅ v0.2 | | 最近文件 LNK (带有用于完成设备匹配的卷序列号) | [`lnk-core`](https://crates.io/crates/lnk-core) | `Accessed` (文件 + 序列号) | ✅ v0.2 | | Jump Lists —— 特定应用程序的最近/固定项目 (`DestList` MRU 访问时间 + 来源主机) | [`lnk-core`](https://crates.io/crates/lnk-core) | `Accessed` (文件 + 序列号) | ✅ v0.3 | SRUM 是目前最强大的数据源——它是第一个将活动归属于特定 **SID** 的数据源,它通过 `SruDbIdMapTable` 解析 SRUM 的整数外键。现在,ShellBags 可以解码为真实的文件夹名称(通过 `winreg-artifacts` + `shellitem` 原语实现),而 Jump Lists 则作为最近项目数据源加入(`lnk-core` 0.3)。详见 [`docs/roadmap.md`](docs/roadmap.md)。 ## 异常代码 每一项发现都是一个**观察结果**(“与……一致”);检验人员需自行得出最终结论。这些代码是稳定且公开的契约规范。 | 代码 | 严重性 | 类别 | 观察描述 | |---|---|---|---| | `USERACT-FILE-ON-EXTERNAL-DEVICE` | 中等 | 威胁 | 在卷序列号与已连接外部设备相匹配的卷上访问了文件/文件夹(即 LNK ⋈ 外设卷序列号匹配)—— 与可移动介质的数据传入/传出一致 (MITRE T1052 / T1091) | | `USERACT-NETWORK-EXFIL-VOLUME` | 中等 | 威胁 | SRUM 网络记录中每个时间间隔的 `bytes_sent` 超过了保守设定的 256 MiB 阈值 —— 这是一个分级的**线索**(而非定论),与批量数据外泄行为一致 (MITRE T1048 / T1052) | | `USERACT-EXEC-DURING-REMOVABLE-MEDIA` | 低 | 威胁 | 在可移动大容量存储设备连接后的一小时内执行了 shell 命令(时间跨源关联)—— 与涉及外部介质的活动一致 (MITRE T1052 / T1091) | | `USERACT-HISTORY-TAMPERED` | 中等 | 隐藏痕迹 | 时间线中存在清除历史记录的活动 —— 与反取证的历史记录篡改一致 (MITRE T1070.003) | **卷序列号关联** (`device_file_volume_joins`) 已生效:携带 `volume_serial`(来自链接的 `VolumeID`)的 LNK `Subject::File` 将与连接时具有相同序列号的 `Subject::Device` 进行匹配,从而触发 `USERACT-FILE-ON-EXTERNAL-DEVICE`。 ## 信任,但需验证 `useract-forensic` 消费的是由攻击者可控的、已解码的证据并对其进行关联分析: - **`#![forbid(unsafe_code)]`** —— 没有 FFI,没有 C 绑定,没有裸指针。 - **无 panic** —— 该工作区在生产代码中禁止使用 `clippy::unwrap_used` 和 `clippy::expect_used`;关联逻辑会优雅降级,绝不崩溃。 - 该库拥有 **100% 的行覆盖率**,`clippy -D warnings` 零警告。 - **基于真实痕迹文件验证** —— 集成测试输入了由真实 `bash` 子 shell 写入的 `.bash_history` 文件(使用公开的 `shellhist_core::parse_auto` 解码)、真实的 `peripheral_core::DeviceConnection`、共享卷序列号的 `lnk_core::ShellLink` 和 `peripheral_core::DeviceConnection`、通过 `SruDbIdMapTable` 归属的 SRUM `NetworkUsageRecord`,以及 `winreg_artifacts` 的 UserAssist 条目 —— 以断言时间线会按 epoch 时间顺序合并所有数据源、卷序列号关联会触发 `USERACT-FILE-ON-EXTERNAL-DEVICE`,且 SRUM 活动已归属到具体行为者(`tests/real_data.rs`)。 ``` cargo add useract-forensic cargo test ``` [隐私政策](https://securityronin.github.io/useract-forensic/privacy/) · [服务条款](https://securityronin.github.io/useract-forensic/terms/) · © 2026 Security Ronin Ltd
标签:Rust, 事件关联, 可视化界面, 数字取证, 网络流量审计, 自动化脚本, 通知系统