Skip to content

v0.21.0

Choose a tag to compare

@hasamba hasamba released this 15 Jun 13:12
· 8 commits to master since this release

[0.21.0] - 2026-06-15

Added

  • GraphRAG for "Ask the case" — the Ask prompt is now grounded with the deterministic evidence-chain graph (process spawns, file lineage, lateral movement, network flows) serialized as causal edges with backing event ids, so multi-hop questions ("trace the path from the phishing email to the Domain Controller") are answered by following real graph relationships instead of the flat timeline; edge count capped by DFIR_ASK_GRAPH_MAX_EDGES (default 120, highest-severity first), pure + no extra AI call (closes #98).
  • Memory-forensics "Next-Step" agent — when a case has Volatility 3 / Rekall output imported, one AI call reads the memory evidence (process tree, malfind, connections, command lines), spots anomalies (e.g. svchost.exe without a services.exe parent, injection, suspicious connections), and proposes the exact next Volatility command to run (vol -f <image> windows.malfind --pid 1234); a ✨ Suggest next steps button in a Memory Next Steps panel shown only when memory evidence exists, ephemeral, POST /cases/:id/memory/next-steps (closes #101).
  • Volatility 3 text-output import — the memory importer now also ingests the default vol <plugin> TEXT/grid renderer (banner + TAB-separated table), not just the -r json renderer; malfind/pstree hexdump+disasm continuation lines are skipped and rows are parsed into the same shape as the JSON path, so malfind.txt/pslist.txt etc. import directly via the unified Import button (#101).
  • Natural-language Query Translator — a dashboard search bar that turns a plain-English hunting request ("PowerShell downloading a file and then executing it", "outbound RDP from this host") into a runnable query for each enabled platform — Velociraptor VQL, Defender/Sentinel KQL, Elastic ES|QL, Splunk SPL, Sigma, YARA, Suricata — grounded in each platform's real schema; one AI call, ephemeral, the Velociraptor query one-click-deploys via the existing hunt flow; platforms gated by DFIR_HUNT_PLATFORMS, POST /cases/:id/translate-query (closes #100).
  • One-click artifact push from the browser extension — on recognized DFIR consoles (Splunk / Velociraptor / Elastic-Kibana / CrowdStrike) the extension injects a Push to DFIR-Companion button that intercepts the clean JSON the tool already fetched (a MAIN-world fetch/XHR hook, injected only on recognized tools) — or scrapes the visible results table as a fallback — and POSTs it to the selected case's unified /import route on explicit analyst click; per-tool site adapters, no-op on unrecognized sites. Pushed artifacts trigger the same cross-case dashboard warning as screenshots when they land in a case the dashboard isn't viewing, and turning AI on now synthesizes evidence imported while it was off (closes #102).
  • Timeline-gap hypotheses & shadow-artifact hunting — for each flagged silent period, one AI call hypothesises what the attacker did during the silence (grounded in the events bracketing the gap) and pairs every gap with a deterministic catalog of shadow artifacts (USN Journal, SRUM, Prefetch, Amcache, ShimCache, BAM, MFT, UserAssist, LNK) — each a deployable Velociraptor collection to reconstruct the missing window; a ✨ Hypothesize gaps button in the Timeline Gaps panel, ephemeral, POST /cases/:id/timeline-gaps/hypothesize (closes #96).
  • Sort timeline by date or severity — per-column ▲/▼ sort arrows in the Forensic Timeline header: sort by date (oldest/newest first) from the Timestamp column and by severity (most/least severe first) from the Message column; client-side only, persisted across reloads, no server round-trip (closes #104).
  • Payload deobfuscation — automatically detects and decodes base64-obfuscated PowerShell (-enc/-EncodedCommand) and [Convert]::FromBase64String payloads in the forensic timeline; extracts hidden IOCs (URLs, IPs, hashes, domains) from decoded content; shows an expandable [Decoded] block per event in the dashboard; applied deterministically (no AI) on every import and push-ingest, and on demand via POST /cases/:id/deobfuscate (closes #97).
  • CISA KEV integration — cross-reference CVEs found in the forensic timeline and IOCs against the CISA Known Exploited Vulnerabilities catalog; KEV-matched CVEs are surfaced in the synthesis context (initial-access signal) and in a new report §4.5.1; load the catalog from the CISA feed URL or a local file via Settings → KEV; deterministic, no AI, opt-in (closes #99).
  • Import from DFIR-IRIS — pull an existing IRIS case's assets/IOCs/timeline into a Companion case (the reverse of the push); deterministic importIris / irisImport.ts maps timeline events (severity from colour, MITRE/asset/hash from tags+content), IOCs (type from the IRIS ioc-type or value shape), and assets → evidence events; a compact "Import case" toolbar icon opens a chooser (Investigation snapshot or From DFIR-IRIS) + npm run iris:import; Settings → DFIR-IRIS "Test / reconnect" rebuilds the client from .env and pings so config (or IRIS coming back online) applies without a restart (closes #88).
  • Webhook push ingestPOST /cases/:id/push lets external tools (SIEM webhooks, custom scripts) push alerts into a case in real time; token auth (X-DFIR-Key: global DFIR_PUSH_TOKEN and/or a per-case token in Settings), importDetect routing, same import → diff → re-synthesize pipeline, 202-and-async (closes #84).
  • Velociraptor live monitoring — stream a CLIENT_EVENT artifact (e.g. Windows.Events.ProcessCreation) into a case as events fire, from one endpoint or all enrolled clients; one-click auto-monitor starts an all-clients monitor for every artifact already enabled in Velociraptor's Client Monitoring table; server-side poller (DFIR_VELO_MONITOR_POLL_S, default 30s) with a persisted cursor (state/velo-monitor.json) so a restart never re-ingests; Settings → Velociraptor → Live Monitoring + a 🔴 LIVE dashboard badge (closes #84).
  • Velociraptor reconnectPOST /velociraptor/reconnect (Settings → Velociraptor → Reconnect) re-reads DFIR_VELOCIRAPTOR_* from .env, rebuilds the client, and refreshes the inventory (the reachability probe), so configuring Velociraptor after boot — or the server coming back online — applies without a companion restart; the startup inventory refresh now retries with backoff so a Velociraptor that comes up shortly after boot self-heals (#84).
  • IOC block-list export — one-click block-list for network/firewall teams via Export → IOC block-list…; three formats: plain TXT (grouped by type), minimal CSV, and STIX-indicators-only bundle; filters by min severity (default Medium), IOC type, and verdict-confirmed-only; GET /cases/:id/export/ioc-blocklist (closes #87).
  • Wazuh importer — deterministic import of Wazuh SIEM/EDR alert exports (alerts.json, NDJSON, Wazuh API { data: { affected_items } } envelope); rule.level → severity, MITRE from rule.mitre.technique, agent.name → asset, data field IOCs (IP/hash/URL); auto-detected by the unified Import button (closes #85).
  • TheHive importer — deterministic importTheHive / theHiveImport.ts; TheHive 5 case, alert, and observable exports → forensic events + IOCs; severity from TheHive's 1–4 scale, MITRE from ATT&CK-tagged tags, TLP/PAP labels prepended, observables mapped by dataType; Elasticsearch hit-wrapper guard (closes #86).
  • Log gap analysis — flag suspiciously long silent periods in the forensic timeline; a gap where every source went dark (High, earns a finding) is the classic cleared-logs/stopped-collector signature, a single tool going quiet while others log is partial (Medium). Density-aware so naturally-sparse timelines aren't noisy; optional DFIR_GAP_ACTIVE_HOURS. Derived on read, no AI; dashboard Timeline Gaps panel + report §3.3; thresholds DFIR_GAP_MIN_MINUTES/DFIR_GAP_DENSITY_FACTOR (closes #83).
  • Beacon / C2 detection — flag outbound connection channels (host → dest:port) whose inter-arrival intervals are too regular to be human traffic; robust median/MAD period estimate so a missed beacon or operator burst doesn't hide a real channel. Derived from the network timeline, severity High for public destinations, a hunting lead not a verdict. Dashboard Beacon Candidates panel + report §4.9; thresholds DFIR_BEACON_MIN_COUNT/DFIR_BEACON_MAX_JITTER_PCT (closes #82).

Changed

  • Customer Exposure shows found results only — the dashboard panel and report §4.5 now hide clean "checked, no breach" rows (shared hasExposureFinding guard: keep rows with a breach, exposed data, or credential material); the providers/targets lines still record what was checked.
  • Demo case enriched for every sectionseed-demo now seeds a deliberate anti-forensics blackout (cleared DC01 event logs + EDR tampering → a ~16h complete-silence gap with finding f010) so the Timeline Gaps panel and the new Hypothesize gaps (#96) feature have compelling material, plus a seeded narrative timeline and investigator-notebook entries so those sections render too.

Fixed

  • Extension case selection saves without pressing Start — the extension popup's case dropdown now auto-saves on change (keeping screenshot-capture state unchanged), so switching cases or clearing the case applies immediately; the floating "📤 Push" button on DFIR consoles now only appears when a case is connected and hides dynamically when the case is cleared.
  • Demo Customer Exposure rows rendered half-emptyseed-demo's customer-exposure.json used a stale schema (input/kind/breachNames/exposedFields) so the dashboard (reading target/targetType/breach/exposedData) showed only HIBP · :; rewritten to the current StoredCustomerExposureResult shape (one row per HIBP breach, one per Shodan host, plus providers/targets/errors).

Fixed

  • Velociraptor live-monitor discovery on real servers — the CLIENT_EVENT artifact picker and Auto-monitor configured events came back empty on actual Velociraptor: the artifact type is now filtered in TypeScript (fetch all artifact_definitions(), normalize the type string) instead of a VQL =~/lowercase() filter that missed CLIENT_EVENT across versions, and the monitoring-table read returns the raw GetClientMonitoringState() proto and extracts names in TS (walks artifacts.artifacts + specs + label_events, casing-tolerant). The picker auto-populates when Velociraptor is connected; a new GET /velociraptor/diag endpoint dumps the real artifact-type counts + raw monitoring-state shape. Auto-monitor now uses the correct VQL function get_client_monitoring() (the previous GetClientMonitoringState() is the Go/gRPC name and returns null as a VQL call — confirmed against a real server via /velociraptor/diag); still overridable via DFIR_VELOCIRAPTOR_MONITORED_VQL (#84).
  • seed-demo now honours DFIR_CASES_ROOT — the seed script didn't load .env (every other script does), so it wrote the demo to companion/cases while the server read from the configured root, and the dashboard showed no case.