useract-forensic
One per-user timeline from many artifacts — useract-forensic merges shell history, device connections, and (soon) LNK / shellbags / SRUM / registry MRU into a single UserActivity stream and surfaces the cross-source signals no one artifact can show: a command run while a USB stick was mounted, history wiped right after a payload ran.
It is the correlation layer, not another parser. It consumes the forensic fleet's already-built reader crates and normalizes their output into one uniform event — so "who did what, when, to which file / program / folder / device" reads off a single sorted list, with graded findings attached.
30 seconds: merge two sources, get cross-source findings
use ;
// Decode each source with its own published reader crate …
let entries = parse_auto;
let devices = parse;
// … then correlate them here.
let shell = new;
let usb = new;
let timeline = build_timeline; // merged, sorted by epoch
for finding in audit
What it normalizes into
Every source collapses into one event type:
A new source is one impl ActivitySource { fn activities(&self) -> Vec<UserActivity> } away — it slots straight into build_timeline with no API change.
v0.1 sources, and the v0.2 roadmap
| Source | Crate | Action | Status |
|---|---|---|---|
| Shell command history (bash/zsh/fish/PowerShell) | shellhist-core |
Executed / HistoryTampered |
✅ v0.1 |
External device connections (setupapi.dev.log) |
peripheral-core |
Connected (+ volume serial) |
✅ v0.1 |
| Recent-file LNK (and the volume serial that completes the device join) | lnk-core |
Accessed (File) |
v0.2 |
| Shellbags (folder access) | shellbag-core |
Accessed (Folder) |
v0.2 |
| Per-user app exec + network bytes by SID | srum-core |
Executed / Connected (actor!) |
v0.2 |
| UserAssist / RecentDocs / MRU / MountPoints2 | winreg-artifacts |
Executed / Accessed |
v0.2 |
The v0.2 sources need those reader crates published first. SRUM is the strongest — the first source that attributes activity to a specific SID. See docs/roadmap.md.
The anomaly codes
Each finding is an observation ("consistent with …"); the examiner draws the conclusions. Codes are a stable, published contract.
| Code | Severity | Category | What it observes |
|---|---|---|---|
USERACT-EXEC-DURING-REMOVABLE-MEDIA |
Low | Threat | A shell command executed within an hour of a removable mass-storage device being connected (temporal cross-source join) — consistent with activity involving external media (MITRE T1052 / T1091) |
USERACT-HISTORY-TAMPERED |
Medium | Concealment | A history-clearing activity present in the timeline — consistent with anti-forensic history tampering (MITRE T1070.003) |
A volume-serial join seam (device_file_volume_joins) is implemented generically over UserActivity today and tested by construction; it activates with zero code change the moment a v0.2 LNK / shellbag source contributes a file subject carrying a volume serial.
Trust, but verify
useract-forensic consumes attacker-controllable, already-decoded evidence and correlates it:
#![forbid(unsafe_code)]— no FFI, no C bindings, no raw pointers.- Panic-free — the workspace denies
clippy::unwrap_usedandclippy::expect_usedin production code; correlation degrades gracefully, never crashes. - 100% line coverage on the library,
clippy -D warningsclean. - Validated on real artifacts — the integration test feeds a
.bash_historyfile written by a genuinebashsubshell (decoded with the publishedshellhist_core::parse_auto) plus a realperipheral_core::DeviceConnection, and asserts the timeline merges and both findings fire (tests/real_data.rs).
Privacy Policy · Terms of Service · © 2026 Security Ronin Ltd