Inspiration

We started by running an LLM agent against a real memory forensics CTF using a standard Linux terminal (SANS SIFT). For the first twelve minutes it reasoned well — identified a rogue process, decoded base64 arguments, correlated network connections. Then it collapsed. A password prompt hung the tool, the agent had no way to inject input, and it began flooding its own context window with 176+ lines of raw hex dumps hunting for the password. Twenty minutes. $2.07. 147,000 tokens. Manually aborted. Zero extraction. The reasoning was never the problem — the interface was.

What it does

Engram MCP is an autonomous DFIR agent built on the Model Context Protocol (MCP), running on a SANS SIFT Workstation. A Python FastMCP server sits between the LLM and Volatility 3, exposing six deterministic tools that cover a strict 6-phase OODA loop: Surface Triage → Deep User-Space → Kernel Abyss → Advanced Evasion → Substantiation → Incident Reporting. The agent never constructs a Volatility command — it calls a Python function and receives a structured JSON intelligence summary. The context window stays lean across an entire multi-phase investigation.

The final output is a structured investigative narrative written to disk as an immutable forensic artifact — not a raw execution log. Every finding is supported by explicit tool evidence, and every subsystem where telemetry was missing is documented as a verified blind spot rather than silently declared clean.

During testing against a live Windows Domain Controller image, the agent autonomously detected a Ring 0 rootkit (Mnemosyne.sys) responsible for hiding 124 processes from the OS via Direct Kernel Object Manipulation (DKOM) — and correctly identified it had also unlinked the entire kernel module list, network stack, and AV filter drivers.

How we built it

  • Volatility 3 as the forensic engine (pslist, psscan, malfind, modscan, modules, and more)
  • FastMCP Python server abstracting all plugin execution into strict typed functions
  • CLAUDE.md as the agent's governing system prompt — enforcing the OODA loop, the Empty Data Protocol, and the anti-hallucination guardrails
  • Claude Sonnet 4.6 as the orchestrating LLM via Claude Code on SANS SIFT Workstation
  • Three real memory images investigated across different OS profiles and malware families: a Windows workstation (DKOM rootkit), a Windows Domain Controller (Ring 0 rootkit — demo target), and an unknown dump (BlackEnergy malware)

Challenges we ran into

The Empty Data Protocol: On legacy OS images, Volatility plugins silently return empty arrays. The LLM initially interpreted this as "clean." We built a deterministic guardrail at the Python layer that injects "UNVERIFIED: Tool returned no data" and paired it with a prompt-level rule forbidding clean declarations without positive evidence.

Context Decay in Final Reports: In early runs, the agent would correctly flag a Phase 3 failure mid-investigation, then "forget" it by Phase 6 and write "Kernel is clean." We fixed this by anchoring the anti-hallucination guardrail at the very bottom of CLAUDE.md — the last thing the agent reads before generating the summary.

Zero-Knowledge Analysis: Standard forensic datasets are heavily documented online. LLMs risk hallucinating findings from CTF write-ups. We enforce blind analysis by anonymizing all evidence files, stripping metadata, and forcing the agent to derive every finding purely from MCP tool output.

Accomplishments that we're proud of

Self-correction is a first-class architectural requirement, not an afterthought. Concrete examples from live runs:

  • False Positive — Null-name kernel entries: modscan returned four entries with null names and null paths. The agent analyzed their base addresses, determined they fell outside normal Windows x64 kernel VA ranges, and autonomously downgraded them to pool-scan artifacts — discarding the alert without human intervention.
  • False Positive — GDI heap artifact: malfind flagged 11 memory regions in winlogon.exe and csrss.exe. The agent analyzed the raw hex, recognized the ff ee ff ee pattern as a benign Windows GDI heap marker, and self-corrected to False Positive.
  • Stale EPROCESS resolution: suspicious cmd.exe shells discovered via pool-tag scanning returned empty on substantiation. Instead of hallucinating command lines, the agent correctly diagnosed them as terminated processes with stale EPROCESS structures — and documented the limitation explicitly.

Investigating three targets surfaced a cross-host campaign: Mnemosyne.sys and subject_srv.exe appeared independently on both the workstation and the Domain Controller at identical paths — autonomously attributed by the agent as the same threat actor, same toolset, without human direction.

Each target has an independent accuracy report with honest self-assessment of false positives, missed artifacts, and hallucinated claims. Where the agent was wrong, we documented it. Every finding in every incident report is traceable to a specific MCP tool call in the full execution logs — timestamps and raw JSON tool output included — so judges can audit the complete reasoning chain, not just the conclusions.

What we learned

The most important lesson was that LLM reasoning quality is not the bottleneck in autonomous forensics — data pipeline integrity is. An LLM drowning in unstructured hex output fails not because it cannot reason, but because the interface never gave it a chance.

We also learned that honesty is an architectural decision. Early versions of the agent would silently paper over tool failures with confident-sounding summaries. The fix was not better prompting — it was building a deterministic Python guardrail that made it structurally impossible to declare a subsystem clean without positive evidence. Prompt-only solutions drifted under pressure; the architectural fix held across every test.

Finally, anchoring guardrails matters. Rules placed mid-prompt decay as context grows. Rules placed at the very end of the system prompt — the last thing the agent reads before generating output — proved durable across 40,000+ token investigations.

What's next for Engram MCP

  • Expand evidence support beyond memory dumps to disk images, network captures, and structured log files — covering the full DFIR evidence spectrum on SIFT
  • Add Linux memory image support (current implementation targets Windows profiles)
  • Implement automated YARA rule generation from confirmed IOCs, feeding findings from one investigation directly into the next
  • Build a multi-host orchestration layer so a single agent session can correlate findings across an entire fleet, not just individual images

For Judges — Quick Navigation

Built With

  • claude-code
  • claude-sonnet-4.6
  • custom-mcp
  • fastmcp
  • python
  • sans-sift-workstation
  • volatility-3
  • yara
Share this project:

Updates