forensic-catalog
Forensic knowledge as code — zero-dependency, std-only, embeds in any Rust binary.
Quick start
[]
= "0.1"
use is_suspicious_port;
use ;
// Instant port check — no allocations
assert!; // Metasploit default
// Pull every Critical-priority artifact, sorted for triage
let critical: = CATALOG
.for_triage
.into_iter
.filter
.collect;
What's inside
| Module | Covers | Key function / constant |
|---|---|---|
ports |
C2 ports, Cobalt Strike, Tor, WinRM, RAT defaults | is_suspicious_port(port) |
lolbins |
Windows + Linux LOLBins | WINDOWS_LOLBINS, LINUX_LOLBINS |
processes |
Known malware process names | MALWARE_PROCESS_NAMES |
commands |
Reverse shells, PowerShell abuse, download cradles | pattern slices |
paths |
Suspicious filesystem paths | path slices |
persistence |
Windows Run keys, Linux cron/init, macOS LaunchAgents | WINDOWS_RUN_KEYS, LINUX_PERSISTENCE_PATHS, MACOS_PERSISTENCE_PATHS |
catalog |
150+ ArtifactDescriptors with MITRE ATT&CK, triage priority, decode logic |
CATALOG |
antiforensics |
Anti-forensics indicator paths and patterns | indicator slices |
encryption |
FDE artifact paths, credential store locations | path slices |
remote_access |
Remote access tool indicators (RMM, RAT, VPN) | indicator slices |
third_party |
OneDrive, PuTTY, and other third-party app artifact paths | path slices |
pca |
Windows Program Compatibility Assistant artifacts | path / key constants |
references |
Queryable authoritative source map for each public module | module_references(name) |
The ForensicCatalog API
The catalog module is the power feature. Every artifact descriptor is a const-constructible ArtifactDescriptor — MITRE ATT&CK tags, triage priority, retention period, cross-correlation links, and embedded decode logic all in one static struct. No I/O, no allocation until you query.
Query by MITRE technique
use CATALOG;
// All artifacts relevant to process injection
let artifacts = CATALOG.by_mitre;
for d in &artifacts
Triage-ordered collection list
let ordered = CATALOG.for_triage; // Critical → High → Medium → Low
for d in ordered.iter.take
Keyword search
let hits = CATALOG.filter_by_keyword;
// matches on name or meaning, case-insensitive
Structured filter
use ;
let hits = CATALOG.filter;
Decode raw artifact data
use CATALOG;
let descriptor = CATALOG.by_id.unwrap;
let record = CATALOG.decode?;
// record.fields — decoded field name/value pairs
// record.timestamp — ISO 8601 UTC string, if present
// record.mitre_techniques — inherited from the descriptor
| Field | Type | Description |
|---|---|---|
id |
&'static str |
Machine-readable identifier (e.g. "userassist") |
name |
&'static str |
Human-readable display name |
artifact_type |
ArtifactType |
RegistryKey, RegistryValue, File, Directory, EventLog, MemoryRegion |
hive |
Option<HiveTarget> |
Registry hive, or None for file/memory artifacts |
key_path |
&'static str |
Path relative to hive root |
scope |
DataScope |
User, System, Network, Mixed |
os_scope |
OsScope |
Win10Plus, Linux, LinuxSystemd, etc. |
decoder |
Decoder |
Identity, Rot13Name, FiletimeAt, BinaryRecord, Utf16Le, … |
meaning |
&'static str |
Forensic significance |
mitre_techniques |
&'static [&'static str] |
ATT&CK technique IDs |
fields |
&'static [FieldSchema] |
Decoded output field schema |
retention |
Option<&'static str> |
How long artifact typically persists |
triage_priority |
TriagePriority |
Critical / High / Medium / Low |
related_artifacts |
&'static [&'static str] |
Cross-correlation artifact IDs |
Design philosophy
- Zero dependencies —
Cargo.tomlhas no[dependencies]. No transitive supply-chain risk. - No I/O — every function operates on values passed in. Reading files, registry, or memory is the caller's job.
const/static-friendly —ArtifactDescriptorand all its enums are constructible inconstcontext. Extend the catalog at compile time.- Test-driven — every indicator table has positive and negative test cases. Run
cargo testto verify coverage. - Additive — each module is independent. Pull in only what you need.
Source provenance
Module-level research provenance is available through forensic_catalog::references.
use module_references;
let refs = module_references.unwrap;
assert!;
Artifact-level provenance remains embedded directly in the catalog:
use CATALOG;
let desc = CATALOG.by_id.unwrap;
assert!;
Blog Archive Ingestion
The repo also includes a dependency-free blog scraper for building a local DFIR research corpus from archive pages, sitemaps, or Blogger feeds:
Used by
RapidTriage— live incident response triage tool