1hackerway/eviltrace
GitHub: 1hackerway/eviltrace
一款运行于 SIFT Workstation 的自主 DFIR 调查代理,通过 SHA-256 哈希密封和确定性验证器确保 AI 生成的每项取证发现都有真实证据支撑,有效消除幻觉。
Stars: 0 | Forks: 0
# EvilTrace
[](LICENSE)
**EvilTrace 是一个运行于 SANS SIFT Workstation 的自主 DFIR 调查 agent,它会根据原始的、SHA-256 密封的取证工具输出验证每一个发现,并为每个声明标记 `GROUNDED`、`INFERRED` 或 `UNVERIFIED` —— 从而确保自主 AI 调查不会悄悄报告证据不支持的内容。**
## 提交合规对照表
| # | 要求 | 位置 |
|---|---|---|
| 1 | 代码仓库 URL | (本 README) |
| 2 | 开源许可证 | [LICENSE](LICENSE) — MIT,仓库根目录;公开后也会显示在 GitHub 的 *About* 侧边栏中 |
| 3 | 包含设置说明的 README | 本文件 → [在本地试用](#try-it-out-locally-on-sans-sift-workstation) |
| 4 | 面向评委的分步运行说明 | [在本地试用](#try-it-out-locally-on-sans-sift-workstation)(无在线部署;根据规则在 SIFT 上本地运行) |
| 5 | 功能/特性文本描述 | 本 README + [DEVPOST.md](DEVPOST.md);[samples/investigative_narrative.md](samples/investigative_narrative.md) 和 [samples/alihadi_01/investigative_narrative.md](samples/alihadi_01/investigative_narrative.md) — 结构化调查叙述(分析推理要求) |
| 6 | 演示视频 | [在 YouTube 上观看](https://youtu.be/blQwxxCHQoA) |
| 7 | 架构图 | [架构](#architecture)(本 README 中的 Mermaid 图表) |
| 8 | 证据数据集文档 | [datasets/README.md](datasets/README.md) + 各案件简报 [cases/incident_01/CLAUDE.md](cases/incident_01/CLAUDE.md)、[cases/alihadi_01/CLAUDE.md](cases/alihadi_01/CLAUDE.md) |
| 9 | 准确性报告 | [samples/accuracy_report.md](samples/accuracy_report.md)、[samples/accuracy_report_memory.md](samples/accuracy_report_memory.md)、[samples/alihadi_01/accuracy_report.md](samples/alihadi_01/accuracy_report.md)、[samples/alihadi_01/accuracy_report_memory.md](samples/alihadi_01/accuracy_report_memory.md) 以及 [samples/accuracy_self_assessment.md](samples/accuracy_self_assessment.md)(包含证据完整性/销毁部分在内的诚实自我评估) |
| 10 | Agent 执行日志 | [samples/execution_log.jsonl](samples/execution_log.jsonl) 和 [samples/alihadi_01/execution_log.jsonl](samples/alihadi_01/execution_log.jsonl) — 包含各工具时间戳及每轮 token 使用量 |
报告中的每一个发现都可以通过工件引用和执行日志中的 SHA-256 密封,追溯到生成它的具体工具执行过程。
## EvilTrace 的功能
EvilTrace 通过受控的包装层编排 SIFT 取证工具(Sleuth Kit、Zimmerman EZ Tools、Plaso、Volatility 3、YARA),在其上运行自主的 Anthropic SDK agent 循环,然后**将其产生的每一个发现,与它声称所基于的、经过精确预哈希的工具输出进行验证。**
每个报告的发现都包含:
- 一个**精确的工件引用**(`file:LINE`),指向支持该发现的原始工具输出行,
- 一个**置信度标签** —— `GROUNDED`(引用的行字面上包含了所声称的证据)、`INFERRED`(基于已验证事实的合理推论,但并非单一字面行),或 `UNVERIFIED`(无支持行 —— 从结论中排除),
- 一个**完整性判定**,将该引用与在*任何 LLM 查看之前*对原始工具输出计算出的 SHA-256 哈希关联起来。
分配这些标签的验证器是**确定性的,且绝不调用 LLM。** 它无从辩驳,也无法产生幻觉。
## 为什么这很重要
自主 DFIR agent 速度很快,但它们可能会捏造事实。Protocol SIFT 自身的文档将其列为主要未解决的风险,并规定了纠正方法 —— *“使用工具输出作为事实来源,而不是 AI 的摘要文本”* —— 但并未实现。Brian Carrier 博士(The Sleuth Kit 的创建者)表达了相同的观点:*工具必须识别出哪些内容来自 AI,这样你才知道需要验证什么。*
EvilTrace 就是那个自动化了的纠正方案。基础验证器是 Carrier 的“查询项目存在性”方法的直接、确定性实现:当一个发现引用某个工件时,验证器会重新获取该确切行,将源数据与 LLM 前的密封哈希进行重新哈希比对,并拒绝证明任何它无法重现的内容。
## EvilTrace 与 Protocol SIFT 的关系 —— 以及与人在回路平台的关系
EvilTrace **扩展**了 Protocol SIFT 基准,而不是取代它。它采用了那些基本必备的模式 —— 分层的 `CLAUDE.md` agent 人设、按需技能上下文、`stderr → 自我纠正 → 重新运行` 循环、不可变的审计日志,以及严格的“执行任务中途绝不提问”规则 —— 并添加了 Protocol SIFT 文档规定但未构建的推理约束层。
它还在自主性/监督范围上,有意定位在与人在回路(human-in-the-loop)平台(例如 AppliedIR 的 Valhuntir,黑客松的参考示例)不同的位置:
| | 人在回路平台 | EvilTrace |
|---|---|---|
| **信任锚点** | 人类审查员批准每一项发现(发现暂存为 DRAFT 状态;AI 不能批准自己的工作) | 确定性验证器针对哈希密封的原始输出验证每一项发现 |
| **信任速度** | 受限于人工审查 | 机器速度 |
| **保证内容** | 有人类签字确认 | 每个报告的发现都引用了真实的、LLM 前哈希的证据;未验证的声明会被自动降级 |
**诚实的边界:** EvilTrace 的验证器能捕捉*捏造和过度确信* —— 但它**不能**代替人类在*解释*上的判断。`INFERRED` 的发现恰恰是人类分析师仍然发挥作用的地方。EvilTrace 并不“优于人工审查”;它是一种不同的权衡 —— 在完全自主的前提下,为每个声明设定确定性的底线,这在无法以机器速度进行人工审查的场景下非常有用。
## 架构
模型灵活地进行推理。**工具执行受到代码的限制。** 两个接口 —— SDK agent 和 MCP 服务器 —— 都汇聚在同一个只读包装层上,因此无论哪个接口驱动调查,都只有一条确定的审计链。
**框架姿态。** EvilTrace 的编排器是一个**原生 Anthropic SDK 工具使用循环** —— 一种类似的智能体架构,在官方黑客松规则中与 Claude Code 和 OpenClaw 一起被明确允许。自定义 MCP 服务器(`eviltrace_mcp.py`)是 **Claude Code 集成路径**:相同的包装器、相同的审计链,可直接在 Claude Code 会话中运行。
```
graph TB
PATTERN["ARCHITECTURAL PATTERN
Custom MCP Server + comparable raw-SDK agent loop"] subgraph prompt ["PROMPT-BASED GUARDRAILS — guidance only (CLAUDE.md hierarchy)"] C1["~/.claude/CLAUDE.md
global persona"] C2["./CLAUDE.md
project rules"] C3["cases/incident_01/CLAUDE.md
case objective + IOCs"] end TASK["Investigator task"] --> AGENT subgraph agentbox ["agent.py — raw Anthropic SDK tool-use loop"] AGENT["loop: sliding context · max-turns ceiling ·
deterministic vs transient failure recovery"] ALLOW["typed tool allowlist
(the tool list IS the allowlist)"] AGENT --> ALLOW end prompt -. concatenated into system prompt .-> AGENT MCP["eviltrace_mcp.py
Custom MCP Server
(3 read-only tools)"] subgraph arch ["ARCHITECTURAL GUARDRAILS — code-enforced"] DISK["tools/disk_tools.py
structured tool implementations"] WRAP["bin/run_* wrappers + _common.sh
read-only guard · line-numbered capture ·
pre-LLM SHA-256 seal · JSONL audit log"] DISK --> WRAP end ALLOW --> DISK MCP -. shells out to .-> WRAP WRAP -->|invokes| SIFTT["SIFT forensic tools
TSK · Zimmerman EZ Tools · Plaso · Volatility 3 · YARA"] SIFTT -->|read-only| EV[("evidence/ — rd01.E01
READ-ONLY")] WRAP -->|writes only| OUT[("analysis/ · reports/
tool_runs/ + execution_log.jsonl")] OUT --> VAL subgraph valbox ["validator.py — deterministic, never calls an LLM"] VAL["re-fetch cited line · re-hash vs pre-LLM seal ·
tag GROUNDED / INFERRED / UNVERIFIED"] end VAL --> REP["case_report.md + accuracy_report.md
(confidence-tagged)"] HOOK["hooks/stop_hook.py
completion-promise verification"] -. gates completion .-> AGENT classDef patternLabel fill:none,stroke:none,font-weight:bold classDef promptLayer stroke-dasharray:6 4 classDef archLayer stroke-width:3px class PATTERN patternLabel class prompt promptLayer class arch,valbox archLayer ``` **基于 Prompt 的护栏**(`CLAUDE.md` 层级)塑造了 *agent 如何推理* —— 人设、目标和任务中途不提问规则。它们是建议性的。 **架构性护栏**(包装层 + 类型化工具白名单)决定了 *物理上可以执行什么*。Agent 没有原始 shell 访问权限。它只能调用其白名单上的工具;每个工具都通过 `bin/run_*` 包装器进行 shell 调用,该包装器拒绝在证据树内写入,捕获带有行号的输出,并在任何 LLM 查看之前对原始字节进行 SHA-256 密封。这就是评委所关注的区别,EvilTrace 在代码中而非在 Prompt 中强制执行这些安全关键部分。 ## 安全模型和护栏 - 证据被视为**只读**;包装器拒绝任何指向证据 / `/mnt` / `/media` 树内的输出路径,仅写入 `analysis/`、`reports/` 和 `exports/`。 - LLM **没有原始 shell 访问权限**。暴露的工具列表就是白名单。 - 所有取证执行都流经包装器脚本,这些脚本在**总结或验证之前**对原始输出进行哈希处理。 - 发现需要**精确的工件引用**;验证器是确定性的,且不使用 LLM。 - 完成时的 **Stop hook** 会在接受运行之前验证承诺的工件确实存在。 **绕过测试。** 只读护栏(`bin/_common.sh` 中的 `assert_safe_output`)已由 [`tests/test_guardrail.sh`](tests/test_guardrail.sh) 验证,该脚本使用五个路径对其进行探测:一个合法的输出路径、直接写入证据树的路径、`..` 路径遍历逃逸、受保护挂载(`/mnt`)写入和树外写入。只有合法路径被允许;每一个绕过尝试都被拒绝。因为该护栏在检查之前使用 `readlink -f` 进行规范化,所以 `..` 遍历会折叠回证据树并被捕获。捕获的运行记录:[`tests/guardrail_selftest.txt`](tests/guardrail_selftest.txt)。 EvilTrace 通过架构性护栏和确定性验证**降低**了幻觉和证据销毁的风险。它**并非**旨在防御故意恶意的模型,也不能替代写阻断器、经验证的证据处理程序或审查员的判断。 ## 在 SANS SIFT Workstation 上本地试用 EvilTrace 在 SANS SIFT Workstation 上本地运行。没有托管部署 —— 它在本地取证证据和本地 DFIR 工具上运行。 **前置条件** - SANS SIFT Workstation(通过 .NET 提供 Sleuth Kit、Zimmerman EZ Tools、Plaso、Volatility 3、YARA) - Python 3.10+ - 一个 Anthropic API 密钥 - `pip install anthropic --break-system-packages`(仅在你想运行 MCP 服务器时才添加 `fastmcp`) **运行磁盘调查** ``` git clone https://github.com/1hackerway/eviltrace.git cd eviltrace export ANTHROPIC_API_KEY="sk-ant-..." # EvilTrace 不附带 evidence。请放置(或创建符号链接)磁盘镜像: mkdir -p cases/incident_01/evidence # cases/incident_01/evidence/rd01.E01 <-- 将镜像放在这里 # 自主调查(提取 artifacts、解析它们、记录 findings): python3 agent.py incident_01 # 确定性验证:标记每个 finding + 输出准确性报告: python3 validator.py --write ``` **查看输出** ``` cases/incident_01/reports/case_report.md # findings with confidence tags cases/incident_01/analysis/findings.json # structured findings + citations cases/incident_01/reports/accuracy_report.md # grounded / inferred / unverified rates cases/incident_01/reports/execution_log.jsonl # per-tool + per-turn audit trail ``` **预期内容。** 磁盘运行会提取 `$MFT`、`Amcache.hve` 以及 `SOFTWARE`/`SYSTEM` 配置单元,解析它们并构建 Plaso 时间线 —— 仅时间线步骤就可能需要 20-40 分钟。一次典型的运行会产生 **7 个磁盘发现(5 个 GROUNDED,2 个 INFERRED,0 个 UNVERIFIED)**。由于 agent 是自主的,每次运行的确切发现可能会略有不同;提交的 `samples/` 反映了经过验证的参考运行。 **没有证据,或者想跳过运行?** 预计算的参考输出位于 [`samples/`](samples/) 中 —— 磁盘部分(`findings.json`,7 个发现)和内存部分(`memory_findings.json`,6 个发现)共同构成了**完整的 incident_01 案件:13 个发现 —— 11 个 GROUNDED,2 个 INFERRED,0 个 UNVERIFIED。** 评委无需 3 GB 的内存镜像即可验证项目。 **在两个案件中:18 个发现 —— 14 个 GROUNDED,3 个 INFERRED,1 个 UNVERIFIED。** 诚实的准确性说明 —— 包括为什么唯一的 `UNVERIFIED` 是正确的底线而不是失误 —— 位于 [`samples/accuracy_self_assessment.md`](samples/accuracy_self_assessment.md) 中。 ### 泛化案例 — alihadi_01 第二台独立的主机表明该流水线的泛化能力超越了 SHIELDBASE 案例:[Ali Hadi 公开 Web 服务器案例](https://archive.org/details/dfir-case1)(Windows Server 2008 / XAMPP,**一个在扇区 2048 处分区的磁盘及 NTFS**,外加内存镜像),在简报中**没有任何参考答案**的情况下运行。它产生了 **5 个发现 —— 3 个 GROUNDED / 1 个 INFERRED / 1 个 UNVERIFIED**。唯一的 `UNVERIFIED` 是一个真实但无法机械验证的目录创建发现:事件确实发生了,但低熵的目录名称并不是确定性验证器可以基于单行进行验证的硬锚点,因此它会诚实地触及底线,而不是过度证明(参见 [`samples/accuracy_self_assessment.md`](samples/accuracy_self_assessment.md) §3)。参考输出在 [`samples/alihadi_01/`](samples/alihadi_01/) 中。 **可选 —— MCP 服务器(自定义 MCP Server 模式)** ``` pip install fastmcp --break-system-packages claude mcp add eviltrace-forensics python3 eviltrace_mcp.py claude mcp list # should show eviltrace-forensics ✓ Connected ``` 注册信息会写入你本地的 Claude 配置中,而不是本仓库,因此在全新克隆后必须重新运行。 ## 自己验证每一个数字 演示中的所有置信度计数均来自本仓库中已提交的文件。 克隆它并运行这三个命令 —— 无需任何工具或证据镜像: ``` # 综合记分板(按 case 统计 + 总计) sed -n '/## 2. Results summary/,/Combined/p' samples/accuracy_self_assessment.md # 按 case 统计的记分板(为总和提供独立依据) grep -niE 'scoreboard' samples/case_report.md # incident_01 → 11 / 2 / 0 grep -niE 'scoreboard' samples/alihadi_01/case_report.md # alihadi_01 → 3 / 1 / 1 ``` 预期:incident_01 (13 = 11/2/0) + alihadi_01 (5 = 3/1/1) = **18 个发现 —— 14 个 GROUNDED / 3 个 INFERRED / 1 个 UNVERIFIED。** ## 输出 实时运行会在 `cases/incident_01/` 下写入内容。`analysis/` 的输出(提取的、解析的 CSV)被 gitignored;`reports/` 的输出会被跟踪。为了便于一站式审查,`samples/` 捆绑了每个面向提交的工件(磁盘 + 内存)的副本。 | 输出 | 实时运行路径 | 跟踪的副本 | |---|---|---| | 磁盘发现(结构化) | `cases/incident_01/analysis/findings.json` | `samples/findings.json` | | 内存发现(结构化) | `cases/incident_01/analysis/memory_findings.json` | `samples/memory_findings.json` | | 案件报告(磁盘) | `cases/incident_01/reports/case_report.md` | `samples/case_report.md` | | 准确性报告(磁盘) | `cases/incident_01/reports/accuracy_report.md` | `samples/accuracy_report.md` | | 准确性报告(内存) | `cases/incident_01/reports/accuracy_report_memory.md` | `samples/accuracy_report_memory.md` | | 执行日志 | `cases/incident_01/reports/execution_log.jsonl` | `samples/execution_log.jsonl` | | 自我纠正摘录 | (从执行日志中提取) | `samples/self_correction_excerpt.jsonl` | | 原始工具输出 | `cases/incident_01/analysis/tool_runs/` | (已排除 — 体积大) | **演示视频运行来源。** 演示视频的实时运行画面是在 incident_01 案件的临时副本上进行的单独冷运行(cold run)。其完整的审计工件 —— 执行日志(包括镜头中的自我纠正)、发现、会话承诺以及渲染的案例报告 —— 均按原样提交在 [`samples/video_demo_run/`](samples/video_demo_run/) 中,因此视频中的每一帧终端输出都可以追溯到记录的工具执行过程。规范的提交结果仍保留在 [`samples/`](samples/) (incident_01) 和 [`samples/alihadi_01/`](samples/alihadi_01/) 中。 ## 准确性和验证方法 EvilTrace 测量两个不同的事物并将它们分开: 1. **基础/推理约束准确性** *(自包含 —— 这是区分点)。* 对于每一个发现,引用的行是否存在,是否与 LLM 前的哈希匹配,以及它是否确实支持该声明?这不需要外部答案 —— 仅从仓库即可验证。 2. **调查召回率** *(需要外部答案)。* Agent 是否找到了人类会找到的所有内容?这**尚未**进行外部基准测试,准确性报告中已明确说明了这一点。 `validator.py` 中的真实摘录(已裁剪): ``` [F001] ✔ GROUNDED mft_output.csv:L219674 files matched : procdump.exe sizes matched : 515776 bytes path corrob. : tdungan, dashlane, procdump.exe integrity : VERIFIED (input_seal=OK, csv_seal=SEALED_OK) [F004] ~ INFERRED SOFTWARE_recmd.csv:L31 files matched : msascuil.exe MISSING : file:vmtoolsd.exe -> not GROUNDED integrity : VERIFIED (input_seal=OK, csv_seal=SEALED_OK) ``` F004 一针见血地展示了护城河:agent 的声明引用了被引用行中不包含的文件,因此验证器**自动将其从 GROUNDED 降级为 INFERRED** —— 无需人工盘问。 参考运行还正确地**拒绝了相似项**,而不是过度报告 —— 例如 `LogUploader.dll` 和 `Qt5*.dll`(合法的 OneDrive/Dashlane 组件)、`csscan.exe`(McAfee)、`remsh.exe`(Windows `rempl`)和 Office 安装程序二进制文件 —— 并记录了**零幻觉发现**。仅存在于内存镜像中的记录在案的 IOC(例如 `STUN.exe`、`msedge.exe`、`172.15.1.20`)被正确地从磁盘发现中**剔除**,而不是被捏造。 ## 审计追踪和证据完整性 审计追踪不是叙事性的总结 —— 它是关于 agent 和工具实际执行操作的结构化证据。任何发现都可以通过以下单一链条追溯: ``` finding → artifact citation (file:LINE) → tool_runs/ raw output → pre-LLM SHA-256 seal in execution_log.jsonl ``` `execution_log.jsonl` 包含三种记录类型: - **tool runs(工具运行)** —— 时间戳、工具、命令、返回代码、原始输出路径、LLM 前 SHA-256(对于解析的 CSV 包含一个 `csv_seal`), - **`self_correction`(自我纠正)** —— 当发生确定性工具错误时,记录该决策,将结构化错误返回给模型,并且模型重定向(这*不是*盲目重试), - **`llm_turn`(LLM 轮次)** —— 每轮时间戳、模型、停止原因以及输入/输出 token 使用量。 验证器的完整性判定准确描述了链条可以被证明到的程度: | 判定 | 含义 | |---|---| | `VERIFIED` | 输入工件密封**和**解析后的 CSV 密封均匹配 | | `INPUT_VERIFIED` | 输入工件密封匹配;解析器未发出 CSV 密封 | | `CSV_VERIFIED` | 自捕获以来解析后的输出是字节稳定的;生产者链条无法通过正则表达式追踪 | | `RAW_VERIFIED` | 原始工具输出密封匹配(用于内存/Volatility 发现) | ## 数据集文档 完整的来源信息位于 [`datasets/README.md`](datasets/README.md) 中。简而言之:Operation SHIELDBASE,主机 `base-rd-01`,磁盘镜像 `rd01.E01`(EWF,单卷 NTFS,镜像 MD5 `391be74b6830344eace7272f697cf1ae`)。证据文件**不**包含在本仓库中。 ## 提交合规性 | 要求 | 位置 | |---|---| | 公开的 GitHub 仓库 | 本仓库 | | 开源许可证 (MIT) | [`LICENSE`](LICENSE) | | 演示视频 | (Devpost 提交链接) | | 架构图(基于 Prompt 与架构性护栏) | 上方的[架构](#architecture) | | 数据集文档 | [`datasets/README.md`](datasets/README.md) | | 准确性报告 | [`samples/accuracy_report.md`](samples/accuracy_report.md)(磁盘)+ [`samples/accuracy_report_memory.md`](samples/accuracy_report_memory.md)(内存) | | 试用说明 | 上方的[在本地试用](#try-it-out-locally-on-sans-sift-workstation) | | Agent 执行日志(时间戳 + token 使用量) | [`samples/execution_log.jsonl`](samples/execution_log.jsonl) | ## 已知局限 - 主要的调查 agent 是**原生 Anthropic SDK 循环**。`eviltrace_mcp.py` 是一个独立的自定义 MCP Server 接口,用于在相同的包装层上演示 MCP 模式;它**不**在 agent 的运行时路径中。 - 该流水线针对参考镜像(EWF,单卷 NTFS)进行了调优。其他镜像格式可能需要调整。 - 基础准确性是自包含且可验证的;**调查召回率尚未**针对独立的参考答案进行外部基准测试。 - 当单个被引用的行无法证明整个声明时,某些发现被有意设置为 `INFERRED` —— 这是设计使然,而不是缺陷。 - 本地 SIFT 工具路径可能因工作站构建版本而异。 - 公开仓库中不包含证据文件。 ## 负责任的使用和法律声明 EvilTrace 是一个研究原型。AI 是供训练有素的事件响应专业人员使用的工具;对发现准确性和完整性的责任仍由人类审查员承担。仅在您被授权分析的系统和使用的数据上使用。本软件“按原样”提供,不提供任何形式的保证 —— 参见 [`LICENSE`](LICENSE)。 SIFT Workstation 是 SANS Institute 的产品。 ## 致谢 由 Anand Kumar 为 SANS *Find Evil!* AI 黑客松 (2026) 构建。EvilTrace 扩展了 Protocol SIFT 参考架构(Rob T. Lee, SANS)。其抗击幻觉的设计参考了 Brian Carrier 博士在 DFIR 中关于 AI 验证的工作 (cybertriage.com)。实施过程得到了 Claude Code (Anthropic) 的协助。评估数据集是 SANS Operation SHIELDBASE 场景。 ## 许可证 MIT —— 参见 [`LICENSE`](LICENSE)。
Custom MCP Server + comparable raw-SDK agent loop"] subgraph prompt ["PROMPT-BASED GUARDRAILS — guidance only (CLAUDE.md hierarchy)"] C1["~/.claude/CLAUDE.md
global persona"] C2["./CLAUDE.md
project rules"] C3["cases/incident_01/CLAUDE.md
case objective + IOCs"] end TASK["Investigator task"] --> AGENT subgraph agentbox ["agent.py — raw Anthropic SDK tool-use loop"] AGENT["loop: sliding context · max-turns ceiling ·
deterministic vs transient failure recovery"] ALLOW["typed tool allowlist
(the tool list IS the allowlist)"] AGENT --> ALLOW end prompt -. concatenated into system prompt .-> AGENT MCP["eviltrace_mcp.py
Custom MCP Server
(3 read-only tools)"] subgraph arch ["ARCHITECTURAL GUARDRAILS — code-enforced"] DISK["tools/disk_tools.py
structured tool implementations"] WRAP["bin/run_* wrappers + _common.sh
read-only guard · line-numbered capture ·
pre-LLM SHA-256 seal · JSONL audit log"] DISK --> WRAP end ALLOW --> DISK MCP -. shells out to .-> WRAP WRAP -->|invokes| SIFTT["SIFT forensic tools
TSK · Zimmerman EZ Tools · Plaso · Volatility 3 · YARA"] SIFTT -->|read-only| EV[("evidence/ — rd01.E01
READ-ONLY")] WRAP -->|writes only| OUT[("analysis/ · reports/
tool_runs/ + execution_log.jsonl")] OUT --> VAL subgraph valbox ["validator.py — deterministic, never calls an LLM"] VAL["re-fetch cited line · re-hash vs pre-LLM seal ·
tag GROUNDED / INFERRED / UNVERIFIED"] end VAL --> REP["case_report.md + accuracy_report.md
(confidence-tagged)"] HOOK["hooks/stop_hook.py
completion-promise verification"] -. gates completion .-> AGENT classDef patternLabel fill:none,stroke:none,font-weight:bold classDef promptLayer stroke-dasharray:6 4 classDef archLayer stroke-width:3px class PATTERN patternLabel class prompt promptLayer class arch,valbox archLayer ``` **基于 Prompt 的护栏**(`CLAUDE.md` 层级)塑造了 *agent 如何推理* —— 人设、目标和任务中途不提问规则。它们是建议性的。 **架构性护栏**(包装层 + 类型化工具白名单)决定了 *物理上可以执行什么*。Agent 没有原始 shell 访问权限。它只能调用其白名单上的工具;每个工具都通过 `bin/run_*` 包装器进行 shell 调用,该包装器拒绝在证据树内写入,捕获带有行号的输出,并在任何 LLM 查看之前对原始字节进行 SHA-256 密封。这就是评委所关注的区别,EvilTrace 在代码中而非在 Prompt 中强制执行这些安全关键部分。 ## 安全模型和护栏 - 证据被视为**只读**;包装器拒绝任何指向证据 / `/mnt` / `/media` 树内的输出路径,仅写入 `analysis/`、`reports/` 和 `exports/`。 - LLM **没有原始 shell 访问权限**。暴露的工具列表就是白名单。 - 所有取证执行都流经包装器脚本,这些脚本在**总结或验证之前**对原始输出进行哈希处理。 - 发现需要**精确的工件引用**;验证器是确定性的,且不使用 LLM。 - 完成时的 **Stop hook** 会在接受运行之前验证承诺的工件确实存在。 **绕过测试。** 只读护栏(`bin/_common.sh` 中的 `assert_safe_output`)已由 [`tests/test_guardrail.sh`](tests/test_guardrail.sh) 验证,该脚本使用五个路径对其进行探测:一个合法的输出路径、直接写入证据树的路径、`..` 路径遍历逃逸、受保护挂载(`/mnt`)写入和树外写入。只有合法路径被允许;每一个绕过尝试都被拒绝。因为该护栏在检查之前使用 `readlink -f` 进行规范化,所以 `..` 遍历会折叠回证据树并被捕获。捕获的运行记录:[`tests/guardrail_selftest.txt`](tests/guardrail_selftest.txt)。 EvilTrace 通过架构性护栏和确定性验证**降低**了幻觉和证据销毁的风险。它**并非**旨在防御故意恶意的模型,也不能替代写阻断器、经验证的证据处理程序或审查员的判断。 ## 在 SANS SIFT Workstation 上本地试用 EvilTrace 在 SANS SIFT Workstation 上本地运行。没有托管部署 —— 它在本地取证证据和本地 DFIR 工具上运行。 **前置条件** - SANS SIFT Workstation(通过 .NET 提供 Sleuth Kit、Zimmerman EZ Tools、Plaso、Volatility 3、YARA) - Python 3.10+ - 一个 Anthropic API 密钥 - `pip install anthropic --break-system-packages`(仅在你想运行 MCP 服务器时才添加 `fastmcp`) **运行磁盘调查** ``` git clone https://github.com/1hackerway/eviltrace.git cd eviltrace export ANTHROPIC_API_KEY="sk-ant-..." # EvilTrace 不附带 evidence。请放置(或创建符号链接)磁盘镜像: mkdir -p cases/incident_01/evidence # cases/incident_01/evidence/rd01.E01 <-- 将镜像放在这里 # 自主调查(提取 artifacts、解析它们、记录 findings): python3 agent.py incident_01 # 确定性验证:标记每个 finding + 输出准确性报告: python3 validator.py --write ``` **查看输出** ``` cases/incident_01/reports/case_report.md # findings with confidence tags cases/incident_01/analysis/findings.json # structured findings + citations cases/incident_01/reports/accuracy_report.md # grounded / inferred / unverified rates cases/incident_01/reports/execution_log.jsonl # per-tool + per-turn audit trail ``` **预期内容。** 磁盘运行会提取 `$MFT`、`Amcache.hve` 以及 `SOFTWARE`/`SYSTEM` 配置单元,解析它们并构建 Plaso 时间线 —— 仅时间线步骤就可能需要 20-40 分钟。一次典型的运行会产生 **7 个磁盘发现(5 个 GROUNDED,2 个 INFERRED,0 个 UNVERIFIED)**。由于 agent 是自主的,每次运行的确切发现可能会略有不同;提交的 `samples/` 反映了经过验证的参考运行。 **没有证据,或者想跳过运行?** 预计算的参考输出位于 [`samples/`](samples/) 中 —— 磁盘部分(`findings.json`,7 个发现)和内存部分(`memory_findings.json`,6 个发现)共同构成了**完整的 incident_01 案件:13 个发现 —— 11 个 GROUNDED,2 个 INFERRED,0 个 UNVERIFIED。** 评委无需 3 GB 的内存镜像即可验证项目。 **在两个案件中:18 个发现 —— 14 个 GROUNDED,3 个 INFERRED,1 个 UNVERIFIED。** 诚实的准确性说明 —— 包括为什么唯一的 `UNVERIFIED` 是正确的底线而不是失误 —— 位于 [`samples/accuracy_self_assessment.md`](samples/accuracy_self_assessment.md) 中。 ### 泛化案例 — alihadi_01 第二台独立的主机表明该流水线的泛化能力超越了 SHIELDBASE 案例:[Ali Hadi 公开 Web 服务器案例](https://archive.org/details/dfir-case1)(Windows Server 2008 / XAMPP,**一个在扇区 2048 处分区的磁盘及 NTFS**,外加内存镜像),在简报中**没有任何参考答案**的情况下运行。它产生了 **5 个发现 —— 3 个 GROUNDED / 1 个 INFERRED / 1 个 UNVERIFIED**。唯一的 `UNVERIFIED` 是一个真实但无法机械验证的目录创建发现:事件确实发生了,但低熵的目录名称并不是确定性验证器可以基于单行进行验证的硬锚点,因此它会诚实地触及底线,而不是过度证明(参见 [`samples/accuracy_self_assessment.md`](samples/accuracy_self_assessment.md) §3)。参考输出在 [`samples/alihadi_01/`](samples/alihadi_01/) 中。 **可选 —— MCP 服务器(自定义 MCP Server 模式)** ``` pip install fastmcp --break-system-packages claude mcp add eviltrace-forensics python3 eviltrace_mcp.py claude mcp list # should show eviltrace-forensics ✓ Connected ``` 注册信息会写入你本地的 Claude 配置中,而不是本仓库,因此在全新克隆后必须重新运行。 ## 自己验证每一个数字 演示中的所有置信度计数均来自本仓库中已提交的文件。 克隆它并运行这三个命令 —— 无需任何工具或证据镜像: ``` # 综合记分板(按 case 统计 + 总计) sed -n '/## 2. Results summary/,/Combined/p' samples/accuracy_self_assessment.md # 按 case 统计的记分板(为总和提供独立依据) grep -niE 'scoreboard' samples/case_report.md # incident_01 → 11 / 2 / 0 grep -niE 'scoreboard' samples/alihadi_01/case_report.md # alihadi_01 → 3 / 1 / 1 ``` 预期:incident_01 (13 = 11/2/0) + alihadi_01 (5 = 3/1/1) = **18 个发现 —— 14 个 GROUNDED / 3 个 INFERRED / 1 个 UNVERIFIED。** ## 输出 实时运行会在 `cases/incident_01/` 下写入内容。`analysis/` 的输出(提取的、解析的 CSV)被 gitignored;`reports/` 的输出会被跟踪。为了便于一站式审查,`samples/` 捆绑了每个面向提交的工件(磁盘 + 内存)的副本。 | 输出 | 实时运行路径 | 跟踪的副本 | |---|---|---| | 磁盘发现(结构化) | `cases/incident_01/analysis/findings.json` | `samples/findings.json` | | 内存发现(结构化) | `cases/incident_01/analysis/memory_findings.json` | `samples/memory_findings.json` | | 案件报告(磁盘) | `cases/incident_01/reports/case_report.md` | `samples/case_report.md` | | 准确性报告(磁盘) | `cases/incident_01/reports/accuracy_report.md` | `samples/accuracy_report.md` | | 准确性报告(内存) | `cases/incident_01/reports/accuracy_report_memory.md` | `samples/accuracy_report_memory.md` | | 执行日志 | `cases/incident_01/reports/execution_log.jsonl` | `samples/execution_log.jsonl` | | 自我纠正摘录 | (从执行日志中提取) | `samples/self_correction_excerpt.jsonl` | | 原始工具输出 | `cases/incident_01/analysis/tool_runs/` | (已排除 — 体积大) | **演示视频运行来源。** 演示视频的实时运行画面是在 incident_01 案件的临时副本上进行的单独冷运行(cold run)。其完整的审计工件 —— 执行日志(包括镜头中的自我纠正)、发现、会话承诺以及渲染的案例报告 —— 均按原样提交在 [`samples/video_demo_run/`](samples/video_demo_run/) 中,因此视频中的每一帧终端输出都可以追溯到记录的工具执行过程。规范的提交结果仍保留在 [`samples/`](samples/) (incident_01) 和 [`samples/alihadi_01/`](samples/alihadi_01/) 中。 ## 准确性和验证方法 EvilTrace 测量两个不同的事物并将它们分开: 1. **基础/推理约束准确性** *(自包含 —— 这是区分点)。* 对于每一个发现,引用的行是否存在,是否与 LLM 前的哈希匹配,以及它是否确实支持该声明?这不需要外部答案 —— 仅从仓库即可验证。 2. **调查召回率** *(需要外部答案)。* Agent 是否找到了人类会找到的所有内容?这**尚未**进行外部基准测试,准确性报告中已明确说明了这一点。 `validator.py` 中的真实摘录(已裁剪): ``` [F001] ✔ GROUNDED mft_output.csv:L219674 files matched : procdump.exe sizes matched : 515776 bytes path corrob. : tdungan, dashlane, procdump.exe integrity : VERIFIED (input_seal=OK, csv_seal=SEALED_OK) [F004] ~ INFERRED SOFTWARE_recmd.csv:L31 files matched : msascuil.exe MISSING : file:vmtoolsd.exe -> not GROUNDED integrity : VERIFIED (input_seal=OK, csv_seal=SEALED_OK) ``` F004 一针见血地展示了护城河:agent 的声明引用了被引用行中不包含的文件,因此验证器**自动将其从 GROUNDED 降级为 INFERRED** —— 无需人工盘问。 参考运行还正确地**拒绝了相似项**,而不是过度报告 —— 例如 `LogUploader.dll` 和 `Qt5*.dll`(合法的 OneDrive/Dashlane 组件)、`csscan.exe`(McAfee)、`remsh.exe`(Windows `rempl`)和 Office 安装程序二进制文件 —— 并记录了**零幻觉发现**。仅存在于内存镜像中的记录在案的 IOC(例如 `STUN.exe`、`msedge.exe`、`172.15.1.20`)被正确地从磁盘发现中**剔除**,而不是被捏造。 ## 审计追踪和证据完整性 审计追踪不是叙事性的总结 —— 它是关于 agent 和工具实际执行操作的结构化证据。任何发现都可以通过以下单一链条追溯: ``` finding → artifact citation (file:LINE) → tool_runs/ raw output → pre-LLM SHA-256 seal in execution_log.jsonl ``` `execution_log.jsonl` 包含三种记录类型: - **tool runs(工具运行)** —— 时间戳、工具、命令、返回代码、原始输出路径、LLM 前 SHA-256(对于解析的 CSV 包含一个 `csv_seal`), - **`self_correction`(自我纠正)** —— 当发生确定性工具错误时,记录该决策,将结构化错误返回给模型,并且模型重定向(这*不是*盲目重试), - **`llm_turn`(LLM 轮次)** —— 每轮时间戳、模型、停止原因以及输入/输出 token 使用量。 验证器的完整性判定准确描述了链条可以被证明到的程度: | 判定 | 含义 | |---|---| | `VERIFIED` | 输入工件密封**和**解析后的 CSV 密封均匹配 | | `INPUT_VERIFIED` | 输入工件密封匹配;解析器未发出 CSV 密封 | | `CSV_VERIFIED` | 自捕获以来解析后的输出是字节稳定的;生产者链条无法通过正则表达式追踪 | | `RAW_VERIFIED` | 原始工具输出密封匹配(用于内存/Volatility 发现) | ## 数据集文档 完整的来源信息位于 [`datasets/README.md`](datasets/README.md) 中。简而言之:Operation SHIELDBASE,主机 `base-rd-01`,磁盘镜像 `rd01.E01`(EWF,单卷 NTFS,镜像 MD5 `391be74b6830344eace7272f697cf1ae`)。证据文件**不**包含在本仓库中。 ## 提交合规性 | 要求 | 位置 | |---|---| | 公开的 GitHub 仓库 | 本仓库 | | 开源许可证 (MIT) | [`LICENSE`](LICENSE) | | 演示视频 | (Devpost 提交链接) | | 架构图(基于 Prompt 与架构性护栏) | 上方的[架构](#architecture) | | 数据集文档 | [`datasets/README.md`](datasets/README.md) | | 准确性报告 | [`samples/accuracy_report.md`](samples/accuracy_report.md)(磁盘)+ [`samples/accuracy_report_memory.md`](samples/accuracy_report_memory.md)(内存) | | 试用说明 | 上方的[在本地试用](#try-it-out-locally-on-sans-sift-workstation) | | Agent 执行日志(时间戳 + token 使用量) | [`samples/execution_log.jsonl`](samples/execution_log.jsonl) | ## 已知局限 - 主要的调查 agent 是**原生 Anthropic SDK 循环**。`eviltrace_mcp.py` 是一个独立的自定义 MCP Server 接口,用于在相同的包装层上演示 MCP 模式;它**不**在 agent 的运行时路径中。 - 该流水线针对参考镜像(EWF,单卷 NTFS)进行了调优。其他镜像格式可能需要调整。 - 基础准确性是自包含且可验证的;**调查召回率尚未**针对独立的参考答案进行外部基准测试。 - 当单个被引用的行无法证明整个声明时,某些发现被有意设置为 `INFERRED` —— 这是设计使然,而不是缺陷。 - 本地 SIFT 工具路径可能因工作站构建版本而异。 - 公开仓库中不包含证据文件。 ## 负责任的使用和法律声明 EvilTrace 是一个研究原型。AI 是供训练有素的事件响应专业人员使用的工具;对发现准确性和完整性的责任仍由人类审查员承担。仅在您被授权分析的系统和使用的数据上使用。本软件“按原样”提供,不提供任何形式的保证 —— 参见 [`LICENSE`](LICENSE)。 SIFT Workstation 是 SANS Institute 的产品。 ## 致谢 由 Anand Kumar 为 SANS *Find Evil!* AI 黑客松 (2026) 构建。EvilTrace 扩展了 Protocol SIFT 参考架构(Rob T. Lee, SANS)。其抗击幻觉的设计参考了 Brian Carrier 博士在 DFIR 中关于 AI 验证的工作 (cybertriage.com)。实施过程得到了 Claude Code (Anthropic) 的协助。评估数据集是 SANS Operation SHIELDBASE 场景。 ## 许可证 MIT —— 参见 [`LICENSE`](LICENSE)。
标签:DLL 劫持, 大语言模型, 库, 应急响应, 数字取证, 自主智能体, 自动化脚本, 证据验证, 逆向工具