docs: rewrite README for EvidenceGraph + 5-phase + 7-agent architecture

Previous README described a Blackboard-based 4-phase, 6-agent system.
The actual code uses:
- EvidenceGraph with typed weighted edges (Phenomenon/Hypothesis/Entity)
- 5 phases (explicit Hypothesis Generation between survey and investigation)
- 7 agents (added HypothesisAgent)

Documents the confidence update formula, Phenomenon Jaccard merging,
Asset Library inode dedup, tool-result caching, Gap Analysis coverage
check, auto-persistence, and the resume mechanism.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
BattleTag
2026-05-12 14:09:59 +08:00
parent 097d2ce472
commit fde96c7d9f

231
README.md
View File

@@ -2,43 +2,114 @@
Multi-Agent System for Digital Forensics — 基于大语言模型的多智能体电子取证系统。
系统通过 6 个专业化 Agent 协同工作,对磁盘镜像进行自动化取证分析,最终生成结构化的取证报告。
系统通过 7 个专业化 Agent 协同工作,对磁盘镜像进行自动化取证分析,最终生成结构化的取证报告。Agent 之间不直接通信,通过共享的 **EvidenceGraph**(证据知识图)协作。
## 架构
```
main.py 入口:配置加载、恢复检测、运行管理
main.py 入口:配置加载、镜像选择、断连恢复
├── Orchestrator 阶段流水线调度
├── Orchestrator 阶段流水线调度
│ │
│ ├── FileSystemAgent 磁盘结构、文件系统、删除文件、Prefetch
│ ├── RegistryAgent 注册表分析(系统/用户/网络/软件)
│ ├── CommunicationAgent 邮件、IRC 聊天记录
│ ├── FileSystemAgent 分区/文件系统、目录、删除文件、Prefetch
│ ├── HypothesisAgent 生成假设,链接已有证据
│ ├── RegistryAgent 注册表分析SYSTEM/SOFTWARE/SAM/NTUSER.DAT
│ ├── CommunicationAgent 邮件、IRC/mIRC 聊天记录
│ ├── NetworkAgent 浏览器历史、PCAP 抓包
│ ├── TimelineAgent 跨类别时间线关联
│ └── ReportAgent 综合报告生成
├── Blackboard 共享知识库Evidence + Lead
── LLMClient Claude API 调用ReAct 模式)
├── EvidenceGraph 带类型边的证据知识图(自动持久化
── AgentFactory 角色模板 + 动态 Agent 组合
├── ToolRegistry 工具目录 + 结果缓存
└── LLMClient Claude API 客户端异步、tool-use
```
Agent 之间不直接通信,通过 **Blackboard黑板** 共享发现Evidence和线索Lead
## EvidenceGraph证据知识图
## 调查流程
三类节点 + 类型化加权边:
| 节点 | 前缀 | 含义 |
|---|---|---|
| `Phenomenon` | `ph-*` | 可观测的取证产物(一条具体发现) |
| `Hypothesis` | `hyp-*` | 解释性假设(待验证的论断) |
| `Entity` | `ent-*` | 人、程序、主机、IP 等可复现的实体 |
Phenomenon → Hypothesis 的边类型与权重写死在 `HYPOTHESIS_EDGE_WEIGHTS`
| 边类型 | 权重 | 语义 |
|---|---:|---|
| `direct_evidence` | +0.25 | 现象就是假设所述行为本身 |
| `supports` | +0.15 | 与假设一致但非决定性 |
| `consequence_observed` | +0.15 | 观察到假设预期的结果 |
| `prerequisite_met` | +0.10 | 满足假设的前置条件 |
| `weakens` | 0.10 | 降低假设可能性 |
| `contradicts` | 0.20 | 直接反驳假设 |
置信度更新公式(收敛于 [0, 1]
- 正向边:`delta = weight * (1 - old_conf)`
- 负向边:`delta = weight * old_conf`
跨阈值自动转状态:≥ 0.8 → `supported`,≤ 0.2 → `refuted`,跑完仍 active → `inconclusive`。LLM 只负责挑边类型(分类任务),权重表与状态转移由代码裁决,避免数值幻觉。
新增 Phenomenon 时通过 Jaccard 相似度合并title > 0.6 且 description > 0.4 即视为重复,合并后提升置信度并追加 `corroborating_agents`),避免同一发现被重复入图。
## 五阶段流水线
| 阶段 | 说明 |
|------|------|
| **Phase 1** | FileSystemAgent 勘查磁盘镜像,识别分区、目录结构、关键文件,产出初始 Lead |
| **Phase 2** | 多轮线索追踪 — Lead 按 Agent 类型分组并行派发,最多 10 轮迭代 |
| **Phase 2.5** | 覆盖率缺口分析 — 对照 config.yaml 中的 10 个调查领域,自动补漏 |
| **Phase 3** | TimelineAgent 综合所有 evidence 建立事件时间线 |
| **Phase 4** | ReportAgent 生成 Markdown 格式取证报告 |
| **Phase 1** | FileSystemAgent 勘镜像,识别分区/文件系统/关键路径,产出首批 Phenomenon |
| **Phase 2** | 假设生成 — 优先读 `config.yaml:hypotheses`;未配置则由 HypothesisAgent 从 Phase 1 现象自动生成 3-7 个 |
| **Phase 3** | 假设驱动调查(默认 5 轮迭代)。每轮:一次性为所有 active 假设产出 leads → 按 agent 类型并发派发(信号量 = 3→ 一次性判定新现象与各假设的关系。所有假设收敛即提前退出。末尾:失败 lead 重试一次 + Gap Analysis |
| **Phase 4** | TimelineAgent `build_filesystem_timeline` 生成 MAC 时间线,与 Phenomenon 时间戳关联 |
| **Phase 5** | ReportAgent 综合假设、证据、实体,生成 Markdown 报告 |
## 取证工具链
### Gap AnalysisPhase 3 末)
### Sleuth Kit磁盘取证
`config.yaml:investigation_areas` 列出必须覆盖的调查领域系统信息、用户账户、网络配置、邮件配置、IRC 日志、PCAP、删除文件、Prefetch 等。Orchestrator 两层判定覆盖情况:
通过异步子进程调用 TSK 命令行工具:
1. **关键词匹配**`_AREA_KEYWORDS`)— 扫现有 Phenomenon 标题/描述
2. **工具命中**`_AREA_TOOLS`)— 检查是否调用过该领域的关键工具(如 `enumerate_users``parse_pcap_strings`
未覆盖的领域自动派发 lead最多 3 轮补漏。
## Agent 体系
`AgentFactory` 维护 7 个角色模板(`ROLE_TEMPLATES`),每个模板指定默认工具集。`HypothesisAgent``ReportAgent``BaseAgent` 的子类(额外注册专用工具),其余 5 个 Agent 直接由 `BaseAgent` + 工具列表生成。
### Agent 工作流
`BaseAgent.run` 在 system prompt 中强制四阶段:
```
A. INVESTIGATE 先查图状态 / Asset Library再调取证工具
B. RECORD 每条发现写 add_phenomenon
C. LINK 按需 link_to_entity但禁止凭记忆引用 ph-id必须先 list_phenomena
D. ANSWER 以上完成后再给最终答复
```
prompt 内置**反幻觉规则**:只允许记录工具输出中逐字出现的内容;时间戳/路径/inode 必须来自工具返回;输出被截断须标 `[truncated]`
### 动态 Agent 组合
`AgentFactory.create_specialized_agent()` 应对能力缺口:将工具目录与假设描述喂给 LLM由其挑 3-8 个工具并写角色描述,工厂据此实例化新 Agent 并缓存。
## 工具系统
`tool_registry.py` 启动时调用 `register_all_tools(image_path, partition_offset, graph)`,将所有工具一次性注册到全局 `TOOL_CATALOG`
### 工具结果缓存
`CACHEABLE_TOOLS` 集合标记纯读取/确定性工具partition_info、list_directory、parse_registry_key …)。镜像只读,同 args 调用产出固定,命中缓存直接复用,错误结果不入缓存。
### Asset Library
`EvidenceGraph.asset_library` 按 inode 索引所有已提取文件,避免重复 extract。Agent 通过 `list_assets` / `find_extracted_file` 工具查询。新文件按文件名自动归类到 `registry_hive` / `chat_log` / `prefetch` / `network_capture` / `recycle_bin` 等十类之一。
### 取证工具链
**Sleuth Kit磁盘取证** — 异步子进程调用 TSK
| 工具 | 用途 |
|------|------|
@@ -49,47 +120,43 @@ Agent 之间不直接通信,通过 **Blackboard黑板** 共享发现E
| `srch_strings` | 磁盘字符串搜索 |
| `fls -m` | MAC 时间线生成 |
### regipy注册表解析
**regipy注册表解析** — 直接读 SYSTEM / SOFTWARE / SAM / NTUSER.DAT 二进制,提取系统信息、用户账户、网络配置、已安装软件、邮件账户、关机时间等。
直接解析 Windows 注册表 hive 二进制文件SYSTEM、SOFTWARE、SAM、NTUSER.DAT提取系统信息、用户账户、网络配置、已安装软件、邮件账户、关机时间等
**文件解析器** — Prefetch 二进制(`.pf`、PCAP 字符串提取HTTP 请求 / Host / Cookie / UA、通用文本与二进制读取、正则搜索、Hex dump
### 文件解析器
## 断连恢复与运行归档
- **Prefetch** — 二进制解析 Windows XP .pf 文件(运行次数、最后执行时间)
- **PCAP** — 从抓包文件提取 HTTP 请求、Host、Cookie、User-Agent
- **通用文本/二进制** — 按偏移读取、正则搜索、Hex dump
三层防护:
## 断连恢复与数据归档
1. **EvidenceGraph 自动持久化** — 每次 `add_phenomenon` / `add_hypothesis` / `add_edge` / `add_lead` 等写操作均自动落盘(原子写 `.tmp` 后 rename
2. **Agent 级容错** — 单 Agent 失败 → 该 lead 标 `failed`,连续 3 次失败触发 `AnalysisAborted` 优雅退出Phase 3 末尾对失败 lead 重试一次(`retry=True` 防无限循环)
3. **续跑**`main.py` 启动时扫 `runs/*/graph_state.json`,发现存在但缺 `run_metadata.json` 的目录即提示恢复,并按 graph 当前状态决定从哪一阶段续起
系统设计了三层防护,应对长时间运行中的网络中断:
1. **Blackboard 自动持久化** — 每次 add_evidence / add_lead 自动写盘(原子写入)
2. **Agent 级容错** — 单个 Agent 失败标记 Lead 为 failed不影响其他 Agent自动重试一次
3. **优雅退出** — 连续 3 次 Agent 失败后保存现有成果并干净退出
每次运行自动创建带时间戳的归档目录:
### 运行归档目录
```
runs/
2026-04-02T14-30-00/
config.yaml 配置快照
blackboard_state.json 实时状态(用于恢复
evidence.json 结构化证据导出
leads.json 线索及最终状态
report.md 取证报告
run_metadata.json 运行元数据(时长、统计、错误)
masforensics.log 运行日志
config.yaml 配置快照
graph_state.json 实时状态(续跑用)
phenomena.json 现象导出
hypotheses.json 假设 + 置信度日志
entities.json 实体
edges.json
leads.json 线索及最终状态
extracted/ 从镜像提取的文件
<image>_forensic_report.md 取证报告
run_metadata.json 运行元数据(时长、统计、错误)
masforensics.log 运行日志
```
中断后再次运行 `python main.py`,系统自动检测未完成的运行并提示恢复。
## 快速开始
### 环境要求
- Python >= 3.14
- The Sleuth Kit系统安装提供 `mmls``fls``icat` 等命令)
- 磁盘镜像文件置于 `image/` 目录
- 磁盘镜像文件
### 安装
@@ -99,50 +166,76 @@ uv sync
### 配置
编辑 `config.yaml`,填入 LLM API 地址和密钥
编辑 `config.yaml`
```yaml
agent:
base_url: "https://your-api-proxy.com"
api_key: "sk-your-key"
model: "claude-sonnet-4-6"
max_tokens: 4096
max_tokens: 16384
max_investigation_rounds: 5 # Phase 3 最大迭代轮数
# hypotheses: # 可选:手动指定初始假设
# - title: "嫌疑人主动实施网络嗅探"
# description: "..."
investigation_areas: # Gap Analysis 必须覆盖的领域
- area: system_info
agent: registry
task: "..."
# ...
```
`investigation_areas` 部分定义了必须覆盖的调查领域,可按需增减
未配置 `hypotheses` 时由 HypothesisAgent 自动生成
### 运行
```bash
python main.py
python main.py # 交互式选镜像与分区
python main.py /path/to/image/dir # 指定镜像目录
```
报告和所有结构化数据将保存在 `runs/<timestamp>/` 目录下
中断后再次运行会自动检测未完成的 run 并提示是否续跑
### 仅重生成报告
跑完一次后若只想换提示词或修复报告:
```bash
python regenerate_report.py runs/<timestamp>
```
跳过 Phase 1-4直接从已有 `graph_state.json` 重跑 ReportAgent。
## 项目结构
```
MASForensics/
├── main.py 入口
├── orchestrator.py 流水线调度
├── blackboard.py 共享知识库
├── llm_client.py LLM API 客户端
├── base_agent.py Agent 基类
├── config.yaml 配置文件
├── main.py 入口、镜像选择、断连恢复
├── orchestrator.py 五阶段流水线调度
├── evidence_graph.py 证据知识图 + 边权重表 + 持久化
├── base_agent.py Agent 基类 + 内建 graph 工具
├── agent_factory.py 角色模板 + 动态 Agent 组合
├── tool_registry.py 工具目录 + 结果缓存 + 自动归类
├── llm_client.py LLM API 客户端
├── log_config.py 彩色终端日志 + 文件日志
├── regenerate_report.py 从已有 graph_state 重生成报告
├── config.yaml 配置 + 调查领域 + 可选假设
├── agents/
│ ├── filesystem.py 文件系统 Agent
│ ├── registry.py 注册表 Agent
│ ├── communication.py 通信 Agent
── network.py 网络 Agent
│ ├── timeline.py 时间线 Agent
│ └── report.py 报告 Agent
│ ├── hypothesis.py HypothesisAgentadd_hypothesis、link
│ ├── report.py ReportAgent综合报告自带读取工具
│ ├── timeline.py TimelineAgent保留以备扩展
── ... filesystem/registry/communication/network同上
├── tools/
│ ├── sleuthkit.py Sleuth Kit 封装
│ ├── registry.py 注册表解析(regipy
│ └── parsers.py 文件格式解析
├── image/ 磁盘镜像
├── extracted/ 提取的文件(运行时生成)
└── runs/ 运行归档
│ ├── sleuthkit.py TSK 异步封装
│ ├── registry.py regipy 解析
│ └── parsers.py Prefetch / PCAP / 通用文件解析
├── image/ 磁盘镜像(用户放)
├── runs/ 运行归档
└── tests/
└── test_optimizations.py
```
## 依赖
@@ -152,14 +245,16 @@ MASForensics/
| `httpx[socks]` | 异步 HTTP 客户端(支持 SOCKS 代理) |
| `pyyaml` | 配置文件解析 |
| `regipy` | Windows 注册表 hive 解析 |
| `pytest` / `pytest-asyncio` | 测试 |
## 当前案例
## 默认案例
默认配置分析 **CFReDS Hacking Case**NIST 标准取证教学镜像):
**CFReDS Hacking Case**NIST 标准取证教学镜像):
- 镜像SCHARDT.001~4.6GBIBM 硬盘8 个分段)
- 镜像SCHARDT.001~4.6 GBIBM 硬盘8 个分段)
- 系统Windows XP
- 场景:涉嫌黑客入侵的计算机取证分析
- 完整镜像 MD5`AEE4FCD9301C03B3B054623CA261959A``config.yaml` 含各分段 MD5 用于校验)
## 测试