内容
# pathhound-mcp
**MCP(模型上下文协议)服务器**,允许大型语言模型(LLM)对活动目录攻击图进行推理,该图已由BloodHound收集——到Tier 0的最短路径,从主体到爆炸半径的权限范围,缓解关键阻塞点的最高杠杆作用,以及针对防御者的缓解文本——每次操作都限定在授权的参与范围内并记录日志。
> **仅限授权渗透测试使用。** 该服务器从不触及实时域,从不收集数据,从不运行攻击。数据收集单独进行(SharpHound / `bloodhound-python`);该工具仅读取和推理Neo4j中生成的图。参见[安全.md](安全.md),了解完整的使用边界。
## 功能
- **将收集的图转化为可解释的答案。** 询问“到Domain Admins的最短路径是什么”,“如果我拥有这个账户,什么变得可达”,或“应该首先修复哪些边”并获得结构化结果。
- **设计上只读并限定范围。** 它拒绝在没有参与范围的情况下启动,拒绝查询该范围以外的域,拒绝写/破坏性Cypher,并将每个调用追加到审计日志中。
- **面向防御者的输出。** `explain_edge`和`remediation_for_path`生成报告-ready的缓解措施,而不是利用命令。
### 工具
| 工具 | 返回内容 |
| --- | --- |
| `list_domains()` | 图中的域/森林,节点数和范围标志。 |
| `run_cypher(query, params)` | 只读Cypher查询的结果。写入子句被拒绝,除非设置`allow_writes`;破坏性/外部操作始终被拒绝。结果按行限制,带有截断标志。 |
| `shortest_paths_to_tier0(start, max_paths)` | 到Tier 0 /高价值目标的最短攻击路径——从`start`(范围内主体)或从每个`owned`主体开始。每个路径是有序的`start —[edge]→ end`跳转列表。 |
| `reachable_from(principal, max_hops)` | 从主体到权限范围的总结,按节点类型,突出任何Tier 0可达性。 |
| `find_choke_points(top_n)` | 出现在到Tier 0的最不同的最短路径中的边,每个边都有一个移除它会破坏的路径数。 |
| `explain_edge(edge_type)` | BloodHound边的普通语言原因(如`GenericAll`,`AddKeyCredentialLink`,`DCSync`)是可利用的,技术名称,防御者缓解措施和参考指针。 |
| `remediation_for_path(path_id_or_cypher)` | 对于路径(作为只读Cypher查询返回路径`p`),每个跳转的具体ACE /委托/成员资格更改,适用于报告。 |
| `engagement_summary()` | 报告的要点:主体,拥有,高价值,到Tier 0的独特路径和顶级阻塞点。 |
### 资源
| 资源 | 内容 |
| --- | --- |
| `pathhound://engagement-scope` | 活动范围(参与ID,授权参考,允许域,写入标志)和带有密码掩码的Neo4j目标。 |
| `pathhound://cypher-library` | 精选的,已命名的只读Cypher查询集(Kerberoastable,无约束委托,AS-REP roastable,到Domain Admins的路径,主体ACL滥用...),每个在加载时都经过验证的只读查询。 |
### 可选写入工具(默认关闭)
两个工具——`mark_owned(principal, confirm)`和`set_high_value(principal, confirm)`——设置BloodHound的拥有/Tier 0标记(无其他操作),以便路径工具相应地处理这些节点。它们仅在`scope.yaml`中设置`allow_writes: true`时存在;每个调用还需要显式的`confirm=true`,主体在范围内,并经过审计。它们从不删除或丢弃。保持`allow_writes: false`(默认值)以实现严格的只读部署。
## 要求
- Python 3.11+
- 可通过Bolt访问的**BloodHound CE** Neo4j实例(图形单独收集和摄入-参见下面的快速入门)
## 安装
```bash
# 使用uv(推荐):
uv venv && uv pip install -e ".[dev]"
# 或使用pip:
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt && pip install -e .
```
## 配置
两个配置文件:**参与范围**(文件)和**Neo4j连接**(环境变量-凭证从不硬编码)。
**1. 参与范围** - 复制示例并编辑:
```bash
cp scope.example.yaml scope.yaml
```
```yaml
# scope.yaml
engagement_id: "ENG-0001" # 命名审计日志文件
authorization_ref: "SoW-2026-ACME-001 / JIRA-1234"
allowed_domains: # 仅允许查询这些域
- "CORP.LOCAL"
- "CHILD.CORP.LOCAL"
allow_writes: false # 除非需要写标志工具,否则保持false
max_rows: 500 # run_cypher行限制
```
服务器**拒绝启动**如果`scope.yaml`丢失或`allowed_domains`为空-这是故意的;没有无范围的查询。域名与BloodHound的大写FQDN不区分大小写匹配。
**2. Neo4j连接** - 通过环境变量(或`.env`;参见`.env.example`):
```bash
export NEO4J_URI="bolt://127.0.0.1:7687"
export NEO4J_USER="neo4j"
export NEO4J_PASSWORD="…"
export NEO4J_DATABASE="neo4j" # 可选,默认为neo4j
# export PATHHOUND_SCOPE="/abs/path/scope.yaml" # 可选;默认为./scope.yaml
```
## 运行
作为独立的标准输入输出MCP服务器:
```bash
pathhound-mcp # 或: python -m pathhound_mcp.server
```
### 注册MCP客户端
将客户端指向控制台脚本(使用虚拟环境中的绝对路径,例如`/path/to/pathhound-mcp/.venv/bin/pathhound-mcp`),并通过环境传递连接+范围。示例(Claude Desktop `claude_desktop_config.json`):
```json
{
"mcpServers": {
"pathhound": {
"command": "/path/to/pathhound-mcp/.venv/bin/pathhound-mcp",
"env": {
"NEO4J_URI": "bolt://127.0.0.1:7687",
"NEO4J_USER": "neo4j",
"NEO4J_PASSWORD": "…",
"PATHHOUND_SCOPE": "/path/to/pathhound-mcp/scope.yaml"
}
}
}
}
```
### 向LLM提问示例
连接后,操作员可以询问以下问题:
- *"列出图中的域及其大小。"* → `list_domains`
- *"哪些账户是Kerberoastable的?"* → `run_cypher`使用`kerberoastable_users`库查询
- *"显示到Tier 0的最短攻击路径。"* → `shortest_paths_to_tier0`
- *"如果我入侵`alice@corp.local`,什么变得可达?"* → `reachable_from`
- *"我们应该首先修复哪些前10个阻塞点?"* → `find_choke_points`
- *"为什么`AddKeyCredentialLink`危险,如何修复它?"* → `explain_edge`
- *"给我这个攻击路径的缓解步骤。"* → `remediation_for_path`
- *"为报告总结一下参与情况。"* → `engagement_summary`
## 快速入门:收集到BloodHound,然后指向Neo4j
该服务器仅读取**已收集**的图;数据收集单独进行,不使用此工具。
1. **收集**域与SharpHound或`bloodhound-python`在授权参与期间。你会得到一组JSON文件(或zip)- 来自实验室,如[GOAD](https://github.com/Orange-Cyberdefense/GOAD)(GOAD-Light〜16 GB,完整GOAD〜32 GB)或实际参与。
2. **建立BloodHound CE并摄入数据。** 官方的compose堆栈运行Neo4j(Bolt在`127.0.0.1:7687`),Postgres和BloodHound UI在`:8080`:
```bash
docker compose -f /path/to/docker-compose.yml up -d
# 打开http://localhost:8080,登录并上传收集的zip(管理→文件摄入)。等待摄入+后处理。
```
如果Neo4j卷已经摄入,您可以启动图形:`docker compose -f /path/to/docker-compose.yml up -d graph-db`。
3. **将pathhound-mcp指向Neo4j**(参见[配置](#配置))并运行它。您的`allowed_domains`在`scope.yaml`中应与收集中的域匹配(例如`CORP.LOCAL`)。
### BloodHound架构兼容性
较新的BloodHound CE标签**Tier 0使用`Tag_Tier_Zero`节点标签**和**拥有主体使用`Tag_Owned`**,而较旧的版本使用`highvalue` / `owned`属性(CE还设置`system_tags: admin_tier_0`)。pathhound识别所有这些,因此Tier 0 /拥有推理适用于所有版本。
## 测试
```bash
pytest # 单元测试 - 保障措施,范围,审计,Cypher保障,工具逻辑
```
测试套件是**完全无数据库的**:只读保障措施,范围强制执行,审计日志记录,行限制和路径/报告逻辑都在桩上进行测试,因此`pytest`在几秒钟内运行,无需Neo4j。(工具也已针对真实的BloodHound CE图进行了端到端验证。)
## 项目布局
```
src/pathhound_mcp/
├── server.py # FastMCP应用:工具/资源注册+启动保障
├── config.py # 加载/验证scope.yaml(pydantic);从env获取Neo4j
├── guardrails.py # 只读Cypher保障+范围强制执行
├── audit.py # 追加式JSONL审计日志记录(@audited装饰器)
├── graph.py # Neo4j连接+读取助手(唯一的DB访问)
├── schema.py # 攻击边集+Tier 0 /拥有谓词
├── models.py # pydantic结果模型
├── cypher_library.json / edge_library.json # 精选的只读查询+边知识库
└── tools/ # 清单,查询,路径,报告,边
```
`audit/`,`scope.yaml`和`.env`被gitignore - 将审计日志和收集的图视为参与敏感的。
## 安全模型
参见[安全.md](安全.md),了解预期用途边界和保证:启动时范围,默认只读,范围强制执行,追加式审计日志和无实时域功能。
## 许可证
MIT - 参见[LICENSE](LICENSE)。