SecurityRonin/useract-forensic
GitHub: SecurityRonin/useract-forensic
useract-forensic 是一款纯 Rust 数字取证关联引擎,将 shell 历史、设备连接、SRUM、注册表痕迹和 LNK 等多源证据标准化为统一用户活动时间线,并自动检测跨源异常行为。
Stars: 0 | Forks: 0
# useract-forensic
[](https://crates.io/crates/useract-forensic)
[](https://docs.rs/useract-forensic)
[](https://www.rust-lang.org)
[](LICENSE)
[](https://github.com/sponsors/h4x0r)
[](https://github.com/SecurityRonin/useract-forensic/actions)
[](https://github.com/rust-secure-code/safety-dance)
[](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, 事件关联, 可视化界面, 数字取证, 网络流量审计, 自动化脚本, 通知系统