RECTOR-LABS/spoor

GitHub: RECTOR-LABS/spoor

基于 LangGraph 多智能体编排与 SANS SIFT 工具链的自主数字取证 Agent,通过架构级安全边界和哈希链审计保障调查结论的可验证性与防篡改性。

Stars: 1 | Forks: 0

# Spoor Spoor 通过一个专用的 **MCP server** 驱动 SANS SIFT 取证工具(Volatility 3、Sleuth Kit、RegRipper、plaso、YARA),并由 **LangGraph multi-agent graph** 进行编排——由一个首席调查员通过共享的案件状态,负责路由分诊、时间线、IOC 关联以及报告专家。它做出的每一个断言要么**有可验证的工具执行作为支撑,要么被明确标记为推断**——这是在代码中强制的,而不是在 prompt 中。 专为 SANS **"FIND EVIL!"** 黑客松(Devpost, 2026)而构建。Python · MCP · LangGraph · SIFT。 *Spoor*:动物留下的足迹或气味痕迹——你跟随 spoor 来猎捕猎物。在这里:跟随取证 artifacts 追踪威胁。

Spoor architecture with security boundaries

## 为什么信任它?(与众不同的地方) LLM agent 会产生幻觉;但事件响应报告绝不能这样。Spoor 的解决之道在于架构: | 边界 | 强制执行 | 位置 | |---|---|---| | **B1 — Path jail** | 每个证据路径都会被解析(包括符号链接),并且必须位于只读的证据根目录下 | `guardrails.py` | | **B2 — 无 Shell 允许列表** | 只有 7 个取证二进制文件可以被衍生运行,且仅限 argv 列表——从构造上就不可能执行任意命令 | `guardrails.py`, `runner.py` | | **B3 — Workspace jail** | 工具 artifacts(提取文件、时间线)仅写入一个与证据**不相交**的 workspace | `guardrails.py`,在 graph 构建时强制执行 | | **B4 — 审批门** | 实时操作会在**产生任何副作用之前**调用 `interrupt()`;只有人工恢复才能继续执行 graph;批准*和*拒绝都会被审计 | `orchestration/gate.py` | | **B5 — 防篡改审计** | 每次工具调用都会追加一条 hash 链记录;对 `spoor verify-audit` 的编辑、删除、重排序都会被检测到 | `audit.py` | 在 B5 之上的是 **citation 合约**:一个发现只有在引用了存在于**已验证**链中的 `tool_call_id` 时,才能被声明为*已确认*。缺失或伪造的引用会被降级为推断——这是在 `submit_report` 的实现(`orchestration/report.py`)中确定性完成的。链条断裂会导致所有已确认的声明失效。最终报告自身的内容 hash 会被密封到链条中。 所有五个边界都附带**绕过测试**(`tests/test_guardrails.py`、`tests/test_gate.py`、`tests/test_report.py`)——可以通过 `make guardrails` 实时尝试它们。 ## 快速开始 ``` # 前置条件: uv (https://docs.astral.sh/uv/), Python 3.12+ git clone https://github.com/RECTOR-LABS/spoor && cd spoor make install # deps incl. Volatility 3 (the 'forensics' extra) cp .env.example .env # add SPOOR_OPENROUTER_API_KEY (or OPENROUTER_API_KEY) make test # 112 tests make demo # full multi-agent live run (canned Case-001 demo scenario) make verify-audit # prove the run's hash chain is intact ``` `make demo` 会针对预先准备好的、Case-001 形状的证据层(无需大型下载)运行完整的 graph 测试——包括 supervisor 路由、真实模型、 citation 合约,以及 agent 必须从中恢复的预设工具故障。 ### 观看演示(无声演练) ``` ./scripts/demo_walkthrough.sh # $0 — runs off the committed real run ``` 逐段打印完整的提交过程:结论(`spoor show-report`)、 防篡改审计(`spoor verify-audit`)、失败的 guardrail 绕过尝试 (`spoor demo-guardrails`),以及诚实的准确率数值。实时的 自主运行是 `make real`。 ## 实战运行(真实证据,真实准确率) Spoor 的评分基于 **DFIR Madness Case 001 — "The Stolen Szechuan Sauce"**,这是一个带有已发布答案的公开入侵案例(参见 [`datasets/README.md`](datasets/README.md)): ``` # 获取 DC01 内存镜像 (2.1GB) 并验证其发布的 MD5 — 见 datasets/README.md make real ``` 这会端到端地在真实的 2.1GB 域控内存转储上驱动**真实的 Volatility 3**:自主分诊 → IOC 关联 → 强制报告 → **[`accuracy_report.md`](accuracy_report.md)**,包含 precision/recall/F1、 幻觉率,以及一个**证据完整性证明**(运行前后镜像的 SHA-256——只读操作,经过实验论证)。 ## 自主性与自我纠正 工具故障会作为*数据*返回给模型(失败的调用仍会被审计),因此 agent 会对原因进行推理并重试——这是涌现行为,而不是预设的重试循环。提交的运行日志展示了其实况:`vol_malfind` 失败,agent 完成扫描,返回,重试,恢复(`runs/*/audit.jsonl`,演示运行中的序列 4–5)。一个确定性的**完整性门**会在运行试图在没有强制报告的情况下结束时,在其带有 checkpoint 的线程上重新触发 supervisor。 ## 工具集(12 个只读工具,一个经过审计的骨干) | 家族 | 工具 | 备注 | |---|---|---| | 内存 (Volatility 3) | `vol_pslist` `vol_pstree` `vol_netscan` `vol_malfind` `vol_cmdline` | pstree 扁平化;netscan 去重 + 状态可过滤;所有行均在服务端设限 | | 时间线 (plaso) | `log2timeline_run` `psort_query` | 在 workspace 中构建一次,可多次切片;事件在到达模型前设限 | | 磁盘 (Sleuth Kit) | `tsk_fls` `tsk_icat` | 显示已删除条目;提取文件在提取时即计算 hash(监管链封闭) | | 注册表 (RegRipper) | `regripper_run` | 注册表配置单元来自证据或被雕刻(carve)至 workspace | | 指标 | `hash_file` `yara_scan` | hashing 在进程内完成(无子进程,无解析);规则位于 workspace jail 中 | 每个工具:类型化输入 → guardrails → 无 Shell runner → hash 链审计记录 → 结构化 JSON 输出。 ## 从 Claude Code / 任何 MCP 客户端使用 agent 使用的相同工具通过 MCP (stdio) 提供: ``` // .mcp.json / claude_desktop_config.json { "mcpServers": { "spoor-sift": { "command": "uv", "args": ["--directory", "/ABS/PATH/spoor", "run", "spoor-sift"], "env": { "EVIDENCE_ROOT": "/cases/case001", "SPOOR_WORKSPACE": "/cases/workspace", "SPOOR_AUDIT_PATH": "runs/audit.jsonl" } } } } ``` ## 仓库结构图 ``` spoor_sift/ audit.py hash-chained, tamper-evident audit log (+ verify) guardrails.py path jail · binary allow-list · workspace disjointness runner.py no-shell subprocess runner (text + raw-bytes modes) accuracy.py precision/recall/F1 + hallucination rate vs. an answer key cli.py spoor verify-audit | demo-guardrails | accuracy-report server.py spoor-sift MCP server (FastMCP, stdio) tools/ memory · timeline · disk · registry · indicators orchestration/ supervisor.py Lead Investigator graph (create_supervisor + checkpointer) agents.py triage / timeline / ioc_correlation / reporter specialists report.py the citation contract + the enforcing submit_report tool gate.py interrupt() approval gate for live actions tools.py typed LangChain adapters over the audited core scripts/ live demo run · real-evidence run datasets/ Case 001 docs, fetch instructions, verified ground truth runs/ committed run artifacts: audit logs, reports, tokens, transcripts tests/ 112 tests, TDD-first (incl. guardrail bypass attempts) ``` ## 诚实的局限性 - **内存路径是完全原生的**(纯 Python 的 Volatility 3)。plaso/Sleuth Kit/RegRipper 二进制文件搭载于 SANS SIFT Workstation——在裸机上,除非你安装它们,否则时间线/磁盘/注册表 工具会以可自我纠正的 "binary not found" 错误形式出现。 - 提交的**演示**运行使用预先准备好的、Case-001 形状的证据层,以便低成本地 测试完整的四专家 graph;而**实战**运行(`make real`)是真正的端到端运行 并生成带评分的准确率报告。 - Spoor 的作者是 agent 工程师,而非全职的取证分析师;prompt 中编码的方法论 遵循 SANS 发布的分诊手册,且准确率是*基于公开答案进行测量的*, 而非断言。 ## License MIT — 参见 [`LICENSE`](LICENSE)。
标签:LangGraph, LLM Agent, MCP, SANS SIFT, 库, 应急响应, 数字取证, 自动化脚本, 逆向工具, 防篡改审计