
### 永远警惕的守护者 — 洞察一切的动态安全
**一款云原生、多目标 DAST 编排器,配备关联大脑。**
Yubel 运行最优秀的开源动态安全引擎 — ZAP, Nuclei, Nikto, Wapiti, testssl.sh, sqlmap, dalfox, katana, schemathesis, graphql-cop, kube-hunter — 针对 **Web 应用、REST/GraphQL API、云资产、容器和 Kubernetes**,然后执行单一扫描器无法做到的操作:将其输出**关联**为经过印证的发现,并**合成多步骤攻击链**。支持通过安装 (`pip`)、在 Docker 中、作为 Kubernetes Job/CronJob 或在 CI 中运行。
[](https://github.com/ggeorgeazevedo/yubel/actions/workflows/ci.yml)
[](https://github.com/ggeorgeazevedo/yubel/actions/workflows/codeql.yml)
[](LICENSE)
[](https://github.com/ggeorgeazevedo/yubel/releases)
[](https://pypi.org/project/yubel/)
[](pyproject.toml)
[](https://github.com/ggeorgeazevedo/yubel/pkgs/container/yubel)
[](https://github.com/ggeorgeazevedo/yubel/stargazers)
[](#-air-gapped-by-design)
Web · REST/GraphQL API · 云 · 容器 · Kubernetes | 共识 · 攻击链 · 系统性关联 · 基准差异比对 · OWASP/CWE/MITRE
## 为什么选择 Yubel
没有任何单一扫描器能在所有方面都做到最好。ZAP 擅长深度的认证 Web 爬取;Nuclei 在模板检查和快速模糊测试方面无可匹敌;testssl.sh 主导 TLS 领域;kube-hunter 是对集群进行动态渗透测试的最佳方式;schemathesis 则能撕裂 OpenAPI 契约。真正的安全程序已经在运行其中的几个工具——但它们被糟糕地用定制脚本粘合在一起,报告互不兼容,且没有共享的严重性模型。
**Yubel 就是做得恰到好处的“粘合剂”:**
- **一套配置,多个引擎。** 只需描述一次你的目标;Yubel 就会将每个目标路由到每个能够处理它的引擎。
- **统一的标准化模型。** 每个引擎的输出都会成为共享 5 级严重性量表上的 `Finding`,然后跨引擎的重复项会被合并(并标注来源)。
- **一套报告。** 同一次运行可生成 JSON、自包含的 HTML 仪表板、Markdown,以及用于 GitHub 代码扫描的 **SARIF** 报告。
- **随处运行。** 笔记本电脑、Docker、Kubernetes Job/CronJob,或带有真正拦截机制的 CI pipeline。
- **诚实且具有韧性。** 缺少某个引擎会被跳过,而不是致命错误。一个引擎崩溃绝不会扼杀整个扫描。每一次执行都会被记录下来。
Yubel **不会**重新发明扫描——它站在 [`docs/LANDSCAPE.md`](docs/LANDSCAPE.md) 中编目的 OSS 生态系统的肩膀上(调查了 382 个工具)。
## Yubel 的与众不同之处
大多数工具仅止步于“运行扫描器,打印发现”。由于 Yubel 能同时看到**目标的所有引擎输出**,它增加了一个单一扫描器在结构上无法做到的分析层:
- **跨引擎共识。** 由两个或更多引擎独立报告的发现会被标记为*已印证* (corroborated),并提升其置信度——通过使用引擎作为陪审团,**确定性地**减少误报(无需概率性的 LLM 验证器)。重复项会合并,保留最严重的等级并标注所有报告引擎。
- **攻击链合成。** Yubel 能识别出何时孤立的发现组合成了真实的利用路径,并将其提升为高影响力的独立发现——目前有 13 条规则,例如 *SSRF + 云主机 → IMDS 凭据窃取*、*XSS + 非 HttpOnly cookie → 账户接管*、*匿名 K8s API + 暴露的 kubelet → 集群接管*、*JWT alg=none + admin → 绕过认证*、*请求走私 + 缓存中毒*。没有任何单一的扫描器能报告这些。
- **跨目标的系统性关联。** 当相同的弱点类别出现在两个或更多目标上时,Yubel 会提出一个单一的*系统性*发现——“集中修复,全面解决”。一次只能看到一个应用的工具在结构上是无法做到这一点的。
- **“我们为何相信这一点”的证据链。** 每个发现都带有确定性的、可重现的推论依据(哪些引擎、印证情况、分类法、风险)——提供可审计的推理过程,而不是模型的猜测。
- **基准差异比对。** 将 `--baseline` 指向之前的一次运行,每个发现都会被打上 **新增 / 现有 / 退化** 的标签,并且 **已修复** 的问题会被单独跟踪。`--fail-on-new` 仅针对*新引入*的风险对 CI 进行拦截,因此积压的漏洞绝不会阻塞 pipeline。
- **分类法与风险评分。** 每个发现都会映射到 **OWASP Top 10 (2021)、OWASP API Top 10 (2023)、CWE 和 MITRE ATT&CK**,获得综合的 **0–100 风险评分**,并汇总为每个目标的 **A–F 评级**和 OWASP 覆盖矩阵。
- **噪音聚类。** 200 个“缺少 header”的命中结果会折叠成一个带有实例计数的发现,这样真正的问题就不会被淹没。
Yubel 是**指挥家,而不是另一种乐器**——它甚至可以将 AI 代理扫描器编排为又一个引擎,同时其自身的核心保持确定性和离线状态。查看渲染的报告:[`docs/sample-report.html`](docs/sample-report.html)。
## 快速开始
```
pip install yubel # core (orchestrator + reporters + analysis)
yubel setup # detect & install the scanning engines (one command)
yubel setup --install # actually install the missing ones (brew/pip)
yubel engines # see what's registered and available here
yubel selftest # synthetic run — validates the pipeline, no network
yubel scan -t https://example.com --fail-on high -o report/
```
不想安装任何东西?下面的 Docker 镜像捆绑了所有引擎。
倾向于将所有内容打包在一起?Docker 镜像附带了编排器**以及**引擎:
```
docker run --rm -v "$PWD/out:/out" ghcr.io/ggeorgeazevedo/yubel:latest \
scan -t https://example.com -o /out
open out/yubel.html
```
## 它能理解的目标
| 类型 | 示例 | 路由到的引擎 |
|---|---|---|
| `web` | 应用、门户、仪表板、SPA | zap, nuclei, wapiti, nikto, dalfox, testssl, katana, httpx |
| `api` | REST + OpenAPI/Swagger | zap (api-scan), nuclei, schemathesis, wapiti, testssl |
| `graphql` | GraphQL endpoint | graphw00f, graphql-cop, zap, schemathesis |
| `cloud` | 外部/攻击面资产 | httpx, katana, nuclei, testssl |
| `kubernetes` | 集群(远程/内部/pod) | kube-hunter, nuclei (通过 ingress) |
| `container` / `host` | 暴露的服务 | httpx, nuclei, nikto, testssl |
## 真实的配置
```
yubel init # writes a documented yubel.yaml
yubel scan -c yubel.yaml -o report/
```
```
parallelism: 4
fail_on: high # CI gate: exit non-zero if any finding >= high
targets:
- { name: shop, type: web, url: https://shop.example.com,
auth: { kind: bearer, token: ${SHOP_TOKEN} } }
- { name: payments, type: api, url: https://api.example.com,
openapi: https://api.example.com/openapi.json }
- { name: graph, type: graphql, url: https://api.example.com/graphql }
- { name: prod-cluster, type: kubernetes, host: 10.0.0.10, k8s_mode: remote }
output: { dir: report, formats: [json, html, markdown], sarif: true }
```
通过 `${ENV_VAR}` 扩展,密钥可以安全地远离 git。
## 部署
Kubernetes (Job / CronJob)
```
kubectl apply -f deploy/k8s/configmap.yaml
kubectl apply -f deploy/k8s/job.yaml
kubectl logs -f job/yubel-scan
```
或者使用 Helm(支持 `mode: job|cronjob`,以非 root 用户运行,只读 rootfs):
```
helm install yubel deploy/helm/yubel \
--set mode=cronjob --set schedule="0 2 * * *"
```
要进行**内部集群渗透测试**,可以在集群内以 `k8s_mode: pod` 运行该 Job —— 随后 kube-hunter 会从 pod 网络内部探测控制平面和 kubelet,就像一个被入侵的 workload 一样。
GitHub Actions(带 SARIF 上传)
```
- uses: ggeorgeazevedo/yubel@v0
with:
target: https://staging.example.com
fail-on: high
- uses: github/codeql-action/upload-sarif@v3
if: always()
with: { sarif_file: yubel-report/yubel.sarif }
```
现成的工作流位于 [`.github/workflows/dast.yml`](.github/workflows/dast.yml)。
## 基准 / 趋势扫描
```
yubel scan -c yubel.yaml -o report/ # run 1
cp report/yubel.json baseline.json
# ...稍后,在 CI 中...
yubel scan -c yubel.yaml --baseline baseline.json \
--fail-on critical --fail-on-new -o report/ # fails only on NEW criticals
```
## 报告
- **`yubel.html`** — 具有编辑性质、自包含的评估报告:包含带有 **A–F 风险评级**的执行摘要、**攻击路径**部分、**OWASP Top 10 覆盖矩阵**,以及带有印证情况和分类法标签的风险评分发现。支持离线工作、明暗主题切换,且易于打印。
- **`yubel.sarif`** — SARIF 2.1.0(包含来自风险评分的 `security-severity` + OWASP/MITRE 标签)→ GitHub *Security → Code scanning*。
- **`yubel.json`** — 完整的机器可读结果:发现、丰富信息、各引擎运行日志以及基准差异比对。
- **`yubel.md`** — 用于 PR/Ticket 的 Markdown 摘要(执行摘要、攻击路径、OWASP 覆盖率、发现)。
## Pipeline
```
target ─▶ registry.select_for(target) ─▶ [engines for this type, minus deny-list,
minus intrusive/opt-in]
─▶ ThreadPool (bounded by parallelism)
─▶ each engine: build_command → run in temp workdir → parse → [Finding]
─▶ collect ─▶ dedupe (merge cross-engine dups, keep worst severity)
─▶ ANALYSIS ── taxonomy (OWASP/CWE/MITRE) + risk score
├─ consensus (corroboration → confidence uplift)
├─ cluster noise (info/low repetition → 1 finding)
├─ attack-chain synthesis (composite findings)
└─ baseline diff (new / existing / regressed / fixed)
─▶ reporters (json/html/md/sarif) ─▶ fail-gate exit code
```
侵入式引擎(目前是 **sqlmap**)**默认关闭**,只有在你传递 `--include-intrusive` 或使用 `-e sqlmap` 明确指定它们时才会运行。
## 添加引擎
1. 在 `src/yubel/engines/` 中继承 `Engine` 子类,声明 `name`、`supports`、`binary`。
2. 实现 `build_command()` 和 `parse()`(返回标准化的 `Finding`)。
3. 在 `engines/registry.py` 中注册它。
就是这样——可用性探测、目标路由、CLI 列表、并行处理和报告功能都是免费自带的。请参阅 `engines/nuclei.py` 作为精简参考,以及 [CONTRIBUTING.md](CONTRIBUTING.md)。
## 发布(徽章如何变绿)
只要代码库在 GitHub 上,徽章就会自动亮起:
- **CI / CodeQL** — 在每次推送/PR 时运行(首次成功运行后即变绿)。
- **License / Stars** — 只要代码库公开就会显示。
- **Release / PyPI / Docker** — 在你发布版本时显示:
```
git tag v0.3.0 && git push origin v0.3.0
```
该 tag 会触发 `release.yml`(构建 wheel,通过 Trusted Publishing 发布到 **PyPI**,并创建 **GitHub Release**)和 `docker.yml`(将镜像推送到 **ghcr.io**)。一次性设置:在 PyPI 上为此代码库添加一个 *Trusted Publisher*(Project → Publishing → GitHub)——无需 API token。你的代码库的 **Community Standards** 检查清单(Insights → Community Standards)已达到 100%:README, LICENSE, CODE_OF_CONDUCT, CONTRIBUTING, SECURITY, Issue 模板和 PR 模板均已齐备。
## 架构
完整设计请参阅 [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md),调查的生态系统请参阅 [`docs/LANDSCAPE.md`](docs/LANDSCAPE.md)。
## ⚠️ 法律与合规使用
DAST 是一种主动测试:它会发送真实的攻击流量。**仅扫描你拥有或被明确授权测试的系统。** 侵入式引擎可能会修改数据。你对 Yubel 的使用自行负责。请参阅 [SECURITY.md](SECURITY.md)。
## 许可证
[Apache-2.0](LICENSE)。Yubel 编排的第三方引擎带有其**各自的**许可证(GPL, Apache, MIT, 专有等)——安装或捆绑它们是你自己的责任;请参阅 [`docs/LANDSCAPE.md`](docs/LANDSCAPE.md) 了解每个工具的许可证。