praetorian-inc/vespasian
GitHub: praetorian-inc/vespasian
从真实HTTP流量中自动发现API端点并生成OpenAPI、GraphQL SDL和WSDL规范的安全工具。
Stars: 5 | Forks: 0
从真实 HTTP 流量中发现 API 端点。自动生成 OpenAPI、GraphQL SDL 和 WSDL 规范。
# Vespasian:API 发现与规范生成工具
**Vespasian 通过观察真实的 HTTP 流量来发现 API 端点,并根据这些观察结果生成 API 规范文件。** 它通过无头浏览器爬取捕获流量,或从现有来源(Burp Suite XML 导出、HAR 文件和 mitmproxy 转储)导入流量,然后对请求进行分类,探测发现的端点,并以每种 API 类型的原生格式输出规范:REST 使用 OpenAPI 3.0,GraphQL 使用 GraphQL SDL,SOAP 服务使用 WSDL。
专为需要在缺乏 API 文档时映射 Web 应用程序、单页应用和微服务的 API 攻击面的渗透测试人员和安全工程师而构建。
## 为什么选择 Vespasian?
现代应用程序动态地进行 API 调用。单页应用程序通过 JavaScript 在运行时构建请求。移动应用程序通过原生 HTTP 客户端调用 API。实时功能通过 WebSocket 连接通信。静态分析和源代码审查完全无法捕捉这些运行时行为。
现有的 API 发现方法存在局限性:
- **检查已知路径**(`/swagger.json`、`/openapi.yaml`)只能找到被明确记录的 API
- **静态分析** 无法观察在运行时动态构建的请求
- **手动代理捕获** 既耗时又只能产生原始流量,缺乏结构化规范
Vespasian 采用了一种不同的方法:它在网络层级观察实际流量,然后利用分类启发式方法和主动探测自动生成结构化的 API 规范。由于这本质上具有概率性,Vespasian 仅能发现捕获流量中存在的端点,但它能可靠地映射出应用程序在实际使用过程中暴露的 API 面。
## 核心功能
| 功能 | 描述 |
|---------|-------------|
| **REST API 发现** | 通过 content-type、路径模式和响应结构对 REST 端点进行分类;输出 OpenAPI 3.0 |
| **GraphQL API 发现** | 检测 GraphQL 端点,运行分层内省查询(introspection queries),并生成 GraphQL SDL schema |
| **WSDL/SOAP 发现** | 通过 SOAPAction 头和信标检测识别 SOAP 服务;获取并解析 WSDL 文档 |
| **API 类型自动检测** | 从捕获的流量中自动判断 API 类型,无需手动选择 |
| **无头浏览器爬取** | 驱动支持完整 JavaScript 执行的无头 Chrome 浏览器以支持 SPA,由 [Katana](https://github.com/projectdiscovery/katana) 提供支持 |
| **流量导入** | 从 Burp Suite XML、HAR 1.2 文件和 mitmproxy 转储导入现有捕获 |
| **主动探测** | OPTIONS 发现、JSON schema 推断、WSDL 文档获取和 GraphQL 内省 |
| **路径归一化** | `/users/42` 和 `/users/87` 变为 `/users/{id}`,同时保留已知字面量(`/me`、`/self`) |
| **SSRF 保护** | 默认阻止探测私有地址和环回地址。使用 `--dangerous-allow-private` 测试内部目标。 |
| **代理支持** | 通过 Burp Suite 或其他拦截代理路由无头浏览器流量 |
| **两阶段流水线** | 一次捕获,多次生成:分离捕获和生成步骤,实现最大灵活性 |
## 工作原理
Vespasian 使用将流量捕获与规范生成分离的两阶段流水线:
```
flowchart LR
subgraph Capture
A["Headless Browser Crawler
JS execution, auth injection"] --> C["capture.json
ObservedRequest array"]
B["Traffic Importers
Burp Suite XML, HAR, mitmproxy"] --> C
end
subgraph Generate
C --> D["Classifier
REST, GraphQL, WSDL"]
D --> E["Prober
OPTIONS, schema, WSDL, introspection"]
E --> F["Spec Generator
OpenAPI 3.0, GraphQL SDL, WSDL"]
end
```
**为什么分两个阶段:**
- **一次捕获,多次生成。** 对同一份捕获结果运行不同的生成器,无需重新扫描。
- **可调试。** 捕获文件是可检查的 JSON,将捕获错误与生成错误隔离开来。
- **可组合。** 从任何来源(浏览器爬取、代理捕获、移动测试)导入流量。
- **离线分析。** 无需网络访问即可生成规范,适用于时间有限的测试窗口。
## 如何安装 Vespasian
### 从源码安装
```
go install github.com/praetorian-inc/vespasian/cmd/vespasian@latest
```
### 下载预编译二进制文件
从 [Releases](https://github.com/praetorian-inc/vespasian/releases) 页面下载适用于您平台的最新二进制文件。
### 从源码构建
```
git clone https://github.com/praetorian-inc/vespasian.git
cd vespasian
make build
```
## 如何使用 Vespasian 发现 API
### 快速开始:扫描 Web 应用程序
```
# 一步完成 Crawl 并生成 API spec(自动检测 API 类型)
vespasian scan https://app.example.com -o api.yaml
# 使用身份验证
vespasian scan https://app.example.com -H "Authorization: Bearer
" -o api.yaml
# 显式指定 API type
vespasian scan https://app.example.com --api-type graphql -o schema.graphql
```
### 两阶段工作流
```
# 阶段 1:通过 headless browser 捕获流量
vespasian crawl https://app.example.com -o capture.json
# 阶段 1(替代方案):从 Burp Suite 导入流量
vespasian import burp traffic.xml -o capture.json
# 阶段 1(替代方案):从 HAR archive 导入流量
vespasian import har recording.har -o capture.json
# 阶段 1(替代方案):从 mitmproxy 导入流量
vespasian import mitmproxy flows -o capture.json
# 阶段 2:生成用于 REST 的 OpenAPI spec
vespasian generate rest capture.json -o api.yaml
# 阶段 2:生成 GraphQL SDL schema
vespasian generate graphql capture.json -o schema.graphql
# 阶段 2:从 SOAP 流量生成 WSDL
vespasian generate wsdl capture.json -o service.wsdl
```
### 常用选项
```
# 通过 Burp Suite 路由 crawl 流量
vespasian scan https://app.example.com --proxy http://127.0.0.1:8080 -o api.yaml
# 扫描本地/私有目标(绕过 SSRF 保护)
vespasian scan http://localhost:3000 --dangerous-allow-private -o api.yaml
# Verbose 输出以实时查看发现的请求
vespasian scan https://app.example.com -v -o api.yaml
# 隐藏启动 banner
vespasian --no-banner scan https://app.example.com -o api.yaml
```
## 使用案例
### 在无 API 文档的情况下进行渗透测试
在授权的安全评估中,客户通常无法提供 API 文档。Vespasian 使用无头浏览器爬取目标应用程序,捕获前端发出的每一个 API 调用,并生成描述已发现端点、参数和响应 schema 的规范。
### 从现有代理捕获生成 API 规范
渗透测试人员在进行手动测试时,已经在 Burp Suite 和 mitmproxy 中捕获了流量。无需重新爬取,Vespasian 可以导入这些流量并根据已完成的工作生成规范。这对于移动应用程序测试尤为有用,因为浏览器爬取无法观察到其 API 调用。
### 映射 Web 应用程序的 API 攻击面
为了进行攻击面管理,Vespasian 通过执行 Web 应用程序的 JavaScript 并拦截所有出站请求,识别其暴露的 API 端点。生成的规范可以输入到其他接受 OpenAPI、GraphQL SDL 或 WSDL 输入的安全测试工具中。
### 传递给 Hadrian 进行授权测试
使用 Vespasian 生成 API 规范,然后将其直接传递给 [Hadrian](https://github.com/praetorian-inc/hadrian) 进行自动化的 OWASP API Top 10 授权测试。这创建了一个完整的“发现-然后-测试”工作流。
## API 类型支持
Vespasian 对三种 API 类型进行分类并生成规范:
| API 类型 | 分类信号 | 输出格式 | 探测方式 |
|----------|----------------------|---------------|---------|
| **REST** | JSON/XML content-type,`/api/` `/v1/` 路径模式,HTTP 方法 | OpenAPI 3.0 (YAML/JSON) | OPTIONS 发现,JSON schema 推断 |
| **GraphQL** | `/graphql` 路径,POST body 中的查询结构,`data`/`errors` 响应键 | GraphQL SDL | 分层内省查询(3 层以绕过 WAF) |
| **WSDL/SOAP** | SOAPAction 头,body 中的 SOAP envelope,`?wsdl` URL 参数 | WSDL XML | 主动获取 `?wsdl` 文档 |
### REST 分类启发式规则
1. **Content-type**:响应包含 `application/json` 或 `application/xml`
2. **静态资源排除**:丢弃 `.js`、`.css`、`.png`、`.woff`、`/static/`、`/assets/`
3. **路径启发式**:`/api/`、`/v1/`、`/v2/`、`/v3/`、`/rest/`、`/rpc/` 路径增加置信度
4. **HTTP 方法**:指向非页面 URL 的 POST/PUT/PATCH/DELETE 请求
5. **响应结构**:JSON 对象或数组 body(非 HTML)
### GraphQL 分类启发式规则
1. **路径匹配**:`/graphql` 路径(0.70 置信度)
2. **查询结构**:POST body 中的 GraphQL 查询语法(0.85 置信度)
3. **响应结构**:响应中的 `data`/`errors` 键(0.80 置信度)
4. **组合信号**:路径 + body 组合(0.95 置信度)
### GraphQL 内省
Vespasian 使用分层内省策略来处理受 WAF 保护的 GraphQL 服务器:
- **第 1 层**:包含描述、弃用信息和指令的完整内省
- **第 2 层**:不含描述、弃用信息或指令的最小完整查询
- **第 3 层**:负载最小的最小最后手段查询
- **回退方案**:当内省被禁用时,从观察到的查询和变更推断基于流量的 schema
## CLI 参考
### `vespasian scan`
一条命令即可爬取目标并生成规范的便捷命令。
```
vespasian scan [flags]
--api-type API type: auto, rest, graphql, wsdl (default: auto)
-H, --header Auth headers to inject (repeatable)
-o, --output Output spec file (default: stdout)
--depth Max crawl depth (default: 3)
--max-pages Max pages to visit (default: 100)
--timeout Maximum duration for the entire scan (default: 10m)
--scope same-origin or same-domain (default: same-origin)
--headless Browser mode (default: true)
--proxy Proxy URL for headless browser (e.g., http://127.0.0.1:8080)
--confidence Min classification confidence (default: 0.5)
--probe Enable active probing (default: true)
--deduplicate Deduplicate endpoints before probing (default: true)
--dangerous-allow-private Disable SSRF protection for private targets
--no-request-id Disable auto X-Vespasian-Request-Id header
-v, --verbose Show requests in real-time
```
### `vespasian crawl`
通过驱动无头浏览器遍历目标应用程序来捕获 HTTP 流量。
```
vespasian crawl [flags]
-H, --header Auth headers to inject (repeatable)
-o, --output Capture output file (default: stdout)
--depth Max crawl depth (default: 3)
--max-pages Max pages to visit (default: 100)
--timeout Maximum duration for the entire crawl (default: 10m)
--scope same-origin or same-domain (default: same-origin)
--headless Browser mode (default: true)
--proxy Proxy URL for headless browser (e.g., http://127.0.0.1:8080)
--no-request-id Disable auto X-Vespasian-Request-Id header
-v, --verbose Show requests in real-time
```
### `vespasian import`
将来自外部工具和格式的流量捕获转换为 Vespasian 捕获格式。
```
vespasian import [flags]
Formats: burp, har, mitmproxy
-o, --output Capture output file (default: stdout)
-v, --verbose Show imported requests
```
### `vespasian generate`
从捕获文件生成 API 规范。
```
vespasian generate [flags]
API types: rest, graphql, wsdl
-o, --output Output file (default: stdout)
--confidence Min classification confidence (default: 0.5)
--probe Enable active probing (default: true)
--deduplicate Deduplicate endpoints before probing (default: true)
--dangerous-allow-private Disable SSRF protection for private targets
-v, --verbose Show discovered endpoints
```
## 架构
### 流水线组件
| 组件 | 用途 | 支持类型 |
|-----------|---------|-----------------|
| **Crawler** | 驱动无头浏览器捕获 HTTP 流量,由 [Katana](https://github.com/projectdiscovery/katana) 提供支持 | 协议无关 |
| **Importers** | 将 Burp Suite XML、HAR 和 mitmproxy 流量转换为捕获格式 | 这三种格式 |
| **Classifier** | 使用启发式方法将 API 调用与静态资源分离 | REST, GraphQL, WSDL |
| **Prober** | 通过主动请求丰富端点信息 | OPTIONS, JSON schema, WSDL 获取, GraphQL 内省 |
| **Generator** | 从分类和探测后的流量生成规范文件 | OpenAPI 3.0, GraphQL SDL, WSDL |
### 包布局
```
cmd/vespasian/ CLI entry point
pkg/crawl/ Headless browser crawler + capture format
pkg/importer/ Traffic importers (Burp, HAR, mitmproxy)
pkg/classify/ API classification (REST, GraphQL, WSDL)
pkg/probe/ Endpoint probing (OPTIONS, schema, WSDL, GraphQL introspection)
pkg/generate/
├── rest/ OpenAPI 3.0 generation, path normalization, schema inference
├── graphql/ GraphQL SDL generation, introspection, traffic inference
└── wsdl/ WSDL generation, SOAP operation extraction
```
## 常见问题解答
### Vespasian 可以发现哪些类型的 API?
Vespasian 发现 **REST API**(生成 OpenAPI 3.0 规范)、**GraphQL API**(通过内省或流量推断生成 SDL schema)和 **SOAP/WSDL 服务**(生成 WSDL 文档)。它会自动从捕获的流量中检测 API 类型,或者您可以使用 `--api-type` 明确指定。
### Vespasian 与运行网络爬虫有何不同?
标准的网络爬虫跟踪 HTML 链接并索引页面。Vespasian 拦截无头浏览器的**所有 HTTP 流量**,包括 XHR/fetch API 调用、WebSocket 升级以及 HTML 中未出现的动态构建请求。然后它按 API 类型对这些请求进行分类并生成结构化规范,而不仅仅是 URL 列表。
### Vespasian 能发现未记录的 API 吗?
Vespasian 能发现应用程序在爬取过程中调用的任何 API 端点。如果前端在运行时调用 `/api/internal/debug`,Vespasian 将捕获并记录它,即使它没有出现在任何已发布的 API 文档中。
### 我可以将 Vespasian 用于已经捕获的流量吗?
可以。如果您已经使用 Burp Suite、浏览器开发工具(HAR)或 mitmproxy 捕获了流量,请使用 `vespasian import` 将其转换为捕获格式,然后使用 `vespasian generate` 生成规范。无需重新爬取。
### Vespasian 能处理禁用内省的 GraphQL 服务器吗?
可以。Vespasian 使用分层内省策略。如果完整的内省查询被阻止,它会尝试逐渐简化的查询。如果所有内省都被禁用,它会回退到从捕获流量中观察到的查询和变更推断 schema。
### 在生产环境中运行安全吗?
Vespasian 的爬取阶段驱动浏览器并跟踪链接,这是只读的。探测阶段发送 OPTIONS 请求、获取 `?wsdl` 文档并运行 GraphQL 内省查询,这些都是只读操作。但是,请始终与目标所有者协调,并在安全评估期间首选预发环境。
## 开发
### 前置条件
- [Go 1.24+](https://go.dev/dl/)
- [golangci-lint](https://golangci-lint.run/welcome/install/)
### 构建与测试
```
git clone https://github.com/praetorian-inc/vespasian.git
cd vespasian
make build # Build the binary to bin/vespasian
make test # Run tests with race detection
make lint # Run golangci-lint (gocritic, misspell, revive)
make check # Run all checks (fmt, vet, lint, test)
```
```
make coverage # Generate coverage report
make deps # Download and tidy modules
make clean # Remove build artifacts
```
## 贡献
1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/my-feature`)
3. 提交您的更改 (`git commit -am 'Add my feature'`)
4. 推送到分支 (`git push origin feature/my-feature`)
5. 打开一个 Pull Request
请在请求审查之前确保所有 CI 检查通过。
## 许可证
本项目采用 Apache License 2.0 许可。详见 [LICENSE](LICENSE) 文件。
## 关于 Praetorian
[Praetorian](https://www.praetorian.com/) 是一家网络安全公司,通过进攻性安全服务和 [Praetorian Guard](https://www.praetorian.com/guard) 攻击面管理平台帮助组织保护其最关键的资产。标签:API发现, API规范生成, BeEF, Burp Suite, C2日志可视化, Docker容器, EVTX分析, GitHub, Go语言, GraphQL, HAR文件, OpenAPI生成, REST API, Snort++, SOAP, TShark, WebSocket, Web安全, WSDL, 依赖分析, 安全测试, 对称加密, 开源安全工具, 微服务安全, 指纹识别, 攻击性安全, 攻击面发现, 攻击面映射, 日志审计, 流量捕获, 爬虫, 程序破解, 网络拓扑, 自动化审计, 蓝队分析, 被动扫描, 足迹分析, 逆向工程平台