# 🛡️ VeriSIFT
### 架构原生**只读**。设计内建**自纠错**。
*一个类型化的 MCP 事件响应 Agent,让证据损毁变得**不可能**
,而不仅仅是被禁止——并在人类察觉之前捕获自身的幻觉。*
`Python` · `Model Context Protocol` · `SANS SIFT Workstation` · `DFIR`
**架构模式:** 自定义 MCP Server (#2) ⊕ 持久化学习循环 (#7) — *融合,而非堆叠。*
## ⚡ 30 秒概览
**VeriSIFT 将保障从*指令*层面转移到了*架构*层面:**
| | 基于 Prompt 的 Agent | **VeriSIFT** |
|---|---|---|
| **它能删除证据吗?** | 被告知不能 | ❌ **代码中不存在写入路径** |
| **镜像可写?** | 信任 Prompt | 🔒 **拒绝启动 (fail-closed)** |
| **它知道自己何时出错吗?** | 否 | ✅ **剔除无支撑的声明,标记推断** |
| **陪审员能追溯发现结果吗?** | 否 | 📒 **每次工具调用 → 一条 JSONL 审计记录** |
## 🎬 真实运行示例
一个真实的、**计算得出**的(非脚本预设的)跨三个独立取证工件的关联:
```
STAGE 5 — final report [honest: only what the artifacts support]
[CONFIRMED] execution notepad.exe conf=1.0 supports=['amcache', 'evtx_4688', 'prefetch']
[INFERRED ] logon Administrator conf=0.5 supports=['evtx_4624']
injected test claim dropped: 1 (EVILCORP.EXE — no corroborating artifact, caught by the verifier)
iteration trace:
iter 1: confirmed=0 inferred=2 dropped=1 (hallucination caught)
iter 2: confirmed=1 inferred=1 dropped=0 (notepad corroborated → confirmed)
```
- **`notepad.exe`** 被标记为已确认,仅仅是因为 `correlate()` *机械地*在一条真实的 Event ID 4688 进程创建记录**和**一条真实的 Amcache 条目(外加第三个 prefetch 来源)中匹配到了它的基本名。即使摒弃其中任何一个来源,它依然能通过另外两个来源得到确认。
- **`Administrator` 登录**保持诚实地被标记为**已推断** — 单一来源 (4624),未夸大。
- **`EVILCORP.EXE`** 是一个明确标记的、无支撑工件的合成声明 — 验证器**自动将其剔除**。这就是在镜头记录下的自纠错过程。
## 🏗️ 架构
**核心设计原则:** Agent 只能通过类型化的工具接触证据。
代码中不存在任何写入路径 — 这是**架构层面的保证**,而非 Prompt 指令。
```
┌────────────┐ typed tool calls ┌────────────────────┐
│ Agent │ ───────────────────► │ VeriSIFT MCP │
│ (Claude │ │ server.py │
│ Code) │ ◄─────────────────── │ • open_evidence │
└─────┬──────┘ structured JSON │ • parse_evtx │
│ findings │ • get_amcache │
▼ │ • extract_mft_… │
┌────────────┐ │ • analyze_prefetch│
│ verify.py │ cross-artifact └─────────┬──────────┘
│ gate+loop │ corroboration │ read-only
└─────┬──────┘ ┌───────▼────────┐
│ iteration traces │ evidence.py │
▼ │ O_RDONLY + │
┌────────────┐ │ fail-closed │
│ audit.py │ JSONL execution log └───────┬────────┘
└────────────┘ ┌───────▼────────┐
│ parsers.py → │
│ TSK / regipy / │
│ pyscca / evtx │
└───────┬────────┘
read-only image
═══ trust boundary ══════════════════════════════════════════════
The agent cannot reach the image except through typed tools.
No write path exists in code. This is ARCHITECTURAL, not a prompt.
```
## 🔬 紧密锁定的两层结构
### 1 · 类型化 MCP server — 架构护栏
Agent 不再使用通用的 `execute_shell`,而是**仅**获得五个类型化的只读工具。
破坏性命令根本无法被下发,因为**该能力在 server 中并不存在**。
- 证据以 `O_RDONLY` 方式打开;如果设置了任何写入位,则会**闭环失败** (`evidence.py`)。
- 镜像 SHA-256 在打开时计算哈希;可重新计算哈希以证明前后的完整性。
### 2 · 自纠错验证循环 — 学习层
Agent 将发现结果作为结构化的声明提出。校验门会将每一项与**独立的**工件进行交叉核对,并给出裁定:
| 相互印证的工件 | 裁定 | 置信度 |
|---|---|---|
| 0 — 无任何支撑 | `unsupported` → **剔除** (捕获幻觉) | 0.0 |
| 1 — 单一来源 | `inferred` (诚实标记) | 0.5 |
| 2 | `confirmed` | 0.75 |
| 3 | `confirmed` | 1.0 |
冲突会触发一次条件收紧的重新运行,**上限为 4 次迭代**以防止失控执行。
每次迭代均会被记录。
## 🧰 五个工具
| 工具 | 底层支持 | 返回值 |
|---|---|---|
| `open_evidence(path)` | `evidence.py` (`O_RDONLY`, SHA-256) | 元数据 + `read_only: true` |
| `parse_evtx(channel, event_ids)` | `python-evtx` | 结构化事件记录 |
| `get_amcache(name_contains?)` | `regipy` | `name · sha1 · first_seen · path · registry_key` |
| `extract_mft_timeline(start?, end?)` | `MFTECmd` (EZ Tools) | `path · created · modified · accessed · entry · size` |
| `analyze_prefetch(executable?)` | `pyscca` (libscca) | `name · run_count · last_run_times · source_pf` |
这四个解析器均**针对真实工件进行了验证**,并带有逐条记录的 `try/except`,因此单条损坏的记录永远不会中断整个解析过程。
## 🚀 快速开始
```
# 1. 安装依赖项 (SANS SIFT Workstation)
pip3 install -r requirements.txt # mcp · regipy · python-evtx · pyscca
# 外加 MFTECmd (EZ Tools / dotnet) 和 The Sleuth Kit 在 PATH 上
# 2. 将证据设为只读 — fail-closed 执行
chmod 0444 /path/to/evidence.E01
# 3. 运行端到端演示 (驱动真实 MCP 工具 + verify 循环)
VERISIFT_LOG=./exports/execution_log.jsonl python3 demo_investigation.py
```
**实时观察审计轨迹流 (终端 1):**
```
export VERISIFT_LOG=./exports/execution_log.jsonl
rm -f "$VERISIFT_LOG"; touch "$VERISIFT_LOG"
echo "VeriSIFT audit trail — live:"; tail -f "$VERISIFT_LOG"
```
## 📂 仓库布局
```
verisift/
├── server.py # FastMCP server — 5 typed tools
├── evidence.py # Read-only guardrail (O_RDONLY, fail-closed, SHA-256)
├── parsers.py # 4 verified parsers + correlate() corroboration engine
├── verify.py # Classification + bounded self-correction loop
├── audit.py # JSONL execution log (run_id, seq, duration)
├── demo_investigation.py # End-to-end demo driver (real tools, computed correlation)
├── ACCURACY_REPORT.md # Self-assessed accuracy + integrity proof
├── PROJECT_DESCRIPTION.md # Inspiration · build · lessons
├── analysis/
│ └── make_test_prefetch.py # Builds the synthetic .pf (transparent provenance)
└── test_data/ # Minimal reproducibility fixtures (see provenance below)
├── evtx/ · amcache/ · mft/ · prefetch/
```
### 测试数据来源 (对评审完全透明)
| 工件 | 真实 / 合成 | 来源 |
|---|---|---|
| EVTX (`NTLM2SelfRelay-…evtx`) | **真实** | sbousseaden/EVTX-ATTACK-SAMPLES (med0x2e 采集) |
| Amcache (`amcache.hve`) | **真实** | regipy 验证的 Win10 hive (包含 `notepad.exe`) |
| MFT (`MFT_extracted.bin`) | **真实** | 从合成 NTFS 镜像中提取的 `$MFT` |
| Prefetch (`NOTEPAD.EXE-…pf`) | **合成** | 字节级精确的 v30,基于 libscca 规范构建,由**真实的** pyscca 解析 |
完整的来源、SHA-256 哈希值及复现步骤:[`DATASET.md`](DATASET.md)。
## 🎯 为何这在评分标准中胜出
| 评审标准 | VeriSIFT 如何应对 |
|---|---|
| **自主执行** (决胜环节) | 循环无需人工干预即可重新运行并收紧参数。 |
| **IR 准确性** | 多工件相互印证剔除幻觉;单一来源被标记为*已推断*。 |
| **约束实现** | 不存在 shell 工具;证据为 `O_RDONLY`,若可写则闭环失败。 |
| **审计轨迹** | 每次工具调用 → 一条 JSONL 记录:`run_id`, `seq`, timestamp, duration。 |
| **广度与深度** | 深入磁盘工件,实现真正的跨工件关联 (MFT × prefetch × amcache × EVTX)。 |
## ⚖️ 诚实的局限性
设计上范围限于磁盘镜像工件 — 追求深度而非广度。相互印证规则基于启发式算法;坚定的反取证行为者可能会破坏跨工件的一致性。准确性取决于底层的经法庭验证的解析器。请参阅 [`ACCURACY_REPORT.md`](ACCURACY_REPORT.md) 获取实际测量的数据,而非单纯的声明。
## 📜 License
MIT.