1lkla/pentestops
GitHub: 1lkla/pentestops
PentestOps 是一个 LLM 驱动的自动化渗透测试流水线,从子域名收集到 API 验证全流程自动化,用于高效发现 Web 应用漏洞并生成证据报告。
Stars: 1 | Forks: 1
# PentestOps Agent
PentestOps 把"子域名收集 → 资产探活 → 端点聚合 → 未授权 fuzz → JS 审计 → 认证分析 → API 评分 → 未授权 API 验证"串成证据驱动的测试流水线,每阶段由可替换工具集执行,并通过统一 FindingStore、LLM Planner/Verifier/Reporter 契约和 Tool Card 机制减少误报、补齐验证证据,最终输出含 PoC + curl 复现命令的多格式渗透测试报告。
## 目录
- [核心特性](#核心特性)
- [快速开始](#快速开始)
- [项目结构](#项目结构)
- [安装](#安装)
- [运行模式](#运行模式)
- [配置体系](#配置体系)
- [阶段说明](#阶段说明)
- [输出与会话目录](#输出与会话目录)
- [扩展开发](#扩展开发)
- [Docker 部署](#docker-部署)
- [测试](#测试)
- [安全合规](#安全合规)
- [常见问题](#常见问题)
- [模块契约速查](#模块契约速查)
## 核心特性
| 类别 | 能力 |
|------|------|
| **执行模型** | 7 主阶段 + 未授权 API 验证 + 5 可选深测阶段;Phase1 串行 → Phase2 并行 → Phase3 反馈回路 → Phase4 评分/验证 → Phase5 跨阶段分析 |
| **工具发现** | 统一 `ToolRegistry`:5 种解析策略 (`path_lookup` / `absolute` / `env` / `docker` / `custom_command`);用户本地覆盖文件 `~/.config/pentestops/tools.local.yaml` |
| **置信度分级** | CONFIRMED(有 curl + 状态码 + 响应摘要 + 判定理由)/ LIKELY(强特征命中)/ UNVERIFIED(候选,不进入确认漏洞) |
| **统一发现源** | 所有阶段发现统一进入 `FindingStore`,控制台、Markdown/HTML/JSON 报告和 `findings_normalized.json` 使用同一统计口径 |
| **可恢复** | 阶段级 JSON Checkpoint 原子写入 + 校验 + `--resume` 断点续跑 |
| **可降级** | LLM 后端互为 fallback (Anthropic ↔ Ollama);工具按 `fallback_map.yaml` 失败切换;`jwt_tool` 不可用时自动降级到本地 base64 解析 |
| **安全限速** | 按 host RPS + 全局总量上限 + 并发槽位 + 抖动 + 429 自动降速 + WAF 触发停摆 |
| **范围隔离** | `ScopeGuard`:通配域名 / CIDR / URL pattern;越界目标拒绝运行 + 记录 `out_of_scope.jsonl` |
| **证据链** | 每个 CONFIRMED 都附带 curl 复现命令(凭证自动脱敏),并记录响应状态、摘要、匹配规则和验证分数 |
| **专项验证** | `stage_unauth_api` 对 `/api/*` 进行无鉴权验证,识别用户/密码/token/项目/积分等奖励平台常见敏感数据泄露 |
| **LLM 协同** | 新增 Planner / Verifier / Reporter 三段式 JSON 契约,LLM 只输出结构化意图与判定,不直接拼 shell |
| **工具知识卡** | `skills/tools/*.md` 提供按需加载的 Tool Card,避免把所有工具 `-h` 全量塞入上下文 |
| **报告格式** | Markdown / HTML / JSON 三选一;自定义模板与 `custom_fields` 注入 |
| **导入器** | Burp Suite XML、ENScan JSON、ENScan Excel |
| **知识沉淀** | `knowledge_base/`(M-EXP-01 经验库)+ `tuning/`(M-LOG-01 LLM 调用 JSONL 调优日志) |
| **提示词** | `prompts/` 中文 prompt 模板;`{{include:}}` 片段拼装;可热替换 |
## 快速开始
# 1. 安装
git clone https://github.com/1lkla/pentestops.git
cd pentestops
pip install -e .
# 2. 配置 LLM(任选其一)
export ANTHROPIC_API_KEY=sk-ant-xxx # 云端 Claude 4.7
# 或本地:
ollama serve & ollama pull glm-4.7-flash # 本地 Ollama
# 3. 工具路径(在 PATH 中已有时可跳过;否则建用户本地覆盖)
cat > ~/.config/pentestops/tools.local.yaml <<'YAML'
tools:
oneforall:
absolute_path: /opt/recon/OneForAll
httpx:
env_var: HTTPX_BIN
ffuf:
path_strategy: absolute
absolute_path: /usr/local/bin/ffuf
YAML
# 4. 预检(仅校验,不实际扫描)
python -m pentestops example.com --preflight
# 5. 运行全流水线
python -m pentestops example.com -v
# 6. 看报告
ls workspace/example.com//reports/
## 项目结构
pentestops/
├── README.md / SKILL.md / CHANGELOG.yaml / LICENSE
├── pyproject.toml ← Python 包定义;可选 extras: [test], [html]
├── requirements.txt ← 平铺依赖(便于 docker / CI)
├── Dockerfile / .dockerignore ← 多阶段构建(Go 工具 + Python runtime)
├── PentestOps_Implementation_Blueprint.md ← 2616 行架构契约(蓝图)
├── filter_alive.py ← 独立工具:从 ENScan Excel 提取域名 + httpx 探活
│
├── config/ ← 分层配置(defaults < project < profile < user-local)
│ ├── config.yaml ← project-level legacy 配置(向后兼容)
│ ├── fallback_map.yaml ← 工具失败 fallback 链
│ ├── defaults/
│ │ ├── workflow.yaml ← 工作空间、并发、超时、重试
│ │ ├── tools.yaml ← 可移植工具清单(含 path_strategy)
│ │ ├── stages.yaml ← 启用阶段 + 每阶段选项
│ │ ├── llm.yaml ← 默认后端 (Claude / Ollama)
│ │ └── safety.yaml ← RPS / 总量 / WAF / scope
│ ├── profiles/
│ │ ├── quick.yaml ← 轻量发现:S1/2/3/7,禁 LLM
│ │ ├── deep.yaml ← 全流水线 + 403 bypass
│ │ └── internal.yaml ← 内网:高 RPS,禁 WAF 停摆
│ ├── llm_backends/ ← 扩展点:新增 LLM 后端 YAML
│ │ └── vllm_example.yaml
│ ├── auth_checks/ ← OAuth2/SAML 检查骨架
│ ├── api_scoring_weights.yaml ← Stage7 评分维度(外置)
│ ├── cookie_checks.yaml ← Stage6 Cookie 检查规则
│ ├── fuzz_direction_matrix.yaml ← Stage4/7 Fuzz 方向矩阵
│ ├── js_audit_dimensions.yaml ← Stage5 P0..P3 维度
│ ├── js_audit_sink_knowledge_base.json ← Stage5 LLM 候选证据预筛 taxonomy
│ ├── js_sink_rules.yaml ← Stage5 XSS / sink / 控制源
│ ├── jwt_checks.yaml ← Stage6 JWT 基础检查
│ ├── secret_patterns.yaml ← 密钥检测正则
│ └── verification_rules.yaml ← Stage4 四步研判阈值
│
├── prompts/ ← 中文 prompt 模板({{include:}} 拼装)
│ ├── system_prompt.md ← 主 system prompt(include 三个 snippets)
│ ├── meta_rules.md ← 全局元规则(checkpoint / 三振 / 反幻觉)
│ ├── snippets/
│ │ ├── role.md ← 角色定义
│ │ ├── output_rules.md ← 输出规范 + 三级置信度
│ │ └── confidence_examples.md ← CONFIRMED / LIKELY 示例
│ ├── stage1_subdomain.md … stage7_api_scoring.md
│ └── stage_bypass_403.md, stage_tech_probes.md,
│ stage_ssrf_deep.md, stage_sqli_deep.md, stage_ssti_deep.md
│
├── src/pentestops/
│ ├── __init__.py / __main__.py ← CLI 入口(`python -m pentestops` 或 `pentestops` 命令)
│ ├── orchestrator.py ← M-ORCH-01 流水线编排
│ ├── core/ ← 基础设施
│ │ ├── config.py ← M-CORE-01 分层配置 + 统一 ToolRegistry 注入
│ │ ├── tool_runner.py ← M-CORE-02 异步子进程(超时/重试/三振/fallback)
│ │ ├── workspace.py ← M-CORE-03 session 目录、shared、checkpoints
│ │ ├── llm_client.py ← M-CORE-04 多后端 + 自动降级 + prompt caching
│ │ ├── checkpoint.py ← M-CORE-05 阶段级原子 checkpoint
│ │ ├── tool_registry.py ← ToolSpec 解析与 preflight
│ │ ├── safety_controller.py ← RPS / 并发 / 429 / WAF
│ │ ├── scope_guard.py ← 授权范围校验
│ │ └── finding_store.py ← 规范化 Finding + 指纹去重
│ ├── stages/ ← 12 个 stage(7 主 + 5 可选)
│ │ ├── base.py ← pre_check → execute → analyze → post 生命周期
│ │ ├── stage1_subdomain.py ← OneForAll + subfinder + intelliscanner
│ │ ├── stage2_httpx.py ← httpx 多端口探活 + 资产分类
│ │ ├── stage_tech_probes.py ← 技术栈→候选路径(独立 stage)
│ │ ├── stage3_endpoints.py ← gau + katana + dirsearch + feroxbuster + Burp + OpenAPI
│ │ ├── stage4_fuzz.py ← ffuf + 4 步研判 + 增量 fuzz
│ │ ├── stage5_js_audit.py ← aiohttp 下载 + sink / secret / route 提取
│ │ ├── stage6_auth.py ← Cookie / CORS / JWT
│ │ ├── stage7_api_scoring.py ← 多维评分 + LLM 增强
│ │ ├── stage_bypass_403.py ← 独立 401/403 旁路(opt-in)
│ │ ├── stage_ssrf_deep.py ← 骨架(占位)
│ │ ├── stage_sqli_deep.py ← 骨架(占位)
│ │ └── stage_ssti_deep.py ← 骨架(占位)
│ ├── analyzers/ ← 跨/单阶段分析器
│ │ ├── llm_analyzer.py ← 跨阶段关联 + 摘要 + 零发现自省
│ │ ├── bypass_403.py ← httpx 直发包路径/头部变体
│ │ ├── openapi_discovery.py ← Swagger/OpenAPI 探测与解析
│ │ ├── param_classifier.py ← 参数风险标签
│ │ ├── secret_filter.py ← 密钥识别 + 脱敏
│ │ └── tech_probes.py ← 技术栈→探测路径
│ ├── importers/
│ │ ├── burp_xml.py ← Burp Suite XML 导入
│ │ ├── enscan_importer.py ← ENScan JSON 导入
│ │ └── enscan_xlsx.py ← ENScan 多 sheet 报告生成
│ ├── experience/ ← M-EXP-01 经验库引擎
│ │ └── loader.py ← YAML 加载 + 关键词匹配
│ ├── tuning/ ← M-LOG-01 LLM 调用调优日志
│ │ └── example_logger.py ← JSONL 写入器 + 置信度提取
│ └── report/
│ └── generator.py ← M-RPT-01 Markdown/HTML/JSON + curl 脱敏
│
├── knowledge_base/ ← 经验条目(YAML,按维度组织)
│ ├── by_vuln_type/{jwt,xss,unauth_access}/
│ ├── by_framework/
│ └── by_component/
│
├── tuning/prompt_examples/ ← 调优日志 JSONL 输出目录(运行时生成)
│
├── tests/ ← pytest
│ ├── conftest.py
│ ├── test_checkpoint.py
│ ├── test_scope_guard.py
│ ├── test_secret_filter.py
│ └── test_param_classifier.py
│
├── references/optimization_review.md
└── workspace/ ← 运行时生成(每 target / 每 timestamp 一个会话目录)
## 安装
### 系统要求
- Python **≥ 3.10**
- 外部工具(按需安装;缺失的会自动 fallback / 标 unavailable):
`oneforall`、`subfinder`、`intelliscanner`、`httpx`、`gau`、`katana`、`dirsearch`、`feroxbuster`、`ffuf`、`jwt_tool`、`curl`、`bash`、可选 `docker`
### Python 依赖
`pyproject.toml` 主依赖:
pyyaml>=6.0 anthropic>=0.49.0 openpyxl>=3.1 httpx>=0.27 aiohttp>=3.9
可选 extras:
| Extras | 用途 | 命令 |
|---------|---------------------------------------------------|-----------------------------------|
| `test` | 运行 `tests/`(pytest) | `pip install -e ".[test]"` |
| `html` | 报告生成 HTML 时使用 `markdown2`(更佳渲染) | `pip install -e ".[html]"` |
### 安装步骤
git clone https://github.com/1lkla/pentestops.git
cd pentestops
pip install -e ".[test,html]"
pentestops --version # 安装成功
### 工具发现
`config/defaults/tools.yaml` 提供**可移植的工具清单**,不含任何绝对路径。`ToolRegistry` 按以下顺序解析每个工具:
1. 用户本地覆盖:`~/.config/pentestops/tools.local.yaml`
2. 环境变量(如 `HTTPX_BIN=/path/to/httpx`)
3. `absolute_path` 字段(最高优先于 `path_strategy=absolute`)
4. `path_strategy=path_lookup`:`shutil.which(binary)`
5. `path_strategy=docker`:使用系统 `docker` 二进制
6. `path_strategy=custom_command`:直接执行整条命令字符串
支持 `working_dir` 字段(保留旧式 OneForAll/dirsearch/jwt_tool 需要 `cd` 到项目目录的语义)。运行 `--preflight` 即可看到每个工具的解析结果与安装提示。
## 运行模式
# 基本运行(默认 7 阶段全跑)
python -m pentestops example.com
# 指定阶段(数字或 stage_id 均可)
python -m pentestops example.com --stages 1,2,3,4
python -m pentestops example.com --stages stage1_subdomain,stage2_httpx
# 跑可选阶段(独立 403 bypass)
python -m pentestops example.com --stages stage3_endpoints,stage_bypass_403
# 使用 profile
python -m pentestops example.com --profile quick # 轻量发现
python -m pentestops example.com --profile deep # 全量 + 403 bypass
python -m pentestops example.com --profile internal # 内网模式
# 断点续跑(指向已有 session 目录)
python -m pentestops example.com --resume workspace/example.com/20260514_120000
# 切换 LLM 后端
python -m pentestops example.com --llm-backend ollama
python -m pentestops example.com --llm-backend vllm # 需要 config/llm_backends/vllm.yaml
# 报告格式
python -m pentestops example.com --format markdown # 默认
python -m pentestops example.com --format html
python -m pentestops example.com --format json
# 联动 Burp 抓包
python -m pentestops example.com --burp-xml input.xml
# 联动 ENScan:与 target 同用 = 预导入种子;不给 target = 仅导入
python -m pentestops example.com --enscan-input enscan.json
python -m pentestops --enscan-input enscan.json --enscan-xlsx
# 授权范围
python -m pentestops example.com --scope scope.yaml
# 仅预检(不扫描,输出工具/范围 JSON 报告)
python -m pentestops example.com --preflight
# 自定义工作空间
python -m pentestops example.com --workspace /data/pentests/
# 详细日志(-v INFO;-vv DEBUG)
python -m pentestops example.com -vv
# 查看版本
pentestops --version
### 退出码
| Code | 含义 |
|------|-----------------------------------|
| `0` | 运行成功,未发现 CONFIRMED |
| `1` | 异常退出(配置/工具缺失等) |
| `2` | 成功且发现至少一个 CONFIRMED(CI 友好) |
| `130`| Ctrl-C 中断 |
## 配置体系
### 加载顺序(后者覆盖前者)
1. `config/defaults/{workflow,tools,stages,llm,safety}.yaml`
2. `config/config.yaml`(项目级;保留向后兼容)
3. `config/profiles/.yaml`(`--profile`)
4. `~/.config/pentestops/*.yaml`(用户本地)
5. 环境变量展开(`$VAR` / `${VAR}`)
6. 代码层 overrides dict(API 用)
### Profile
| Profile | 改写要点 |
|------------|--------------------------------------------------------------------------|
| `quick` | `llm.enabled=false`;只跑 `stage1/2/3/7`;端点收集仅 gau+katana |
| `deep` | 7 主阶段 + `stage_bypass_403`;`max_candidates=100` |
| `internal` | `max_rps_per_host=10`,禁 WAF 停摆;端点收集禁用 gau |
### 关键扩展点
| 文件 / 目录 | 作用 |
|--------------------------------------|---------------------------------------------------------|
| `config/llm_backends/.yaml` | 新 LLM 后端(type=openai_compatible/custom) |
| `config/jwt_checks.yaml` | JWT 基础检查规则(alg=none / no-exp / 弱算法 / 角色字段)|
| `config/cookie_checks.yaml` | Cookie 属性检查矩阵 |
| `config/auth_checks/` | OAuth2 / SAML 等扩展认证检查 |
| `config/secret_patterns.yaml` | 密钥检测正则(AWS/GitHub/Slack/Stripe/JWT...) |
| `config/js_sink_rules.yaml` | JS XSS sink + 控制源 + JSONP / prototype / postMessage |
| `config/js_audit_dimensions.yaml` | P0..P3 维度顺序与开关 |
| `config/api_scoring_weights.yaml` | Stage7 评分维度权重 |
| `config/fuzz_direction_matrix.yaml` | Stage4/7 各类型 Fuzz 方向与推荐工具 |
| `config/verification_rules.yaml` | Stage4 四步研判阈值 |
| `config/tech_probes.yaml` | 技术栈→候选路径覆盖(覆盖内置 18 个指纹) |
| `config/fallback_map.yaml` | 工具失败 fallback 链 |
| `config/profiles/.yaml` | 自定义 profile |
### 用户本地覆盖示例
# ~/.config/pentestops/tools.local.yaml
tools:
oneforall:
absolute_path: /opt/recon/OneForAll
working_dir: /opt/recon/OneForAll
ffuf:
path_strategy: absolute
absolute_path: /usr/local/bin/ffuf
jwt_tool:
working_dir: /opt/recon/jwt_tool
absolute_path: /opt/recon/jwt_tool/jwt_tool.py
wordlists:
base_path: /opt/wordlists
common_dirs: /opt/wordlists/common_dirs.txt
upload_bypass: /opt/wordlists/upload_bypass.txt
jwt_secrets: /opt/wordlists/jwt_secrets.txt
### 范围(Scope)文件示例
# scope.yaml — 通过 --scope scope.yaml 加载
allowed_domains:
- "*.example.com"
- api.example.com
denied_domains:
- staging.example.com
allowed_cidrs:
- 10.0.0.0/8
denied_url_patterns:
- /logout
max_depth: 5
notes: "Authorized by client per SOW dated 2026-05-01"
### 安全(Safety)默认值
# config/defaults/safety.yaml
rate_limiting:
max_rps_per_host: 5
max_total_requests: 50000
max_concurrent_hosts: 5
max_concurrent_per_host: 2 # B2 新增
jitter_ms: [100, 500]
behavior:
stop_on_waf: true
respect_robots: false
## 阶段说明
### 主流水线(默认启用)
| Stage ID | 工具 / 输入 | 关键输出 |
|-----------------------|--------------------------------------------|-----------------------------------------------------------|
| `stage1_subdomain` | oneforall + subfinder + intelliscanner | `all_subdomains.txt`、per-tool counts、overlap |
| `stage2_httpx` | httpx 多端口 (`80,443,8080,...`) | `live_assets.txt`、`high_value_targets.txt`、framework_dist |
| `stage_tech_probes` | 读 httpx tech-detect → tech_probes 库 | `tech_probe_candidates.txt` |
| `stage3_endpoints` | gau + katana + dirsearch + feroxbuster + OpenAPI 发现 + Burp 导入 | `all_endpoints_dict.txt` + 分类:api / admin / upload / auth / sensitive_files |
| `stage4_fuzz` | ffuf + 通配符基线 + 4 步研判 | `unauth_confirmed.md` / `unauth_suspicious.md` + scanned_endpoints |
| `stage5_js_audit` | aiohttp 下载 + sink/secret/route 提取 | `js_audit_report.md` + secrets + `js_routes_extracted.txt`(回流 Stage3) |
| `stage6_auth` | curl + jwt_tool(不可用时 base64 降级) | `auth_findings.json` + `jwt_analysis.json` |
| `stage7_api_scoring` | 多维评分(0–10)+ LLM 增强 (score ≥ 6) | `high_value_apis.md` + `fuzz_plan.json` + `attack_surface.md` |
### 执行图
Phase 1(串行) : stage1 → stage2 → stage_tech_probes → stage3
Phase 2(并行) : stage4 + stage5 + stage6 + stage_bypass_403(如启用)
Phase 3(反馈回路) : stage5 提取的路由 → stage3.append_endpoints → stage4 增量 fuzz
Phase 4 : stage7(需 Stage3 最终数据)
Phase 5(最终分析) : LLMAnalyzer 跨阶段关联 + 零发现自省 + ReportGenerator
### 可选阶段
| Stage ID | 状态 | 触发方式 |
|---------------------|----------|----------------------------------------------------|
| `stage_bypass_403` | ✅ 实现 | `--stages stage_bypass_403` 或 `profile=deep` |
| `stage_ssrf_deep` | 🟡 骨架 | 当前仅返回 `quality_warning`,等待规则填充 |
| `stage_sqli_deep` | 🟡 骨架 | 同上 |
| `stage_ssti_deep` | 🟡 骨架 | 同上 |
## 输出与会话目录
每次运行自动生成:
workspace///
├── session_meta.yaml ← target + session_id + stages_enabled + 配置快照
├── shared/ ← 跨阶段共享文件(all_subdomains.txt, all_endpoints_dict.txt)
├── logs/
│ ├── .log ← 每个工具的命令调用日志
│ ├── llm_calls.jsonl ← LLM 调用 token / 延迟 / 命中缓存
│ └── out_of_scope.jsonl ← ScopeGuard 拦截记录
├── checkpoints/
│ └── .json ← 原子写入;--resume 时读取
├── stage1_subdomain/ ← 各 stage 的产出(txt / json / md)
├── stage2_httpx/
├── stage_tech_probes/
├── stage3_endpoints/
├── stage4_fuzz/
├── stage5_js_audit/
├── stage6_auth/
├── stage7_api_scoring/
└── reports/
├── pentest_report.md|html|json ← 主报告
├── findings_normalized.json ← 规范化 Finding 列表(FindingStore)
└── report_meta.json
### 报告内容(Markdown 样例章节)
1. 元信息表(target / date / session / stage 数 / 总时长 + custom_fields)
2. **Executive Summary** — 优先用 LLM 跨阶段分析;回退为数值摘要
3. **Methodology** — 每个 stage 一行状态与耗时
4. **Findings Overview** — stages × {CONFIRMED, LIKELY, key stats} 表
5. **CONFIRMED Vulnerabilities** — 每条含 URL、severity、curl 复现(凭证脱敏)
6. **Appendix: LIKELY Vulnerabilities**(可由 `include_likely=false` 关闭)
7. **Quality Warnings** — 所有阶段告警汇总
8. **Stage Execution Details** — 含 LLM 分析摘要
9. **Tool Execution Log** — 工具/状态/耗时矩阵
10. **Appendix** — 工作空间路径 + 各 stage 文件清单
### 凭证脱敏
所有 curl 复现自动脱敏:
- `-H 'Cookie: ...'`、`-H 'Authorization: ...'`、`-H 'X-Api-Key: ...'` 等头部值 → `***REDACTED***`
- `session*=` / `token*=` / `jwt*=` / `auth*=` / `sid*=` / `csrf*=` Cookie 值 → `***REDACTED***`
- 报告中密钥使用 `AKIA...XXXX` 形式部分掩码;原始密钥仅写入本地证据文件
## 扩展开发
### 新增一个 Stage
# src/pentestops/stages/stage_custom.py
from typing import Any, Dict, List
from .base import BaseStage
class CustomStage(BaseStage):
stage_id = "stage_custom"
prompt_file = "stage_custom" # 对应 prompts/stage_custom.md
required_tools: List[str] = []
async def execute(self) -> Dict[str, Any]:
# 1. 读上游产出
targets = self.ws.read_shared_lines("all_subdomains.txt")
scoped = self.filter_in_scope(targets)
# 2. 调用工具(通过 ToolRunner)
# tool = self.config.registry.get("mytool")
# cmd = tool.command_prefix() + ["-u", url]
# await self.runner.run(tool_name="mytool", command_args=cmd, timeout_seconds=tool.timeout_seconds)
return {"findings": [], "stats": {}, "quality_warnings": []}
注册到 `stages/__init__.py`,并按需在 `orchestrator.DEPENDENCIES` / `ALL_STAGES` / `PARALLEL_GROUP` 中加入。
### 新增一个工具
只需扩展 `config/defaults/tools.yaml`:
tools:
mytool:
display_name: MyTool
category: probe
enabled: true
required_for_stages: [stage_custom]
path_strategy: path_lookup
binary: mytool
env_var: MYTOOL_BIN
version_args: [-V]
timeout_seconds: 300
fallback_tools: [httpx]
可在 `~/.config/pentestops/tools.local.yaml` 用 `absolute_path` / `working_dir` 覆盖。
### 新增 LLM 后端
# config/llm_backends/vllm.yaml
type: openai_compatible
base_url: "http://localhost:8000"
model: "Qwen/Qwen2.5-72B-Instruct"
max_tokens: 8192
context_window: 128000
auth:
type: none
然后用 `--llm-backend vllm` 切换;或在 `defaults/llm.yaml` 改 `default_backend`。
### Prompt 片段化
`prompts/system_prompt.md` 通过 `{{include:snippets/role.md}}` 等指令拼装;自定义片段直接放进 `prompts/snippets/`。
### 经验库条目(M-EXP-01)
# knowledge_base/by_vuln_type/jwt/jwt_alg_none.yaml
id: KB-JWT-001
title: "JWT alg=none 强制接受"
detection_pattern: '"alg":"none"'
verification_steps:
- 用 `python -c "import base64, json; ..." 替换 header 与 signature`
- 重放至受保护端点观察是否 200
remediation: "服务端禁用 'none' 算法;白名单校验 alg 字段"
tags: [jwt, auth, critical]
`ExperienceLoader` 会自动加载所有 `knowledge_base/by_*/.yaml` 并在 LLM 调用时按关键词匹配注入。
## Docker 部署
# 构建(多阶段:Go 工具层 + Python runtime)
docker build -t pentestops:0.4.0 .
# 运行预检
docker run --rm pentestops:0.4.0 example.com --preflight
# 完整运行(挂载 workspace 与 LLM key)
docker run --rm \
-e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
-v $PWD/workspace:/app/workspace \
-v $PWD/scope.yaml:/app/scope.yaml \
pentestops:0.4.0 example.com --scope /app/scope.yaml -v
`Dockerfile` 已预装 `httpx / ffuf / subfinder / katana / gau` Go 二进制。如需 `oneforall / intelliscanner / dirsearch / jwt_tool`(Python 项目),自行扩展并通过 `tools.local.yaml` 指定 `working_dir`。
## 测试
pip install -e ".[test]"
pytest tests/ -v
# 当前覆盖:
# - tests/test_checkpoint.py 4 cases (save/restore/corrupted)
# - tests/test_scope_guard.py 4 cases (domain/CIDR/wildcard/url)
# - tests/test_secret_filter.py 13 cases (AWS/GitHub/JWT/generic API key)
# - tests/test_param_classifier.py 14 cases (url_redirect/file_path/idor/cmd...)
## 安全合规
- **授权**:运行入口由 `ScopeGuard.assert_in_scope(target)` 强制校验。越界目标会被拒绝并写入 `logs/out_of_scope.jsonl`。
- **限速**:`SafetyController` 默认 `5 RPS/host`、`2 并发槽位/host`、全局 `50000 请求上限`。命中 429 自动降速;命中 WAF 静默停摆该 host。
- **隐私**:API Key 仅从环境变量读取,不落盘;密钥在送 LLM / 写报告前由 `SecretFilter` 部分掩码。
- **目标合法性**:CLI 在运行前拒绝含 shell 元字符 (`;&|` 等)、空白、路径分隔符的 target。
- **凭证脱敏**:报告中所有 curl 命令的敏感头部与 Cookie 值脱敏;原始凭证仅留 `logs/.log`。
## 常见问题
**Q: 缺少某个工具会怎样?**
A: 不会中断。`ToolRegistry` 在 preflight 中标 `available=false`,提示 `install_hint`;执行时若该工具是关键依赖会触发 fallback(参考 `fallback_map.yaml`),全部失败则该 stage 的 `quality_warnings` 列出失败原因。
**Q: 没有 `ANTHROPIC_API_KEY` 能跑吗?**
A: 可以。`LLMClient` 初始化失败会被吞掉并 `logger.warn`,所有 stage 的 `analyze()` 步骤自动跳过;仅缺失"研判文本",工具产出与最终报告仍能生成。可改用 Ollama 或 vLLM 本地后端。
**Q: 怎么把 Burp 的抓包数据接进流水线?**
A: `--burp-xml /path/to/burp.xml`。`BurpXMLImporter` 会抽取所有 URL(→ Stage3 端点字典)、JWT/Bearer(→ Stage6)、JS URL(→ Stage5),并把概览写入 `stage3_endpoints/burp_import_summary.json`。
**Q: 怎么断点续跑?**
A: 找到已有的 session 目录(`workspace///`),用 `--resume `。Orchestrator 会读取 `checkpoints/*.json`,跳过所有 `stage_status=completed` 的阶段,从最近的 next_stage 继续。
**Q: 怎么屏蔽某个 stage?**
A: `--stages stage1_subdomain,stage2_httpx,stage3_endpoints` 显式列出要跑的;或写一个 profile 在 `stages.enabled` 中删除不需要的。
**Q: 怎么改报告默认格式?**
A: CLI `--format html` / `--format json`;或在 `config/defaults/llm.yaml` 同级新增 `report.output_format` 字段(`report` 段被自动解析)。
**Q: 哪些深度阶段还没实现?**
A: `stage_ssrf_deep` / `stage_sqli_deep` / `stage_ssti_deep` 当前是骨架(占位 `quality_warning`),用于未来扩展。
## 模块契约速查
| 模块 ID | 文件 | 输出主键 |
|------------|-------------------------------|-------------------------------------------------------------------------------------------------------|
| M-CORE-01 | `core/config.py` | `AppConfig.{llm, workflow, report, registry, tools, stages_enabled, safety}` |
| M-CORE-02 | `core/tool_runner.py` | `ToolResult{success, exit_code, stdout, stderr, output_file_path, duration, retry_count, fallback_used}` |
| M-CORE-03 | `core/workspace.py` | `session_path` + `stage_dir(...)` + `save_*/read_*/append_*` + `summary()` |
| M-CORE-04 | `core/llm_client.py` | `LLMResult{content, backend_used, tokens_in/out, latency, cache_hit, cache_creation/read_input_tokens}` |
| M-CORE-05 | `core/checkpoint.py` | `RestoreResult{last_completed_stage, next_stage, completed_stages_data, is_fresh_start}` |
| M-STG-01..07 | `stages/stage*.py` | `StageResult{outputs, tool_results, analysis, quality_warnings, summary}` |
| M-ORCH-01 | `orchestrator.py` | `{session_path, stages_executed, total_duration_seconds, findings_summary, report_path}` |
| M-RPT-01 | `report/generator.py` | `{report_file, report_format, stats:{total_confirmed, total_likely, severity_distribution, stages_coverage}}` |
| M-EXP-01 | `experience/loader.py` | `ExperienceEntry{id, title, detection_pattern, verification_steps, remediation, tags, category}` |
| M-LOG-01 | `tuning/example_logger.py` | `TuningEntry{prompt_hash, stage, latency, tokens, confidence_returned, was_correct?}` |
详细输入/输出/行为/扩展点契约参见 `PentestOps_Implementation_Blueprint.md`(蓝图文档,2616 行)。
## 版本与许可证
- 版本:`0.4.0`(统一于 `src/pentestops/__init__.py:__version__`)
- 变更记录:`CHANGELOG.yaml`(截止 `CHG-2026-030`)
- 仅用于授权范围内的安全测试。
标签:AI风险缓解, API安全, API评分, C2, JSON输出, JS审计, LLM Planner, LLM Reporter, LLM Verifier, LLM驱动, PoC复现命令, Tool Card机制, Web安全, 可替换工具集, 多格式报告, 子域名收集, 安全合规, 工具注册表, 断点续跑, 未授权API验证, 未授权fuzz, 测试流水线, 渗透测试报告, 端点聚合, 统一FindingStore, 网络代理, 网络安全自动化, 置信度分级, 置信度确认, 自动化渗透测试, 蓝队分析, 认证分析, 证据驱动, 误报减少, 请求拦截, 资产探活, 运行时操纵, 逆向工具