shellhist-forensic 0.1.0

Forensic anomaly auditor for shell command history — history clearing, timestamp regression, and download-pipe-to-shell as graded report::Finding, built on shellhist-core
Documentation
# shellhist-forensic

[![shellhist-forensic](https://img.shields.io/crates/v/shellhist-forensic.svg?label=shellhist-forensic)](https://crates.io/crates/shellhist-forensic)
[![shellhist-core](https://img.shields.io/crates/v/shellhist-core.svg?label=shellhist-core)](https://crates.io/crates/shellhist-core)
[![Docs.rs](https://img.shields.io/docsrs/shellhist-forensic)](https://docs.rs/shellhist-forensic)
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)
[![CI](https://github.com/SecurityRonin/shellhist-forensic/actions/workflows/ci.yml/badge.svg)](https://github.com/SecurityRonin/shellhist-forensic/actions)
[![Sponsor](https://img.shields.io/badge/sponsor-h4x0r-ea4aaa?logo=github-sponsors)](https://github.com/sponsors/h4x0r)

**Point it at a shell-history file, get back severity-graded anomalies — history clearing, back-dated entries, download-pipe-to-shell payloads, and encoded PowerShell as `forensicnomicon::report::Finding`s.**

```toml
[dependencies]
shellhist-forensic = "0.1"   # pulls in shellhist-core
```

```rust
use shellhist_core::parse_auto;
use shellhist_forensic::{audit, source};

let entries = parse_auto(history_bytes, Some(".bash_history"));

for anomaly in audit(&entries) {
    let finding = anomaly.to_finding(source("host"));
    println!("[{:?}] {} — {}", finding.severity, finding.code, finding.note);
    // e.g. [Some(Medium)] SHELLHIST-REMOTE-EXEC-PIPE — the command "curl … | sh" downloads and pipes …
}
```

`audit` grades an entry stream; `audit_findings(&entries, scope)` does the parse-to-`Finding` conversion in one call. Malformed history degrades to plain lines upstream in `shellhist-core`, never a panic.

## The anomaly codes

Each anomaly is an **observation** ("consistent with …"); the examiner draws the conclusions. Codes are a stable, published contract.

| Code | Severity | Category | What it observes |
|---|---|---|---|
| `SHELLHIST-HISTORY-DISABLED` | Medium | Concealment | A surviving command that disables or clears history (`unset HISTFILE`, `history -c`, …) — consistent with anti-forensic history tampering (MITRE T1070.003) |
| `SHELLHIST-TIMESTAMP-REGRESSION` | Medium | Integrity | An entry whose epoch precedes its predecessor's — history went backwards in time, consistent with injected or back-dated entries |
| `SHELLHIST-REMOTE-EXEC-PIPE` | Medium | Threat | A download piped straight into a shell (`curl … \| sh`) — consistent with remote payload execution (MITRE T1059 / T1105) |
| `SHELLHIST-PWSH-ENCODED-CMD` | Medium | Threat | An encoded or policy-bypassing PowerShell invocation — consistent with obfuscated execution (MITRE T1059.001 / T1027) |

`audit(&entries)` returns the typed [`HistAnomaly`] stream; each anomaly emits a graded `report::Finding` via `to_finding(source)`. `source(scope)` stamps the analyzer provenance.

## The two-crate split

This crate is the **analyzer**; the **reader** is [`shellhist-core`](https://crates.io/crates/shellhist-core) (bash, zsh `EXTENDED_HISTORY`, fish, and PowerShell PSReadLine into one uniform `HistoryEntry` stream, with `parse_auto` / `detect` and per-format `parse` entry points). The split mirrors `ntfs-core`/`ntfs-forensic`. Together they feed [`issen`](https://github.com/SecurityRonin/issen) for cross-artifact correlation.

## Trust, but verify

Built for untrusted history files from potentially compromised systems: `#![forbid(unsafe_code)]`; panic-free on crafted input (the workspace denies `clippy::unwrap_used` / `expect_used` in production code, parsing is lenient and bounds-checked); fuzzed with five `cargo-fuzz` targets (one per format plus the full parse→audit pipeline) and exercised end-to-end against a history file generated by a real `bash` subshell, with its planted traces re-surfaced.

---

[Privacy Policy](https://securityronin.github.io/shellhist-forensic/privacy/) · [Terms of Service](https://securityronin.github.io/shellhist-forensic/terms/) · © 2026 Security Ronin Ltd