ZappaBoy/vuln-scanner

GitHub: ZappaBoy/vuln-scanner

一个自动化漏洞评估平台,编排 86 个开源安全工具进行并行扫描,并借助可选的 LLM 分析层生成去重结果、PoC 脚本及多格式专业报告。

Stars: 10 | Forks: 0

# 漏洞扫描器 一个自动化漏洞评估平台,它编排 **86 个开源安全工具**,聚合并去重扫描结果,运行可选的 **OpenAI 兼容 LLM 分析层** 用于分类、聚类和修复,生成 **概念验证脚本**,并生成专业的 **Markdown、HTML 和 JSON 报告** —— 所有这些都来自单个 BlackArch Linux Docker 镜像。 ## 目录 1. [架构](#architecture) 2. [工具](#tools) 3. [目标类型门控](#target-type-gating) 4. [扫描模式](#scan-modes) 5. [认证扫描](#authenticated-scanning) 6. [LLM 分析](#llm-analysis) 7. [PoC 生成与执行](#poc-generation-and-execution) 8. [插件系统](#plugin-system) 9. [报告格式](#report-formats) 10. [快速开始](#quick-start) 11. [配置](#configuration) 12. [环境变量](#environment-variables) 13. [项目结构](#project-structure) 14. [添加新工具](#adding-a-new-tool) 15. [开发](#development) 16. [DefectDojo 集成](#defectdojo-integration) ## 架构 ``` config.toml / env vars / CLI args ↓ AppConfig (pydantic, 3-layer merge: TOML < env < CLI) ↓ Plugin loader — auto-discovers ./plugins/ + ~/.vuln-scanner/plugins/ ↓ ScanOrchestrator • classify_target() → TargetType • tool.applies_to(target) — skips mismatched pairs • asyncio + ThreadPoolExecutor — parallel (tool × target) tasks • AuthConfig forwarded to every applicable tool ↓ ScanResult[] → Assessment ↓ LLMAnalyzer (optional) • Pass 1: triage + PoC design (threaded, per result) • Pass 2: PoC generation (PocGenerator, host-safe) • Pass 3: mitigation (evidence-informed) • Pass 4: clustering + exec summary ↓ PocRunner (container-only, VS_IN_CONTAINER=1 guard) ↓ ┌────────┬────────┬────────┐ │ .md │ .html │ .json │ (all formats written in parallel) └────────┴────────┴────────┘ ↓ DefectDojo (optional) ``` 所有扫描工具和 PoC 执行都在 **BlackArch Linux** Docker 容器内运行 —— 不会在宿主机上安装任何东西。 ## 工具 86 个按类别组织的工具。每个工具都声明了它支持的目标类型;编排器会自动跳过不兼容的匹配。 ### 网络与端口扫描 | 工具 | 备注 | |------|-------| | `nmap` | 带有服务/版本检测的全端口扫描 | | `rustscan` | 快速端口扫描器,结果输入至 nmap | | `masscan` | 高速 TCP/UDP 扫描器 | | `naabu` | 带有服务检测的端口扫描器 | | `netdiscover` | 基于 ARP 的主机发现 | ### Web 应用程序 | 工具 | 备注 | |------|-------| | `nuclei` | 基于模板的漏洞扫描器 | | `nikto` | Web 服务器配置错误扫描器 | | `wapiti` | 黑盒 Web 漏洞扫描器 | | `ffuf` | 快速 Web 模糊测试工具 (目录、参数、标头) | | `feroxbuster` | 递归内容发现工具 | | `gobuster` | URI/DNS/vhost 暴力破解工具 | | `wfuzz` | Web 应用程序模糊测试工具 | | `dalfox` | 带有参数分析的 XSS 扫描器 | | `xsstrike` | 高级 XSS 检测引擎 | | `commix` | 命令注入利用工具 | | `sqlmap` | 自动化 SQL 注入和接管工具 | | `nosqlmap` | NoSQL 注入扫描器 | | `httpx` | HTTP 探测与指纹识别 | | `whatweb` | Web 技术指纹识别工具 | | `wafw00f` | WAF 检测和指纹识别 | | `wpscan` | WordPress 漏洞扫描器 | | `acunetix` | Web 漏洞扫描器 (基于 API) | | `arachni` | Web 应用程序安全扫描器 | | `zap` | OWASP ZAP DAST 扫描器 | | `wapiti` | 黑盒漏洞扫描器 | | `drheader` | HTTP 安全标头分析器 | | `humble` | HTTP 标头安全检查器 | | `hakrawler` | 用于 URL 和 endpoint 的快速 Web 爬虫 | | `katana` | 下一代 Web 爬虫框架 | | `gau` | 已知 URL 收集器 (AlienVault, WaybackMachine) | | `jsluice` | JavaScript 密钥和 URL 提取器 | | `corscanner` | CORS 配置错误扫描器 | | `crlfuzz` | CRLF 注入扫描器 | | `smuggler` | HTTP 请求走私检测器 | | `linkfinder` | JavaScript/HTML 源码中的 endpoint 发现 | | `cariddi` | 带有密钥和 endpoint 检测的 Web 爬虫 | ### API & GraphQL | 工具 | 备注 | |------|-------| | `kiterunner` | 使用 kite 文件的 API 路由发现 | | `graphql_cop` | GraphQL 安全审计工具 | | `restler` | 有状态 REST API 模糊测试工具 | | `apifuzzer` | 基于 OpenAPI/Swagger 的模糊测试工具 | | `cherrybomb` | OpenAPI 规范安全 linter | | `arjun` | HTTP 参数发现工具 | | `paramspider` | 从 wayback/来源挖掘参数 | ### DNS 与侦察 | 工具 | 备注 | |------|-------| | `amass` | 子域名枚举 (被动 + 主动) | | `subfinder` | 快速被动子域名枚举 | | `dnsx` | DNS 解析器和探测工具包 | | `dnsrecon` | DNS 枚举和区域传输 | | `fierce` | DNS 侦察和主机发现 | | `theharvester` | OSINT: 电子邮件、姓名、主机、子域名 | | `puredns` | 带有通配符过滤的快速子域名暴力破解工具 | | `alterx` | 子域名排列引擎 | | `waybackurls` | 从 Wayback Machine 获取历史 URL | | `httprobe` | 存活的 HTTP/HTTPS 主机探测器 | ### TLS / SSL | 工具 | 备注 | |------|-------| | `testssl` | TLS 配置和密码套件审计 | | `sslyze` | TLS 扫描器 (密码套件, Heartbleed, ROBOT) | | `sslscan` | SSL/TLS 服务扫描器 | | `tlsx` | 快速 TLS 探测 | | `tls_attacker` | TLS 协议攻击工具 | | `ssh_audit` | SSH 配置和算法审计工具 | ### SMB 与网络服务 | 工具 | 备注 | |------|-------| | `smbmap` | SMB 共享枚举和权限 | | `enum4linux` | SMB/NetBIOS 枚举 | | `crackmapexec` | Active Directory 和 SMB 评估 | | `openvas` | OpenVAS 漏洞扫描器 | ### SAST 与代码分析 | 工具 | 备注 | |------|-------| | `bandit` | Python SAST — 常见的安全反模式 | | `semgrep` | 带有社区规则的多语言 SAST | | `gosec` | Go 安全检查器 | | `bearer` | 带有隐私和安全规则的数据流 SAST | | `horusec` | 多语言 SAST 引擎 | | `brakeman` | Ruby on Rails SAST 扫描器 | | `flawfinder` | 针对 C/C++ 常见缺陷的静态分析 | | `dependency_check` | OWASP 依赖项漏洞扫描器 | | `pip_audit` | Python 包漏洞检查器 | ### 软件组合分析 (SCA) | 工具 | 备注 | |------|-------| | `osv-scanner` | 开源漏洞数据库扫描器 | | `npm-audit` | Node.js 包漏洞审计 | | `govulncheck` | Go 模块漏洞检查器 | ### 密钥检测 | 工具 | 备注 | |------|-------| | `gitleaks` | Git 历史密钥扫描器 | | `trufflehog` | 基于深度信息熵的密钥查找器 | | `secretfinder` | JS 文件和 endpoint 中的密钥 | | `detect-secrets` | 基于基准线的密钥扫描器 | | `noseyparker` | 带有模式规则的高速密钥扫描器 | ### IaC 与配置 | 工具 | 备注 | |------|-------| | `checkov` | Terraform/K8s/Dockerfile IaC 扫描器 | | `tfsec` | Terraform 静态分析 | | `terrascan` | 多云 IaC 安全扫描器 | | `hadolint` | Dockerfile 最佳实践 linter | ### 云基础设施 | 工具 | 备注 | |------|-------| | `prowler` | AWS/GCP/Azure 安全态势评估 | | `kube-bench` | CIS Kubernetes 基准检查器 | ### 容器与供应链 | 工具 | 备注 | |------|-------| | `trivy` | 容器镜像 + 文件系统漏洞扫描器 | | `grype` | 容器和包漏洞匹配器 | ## 目标类型门控 编排器将每个目标分类为一个或多个类型,并且仅运行声明支持该类型的工具。这消除了例如针对 Web URL 运行 SMB 工具而产生的噪音。 | 类型 | 示例 | 匹配的工具 | |------|---------|-----------------| | `HOST` | `example.com` | DNS、SSL、Web、SMB 工具 | | `IP` | `10.0.0.1` | 网络、端口、SMB 工具 | | `CIDR` | `10.0.0.0/24` | 网络扫描器 | | `URL` | `https://app.example.com` | Web、API、SSL 工具 | | `PATH` | `/src/myapp` | SAST、SCA、密钥、IaC 工具 | | `REPO` | `https://github.com/org/repo` | 密钥、SAST、SCA 工具 | | `IMAGE` | `myapp:latest` | 容器扫描器 | | `CLOUD` | `aws:profile=prod`, `arn:aws:…` | 云态势工具 (prowler, kube-bench, terrascan) | 分类是自动的 —— 只需传入目标字符串;扫描器会自行识别类型。 可识别的云目标格式: - AWS ARN: `arn:aws:iam::123456789012:root` - 命名配置文件简写: `aws:profile=production` - GCP project: `projects/my-project-id` - Azure subscription UUID: `00000000-0000-0000-0000-000000000000` ## 扫描模式 | 模式 | 描述 | |------|-------------| | `paranoid` | 最高隐蔽性 —— 被动探测,最小足迹 | | `passive` | 无主动攻击 —— 仅枚举和抓取 Banner **(默认)** | | `active` | 启用标准漏洞检查 | | `aggressive` | 全面扫描:所有模板,暴力破解,快速计时 | ## 认证扫描 凭据将被转发到所有适用的 Web 工具 (nuclei, ffuf, feroxbuster, gobuster, nikto, sqlmap, dalfox, wpscan, wapiti, katana, hakrawler, arjun, wfuzz, corscanner, kiterunner, httpx)。 ### 全局凭据 除非存在针对目标的覆盖配置,否则将应用于每个目标。 **通过配置:** ``` [scan.auth] bearer_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." username = "admin" password = "secret" [scan.auth.cookies] session = "abc123" [scan.auth.headers] X-API-Key = "my-api-key" ``` **通过环境变量** (仅限全局): ``` VS_AUTH_BEARER_TOKEN=eyJ... VS_AUTH_USERNAME=admin VS_AUTH_PASSWORD=secret ``` **通过 CLI** (仅限全局): ``` vuln-scanner --targets https://app.example.com \ --auth-bearer eyJ... \ --auth-cookie session=abc123 \ --auth-header X-API-Key=secret ``` ### 针对目标的凭据 当扫描多个需要不同凭据的目标时,请在 `[scan.auth.targets.""]` 下定义针对目标的覆盖配置。匹配的条目会完全**替换**该目标的全局配置 —— 不会进行合并。针对目标的认证仅限配置文件 (环境变量和 CLI 标志只能设置全局默认值)。 ``` [scan.auth] # 全局 fallback — 用于任何没有特定条目的 target bearer_token = "default-token" # 主应用的 JWT [scan.auth.targets."https://app.example.com"] bearer_token = "app-specific-jwt" # admin panel 的 Cookie session [scan.auth.targets."https://admin.example.com"] [scan.auth.targets."https://admin.example.com".cookies] session = "s%3Aabc123" csrftoken = "xyz789" # 内部 API 的 HTTP Basic [scan.auth.targets."10.0.0.50"] username = "apiuser" password = "s3cret" # 传统应用的表单登录 [scan.auth.targets."https://legacy.example.com"] login_url = "https://legacy.example.com/login" username = "admin" password = "password123" [scan.auth.targets."https://legacy.example.com".login_data] _token = "csrf-value-here" ``` **解析优先级:** `针对目标的配置 > 全局配置` ## LLM 分析 当存在 API key 时,LLM 层会自动激活。它会对扫描结果执行四遍处理: | 步骤 | 名称 | 功能描述 | |------|------|-------------| | 1 | **分类** | 为每个发现分配 CWE、置信度、误报标志、可利用性摘要,并设计 PoC | | 2 | **PoC 生成** | 编写自包含的 Python/Bash 脚本,使用容器中已有的工具确认发现 | | 3 | **缓解** | 提供具体的短期缓解措施和永久性修复方案,可选地参考 PoC 证据 | | 4 | **聚类** | 按根本原因对发现进行分组,编写共享的修复方案,并生成执行摘要 | ### 提供商配置 LLM 客户端兼容 OpenAI-API —— 适用于 OpenAI、Azure OpenAI、Ollama、vLLM、LM Studio、OpenRouter 以及任何其他兼容的 endpoint。 ``` [llm] enabled = "auto" # "auto" | true | false (auto = on when api_key present) api_key = "" # or set OPENAI_API_KEY env var base_url = "" # leave empty for OpenAI; set for Ollama/vLLM/etc. model = "gpt-4o" # REQUIRED when LLM is active — no default # 采样参数(所有 OpenAI 兼容) temperature = 0.2 top_p = 0.95 max_tokens = 4096 # top_k 和其他非标准参数放在 extra_body 中: # [llm.extra_body] # top_k = 40 ``` **Ollama 示例:** ``` [llm] base_url = "http://localhost:11434/v1" api_key = "ollama" model = "llama3.2" ``` **vLLM 例:** ``` [llm] base_url = "http://localhost:8000/v1" api_key = "token-abc123" model = "meta-llama/Meta-Llama-3-8B-Instruct" ``` ### 功能矩阵 每个 LLM 功能都是一个命名的特性,支持全局切换,并可按工具或按类别进行覆盖。 | 功能 | 默认 | 描述 | |---------|:-------:|-------------| | `logs_analysis` | 开启 | 将工具的原始输出提供给 LLM | | `enrich` | 开启 | CWE / 置信度 / 误报 / 可利用性分类 | | `classify` | 开启 | 对发现的类型和风险进行分类 | | `cluster` | 开启 | 按根本原因对发现进行分组 | | `mitigation` | 开启 | 生成缓解和修复方案 | | `generate_poc` | 开启 | 将 PoC 脚本作为报告资产写入 | | `execute_poc` | **关闭** | 在容器内运行 PoC *(需要 `VS_IN_CONTAINER=1`)* | | `false_positive_filter` | 开启 | 从报告中抑制可能的误报 | **全局功能配置:** ``` [llm.features] generate_poc = true execute_poc = false # enable only inside Docker # 按工具覆盖 — 禁用 bandit 的 PoC(SAST,无 runtime target) [llm.features.tool.bandit] generate_poc = false # 按类别覆盖 — 禁用 noisy crawlers 的日志分析 [llm.features.category.web] logs_analysis = false ``` **功能优先级:** `工具覆盖 > 类别覆盖 > 全局` ### 自定义提示词 所有 LLM 提示词均可被覆盖: ``` [llm.prompts] enrich_system = "You are a senior penetration tester..." mitigation_user = "Write remediation steps for: {title}..." # 可用占位符:{title} {severity} {description} {cwe} # {exploitability} {tool} {target} {cves} {raw_output} ``` ### 范围过滤器 ``` [llm] include_tools = [] # empty = all tools exclude_tools = ["hakrawler", "gau"] include_categories = [] exclude_categories = ["dns"] ``` ## PoC 生成与执行 ### 生成 (始终对宿主安全) LLM 会为每个发现编写自包含的 Python 和/或 Bash 脚本。脚本使用 BlackArch 镜像中已有的工具 (`curl`、`sqlmap`、`nuclei`、`dalfox` 等) 并写入到 `_assets/poc/`。生成过程绝不执行代码 —— 它仅写入文件。 ``` [llm.poc] languages = ["python", "bash"] only_severities = ["critical", "high", "medium"] max_pocs = 20 allow_git_clone = false # permit cloning official exploit PoCs from GitHub ``` ### 执行 (仅在容器内) PoC 的执行受两个独立的防护措施限制: 1. `[llm.features]` 中的 `execute_poc = true` 2. `VS_IN_CONTAINER=1` 环境变量 (内置在 Docker 镜像中) 如果缺少任何一个防护措施,运行器将静默拒绝,因此它**无法在宿主机上执行**。静态拒绝列表会在执行前拒绝包含破坏性模式的脚本 (`rm -rf /`、`mkfs.`、fork 炸弹等)。 ``` # 在 container 内启用 PoC 执行 VS_LLM_FEATURE_EXECUTE_POC=true docker compose ... run --rm scanner ... ``` ## 插件系统 将定义了一个或多个 `AbstractTool` 子类的 `.py` 文件放入 `./plugins/` (或 `~/.vuln-scanner/plugins/`) 中,它们会在启动时被自动发现 —— 无需修改代码。 **发现顺序** (如果名称冲突,后面的条目会覆盖前面的): 1. `./plugins/` (相对于 CWD) 2. `~/.vuln-scanner/plugins/` 3. 通过 `[plugins] dirs` 或 `--plugin-dir` 配置的额外目录 **示例插件** (`plugins/my_scanner.py`): ``` from vuln_scanner.tools.abstract import AbstractTool from vuln_scanner.tools.enums import Severity, ScanStatus, TargetType from vuln_scanner.tools.models import Finding, ScanInput, ScanResult class MyScannerTool(AbstractTool): name: str = "my-scanner" category: str = "web" # Only runs against URL targets — skipped automatically for IPs, paths, etc. applicable_targets: frozenset[TargetType] = frozenset({TargetType.URL}) def build_command(self, target: str, scan_input: ScanInput) -> list[str]: return ["my-scanner", "--target", target, "--json"] def parse_output(self, raw: str, target: str) -> list[Finding]: ... ``` **配置:** ``` [plugins] enabled = true dirs = ["/opt/company-scanners"] ``` **CLI:** ``` vuln-scanner --plugin-dir /opt/company-scanners --targets https://app.example.com ``` ### 针对目标的行为 插件工具是全局注册的,但编排器的类型门控控制着每个插件实际针对哪些目标运行。声明了 `applicable_targets = frozenset({TargetType.URL})` 的插件永远不会针对 IP 或文件系统路径触发。 要在类型门控之外将插件限制为特定的目标字符串 (例如,仅针对已知的预发布主机运行),请在 `run()` 中返回 `ScanStatus.SKIPPED`: ``` def run(self, target: str, scan_input: ScanInput) -> ScanResult: if "staging" not in target: return ScanResult(tool=self.name, target=target, status=ScanStatus.SKIPPED) return super().run(target, scan_input) ``` 没有配置级别的针对目标的插件过滤器 —— 该逻辑属于插件本身。 ## 报告格式 并行生成三种格式。可选择任意组合: ``` [report] formats = ["markdown", "html", "json"] output_dir = "./reports" ``` 或通过 CLI:`--formats markdown html json` ### Markdown (`.md`) 遵循行业渗透测试惯例的专业结构化报告: 1. **执行摘要** —— 面向管理层的文字描述 2. **范围和方法论** —— 目标列表、使用的工具、扫描配置 3. **严重性评级指南** —— CVSS 范围 4. **发现概览** —— 风险分布矩阵 + 按目标的明细 5. **漏洞集群** —— 根本原因分组 (由 LLM 生成) 6. **详细发现** —— 每个发现:ID、严重性、受影响的系统、描述、业务影响、分析师注、缓解措施、永久修复、PoC 参考 7. **附录 A** —— 扫描错误 8. **附录 B** —— PoC 资产索引 如果多个工具报告了在同一目标上的相同问题,这些发现会被去重为一个显示所有相关工具的单一条目。 ### HTML (`.html`) 自包含的单文件报告 (无外部依赖),具有: - 明暗主题切换 - 按严重性颜色编码的发现卡片 - 可折叠的集群部分 - 统计网格和执行摘要主视觉区 ### JSON (`.json`) `Assessment` 模型的完整结构化转储 —— 发现、LLM 富化信息、集群、统计数据、PoC 记录。适用于 CI/CD pipeline 摄取和下游工具对接。 ## 快速开始 `poc.sh` 脚本通过一条命令启动 DefectDojo、三个易受攻击的目标以及扫描器。 **前提条件:** `docker`、`docker compose` 插件、`curl`、`python3` ``` ./poc.sh ``` | 步骤 | 操作 | |------|--------| | 1 | 检查前提条件 | | 2 | 加载 `.env` (如果缺失,则从 `.env.example` 复制) | | 3 | 启动 DefectDojo 技术栈 | | 4 | 等待 DefectDojo API 准备就绪 | | 5 | 通过管理员凭据获取 API token | | 6 | 启动易受攻击的目标容器 | | 7 | 等待每个目标可达 | | 8 | 构建扫描器 Docker 镜像 | | 9 | 运行扫描器,生成报告,推送到 DefectDojo | | 10 | 打印包含 URL 和清理说明的摘要 | **使用 LLM 分析:** ``` # 复制示例 env 并添加你的 key cp .env.example .env # 编辑 .env:设置 OPENAI_API_KEY 和 VS_LLM_MODEL ./poc.sh ``` **覆盖扫描模式:** ``` SCAN_MODE=active ./poc.sh ``` **清理:** ``` docker compose down -v docker compose -f docker-compose.target.yaml down -v ``` ## 易受攻击的目标 ### 本地 (Docker —— 由 `poc.sh` 启动) | 应用 | URL | 描述 | |-----|-----|-------------| | [OWASP Juice Shop](https://owasp.org/www-project-juice-shop/) | http://localhost:3000 | 涵盖 OWASP Top 10 的现代 Node.js 应用 | | [WebGoat](https://owasp.org/www-project-webgoat/) | http://localhost:8888/WebGoat | Java/Spring 编写的故意不安全的应用 | ### 远程实验室 —— [pentest-ground.com](https://pentest-ground.com) 由 pentest-ground.com 维护的公开的、故意存在漏洞的系统。无需设置 —— 直接扫描以验证工具和 PoC 生成。 | 系统 | URL | 类型 | 漏洞类别 | |--------|-----|------|----------------------| | DVWA | `https://pentest-ground.com:4280` | 经典 Web 应用 | CSRF, XSS, SQLi | | DVGQL | `https://pentest-ground.com:5013` | GraphQL API | CMDi, XSS, SQLi | | RestFlaw | `https://pentest-ground.com:9000` | REST API | SQLi, 代码注入, XXE | | GuardianLeaks | `https://pentest-ground.com:81` | Web 应用 | XSS, SSRF, 代码注入 | ``` vuln-scanner --targets \ https://pentest-ground.com:4280 \ https://pentest-ground.com:5013 \ https://pentest-ground.com:9000 \ https://pentest-ground.com:81 \ --mode active ``` ## 配置 复制带有注释的模板: ``` cp config.example.toml config.toml ``` **完整参考:** ``` [scan] targets = ["192.168.1.1", "https://app.example.com", "/src/myapp"] mode = "passive" # paranoid | passive | active | aggressive timeout = 300 # per-tool timeout in seconds rate_limit = null # requests/sec; null = no limit # 已认证扫描 — 转发至所有适用的 web tools [scan.auth] bearer_token = "" # Authorization: Bearer username = "" # HTTP Basic username password = "" # HTTP Basic password login_url = "" # Form-based login URL # [scan.auth.cookies] # session = "abc123" # [scan.auth.headers] # X-API-Key = "secret" [tools] exclude = ["nikto"] # skip specific tools by name [categories] include = ["web", "ssl"] # limit to these categories; empty = all [plugins] enabled = true # dirs = ["/opt/company-scanners"] [report] formats = ["markdown", "html", "json"] output_dir = "./reports" [defectdojo] url = "http://localhost:8080" api_key = "" product_name = "My Product" engagement_name = "Automated Scan" # ── LLM 分析 ───────────────────────────────────────────────────────────── [llm] enabled = "auto" # "auto" | true | false api_key = "" # or OPENAI_API_KEY env var base_url = "" # leave empty for OpenAI model = "" # required when active, e.g. "gpt-4o" or "llama3.2" temperature = 0.2 top_p = 0.95 max_tokens = 4096 # extra_body = { top_k = 40 } # 用于 Ollama/vLLM 的 top_k 支持 exclude_tools = [] exclude_categories = [] [llm.features] logs_analysis = true enrich = true classify = true cluster = true mitigation = true generate_poc = true execute_poc = false # container-only; set VS_LLM_FEATURE_EXECUTE_POC=true false_positive_filter = true # 按工具的功能覆盖(tool > category > global 优先级) [llm.features.tool.bandit] generate_poc = false [llm.features.category.dns] logs_analysis = false [llm.poc] languages = ["python", "bash"] only_severities = ["critical", "high", "medium"] max_pocs = 20 allow_git_clone = false ``` **配置合并优先级:** `CLI > 环境变量 > config.toml > 默认值` ## 环境变量 ### 核心 | 变量 | CLI 标志 | 描述 | |----------|----------|-------------| | `VS_TARGETS` | `--targets` | 空格分隔的目标列表 | | `VS_MODE` | `--mode` | 扫描模式 | | `VS_TIMEOUT` | `--timeout` | 每个工具的超时时间 (秒) | | `VS_RATE_LIMIT` | `--rate-limit` | 速率限制 (req/s) | | `VS_MAX_CONCURRENT` | `--max-concurrent` | 并行工具槽位 | | `VS_INCLUDE_TOOLS` | `--include-tools` | 按名称设置工具白名单 | | `VS_EXCLUDE_TOOLS` | `--exclude-tools` | 按名称设置工具黑名单 | | `VS_INCLUDE_CATEGORIES` | `--include-categories` | 设置类别白名单 | | `VS_EXCLUDE_CATEGORIES` | `--exclude-categories` | 设置类别黑名单 | | `VS_OUTPUT_DIR` | `--output-dir` | 报告输出目录 | ### 报告 | 变量 | CLI 标志 | 描述 | |----------|----------|-------------| | `VS_FORMATS` | `--formats` | 报告格式:`markdown html json` | ### LLM | 变量 | CLI 标志 | 描述 | |----------|----------|-------------| | `OPENAI_API_KEY` | — | API key (标准环境变量,用作备选) | | `OPENAI_BASE_URL` | — | Base URL 备选 (用于非 OpenAI endpoint) | | `VS_LLM_ENABLED` | `--no-llm` | `auto` \| `true` \| `false` | | `VS_LLM_MODEL` | `--llm-model` | 模型名称 (激活时必填) | | `VS_LLM_TEMPERATURE` | — | 采样温度 | | `VS_LLM_MAX_TOKENS` | — | 最大输出 token | | `VS_LLM_FEATURE_` | `--llm-feature NAME=on` | 全局功能切换,例如 `VS_LLM_FEATURE_GENERATE_POC=false` | | `VS_LLM_FEATURE_EXECUTE_POC` | `--llm-poc-execute` | 启用 PoC 执行 (仅在容器内) | ### 认证扫描 | 变量 | CLI 标志 | 描述 | |----------|----------|-------------| | `VS_AUTH_BEARER_TOKEN` | `--auth-bearer` | Bearer token (`Authorization: Bearer …`) | | `VS_AUTH_USERNAME` | `--auth-user` | HTTP Basic 用户名 | | `VS_AUTH_PASSWORD` | `--auth-pass` | HTTP Basic 密码 | | `VS_AUTH_LOGIN_URL` | `--auth-login-url` | 基于表单的登录 URL | Cookie 和额外的标头必须通过配置文件或 `--auth-cookie` / `--auth-header` CLI 标志进行设置。 ### 插件 | 变量 | CLI 标志 | 描述 | |----------|----------|-------------| | `VS_PLUGINS_ENABLED` | `--no-plugins` | 启用/禁用插件自动发现 | | `VS_PLUGINS_DIRS` | `--plugin-dir` | 额外的插件目录 (空格分隔) | ### DefectDojo | 变量 | CLI 标志 | 描述 | |----------|----------|-------------| | `VS_DEFECTDOJO_URL` | `--defectdojo-url` | DefectDojo base URL | | `VS_DEFECTDOJO_API_KEY` | `--defectdojo-api-key` | API token | | `VS_DEFECTDOJO_PRODUCT` | — | Product 名称 | | `VS_DEFECTDOJO_ENGAGEMENT` | — | Engagement 名称 | ## 项目结构 ``` vuln_scanner/ ├── config/ │ ├── models.py # AppConfig, AppLLMConfig, PluginsConfig (pydantic) │ └── loader.py # 3-layer merge: TOML + env (VS_*) + CLI │ ├── tools/ │ ├── enums.py # Severity, Confidence, ScanStatus, ScanMode, TargetType │ ├── models.py # Finding, ScanInput, ScanResult, AuthConfig (pydantic) │ ├── target.py # classify_target() — maps target string to TargetType set │ ├── abstract.py # AbstractTool ABC + subprocess execution helpers │ ├── __init__.py # TOOL_REGISTRY (86 tools) │ └── .py # One file per tool (86 total) │ ├── llm/ │ ├── models.py # LLMConfig, LLMFeatures, PocConfig (pydantic) │ ├── features.py # resolve_features() — tool > category > global merge │ ├── client.py # LLMClient — thin openai SDK wrapper │ ├── analyzer.py # LLMAnalyzer — 4-pass analysis pipeline │ └── prompts.py # Default prompt templates (all overridable) │ ├── poc/ │ ├── models.py # Poc, PocVerdict │ ├── generator.py # PocGenerator — writes scripts, never executes (host-safe) │ └── runner.py # PocRunner — executes scripts (VS_IN_CONTAINER guard) │ ├── reports/ │ ├── base.py # AbstractReporter │ ├── markdown.py # Professional structured Markdown report │ ├── html.py # Self-contained HTML with light/dark theme │ └── json_reporter.py # Full Assessment JSON dump │ ├── defectdojo/ │ └── client.py # DefectDojoClient — push findings via REST API │ ├── plugins.py # Plugin auto-discovery (./plugins/, ~/.vuln-scanner/plugins/) ├── model.py # Assessment, Cluster, AssessmentStats └── orchestrator.py # ScanOrchestrator — type-gated, async concurrent execution plugins/ # Drop .py plugin files here (auto-discovered at startup) main.py # Entry point config.example.toml # Fully documented configuration template .env.example # Environment variable reference Dockerfile # BlackArch-based image; bakes VS_IN_CONTAINER=1 docker-compose.yml # DefectDojo stack docker-compose.scanner.yml # Scanner service docker-compose.target.yaml # Vulnerable test targets (Juice Shop, WebGoat) poc.sh # End-to-end quick-start script ``` ## 添加新工具 对于一次性或私有工具,请使用[插件系统](#plugin-system) —— 将 `.py` 文件放入 `./plugins/` 中,无需修改代码。对于应随项目一起发布的工具: 1. 创建 `vuln_scanner/tools/mytool.py`: ``` from vuln_scanner.tools.abstract import AbstractTool from vuln_scanner.tools.enums import Severity, TargetType from vuln_scanner.tools.models import Finding, ScanInput class MyTool(AbstractTool): name: str = "mytool" category: str = "web" # Declare which target types this tool supports. # The orchestrator skips mismatched (tool, target) pairs automatically. applicable_targets: frozenset[TargetType] = frozenset({TargetType.URL, TargetType.HOST}) def build_command(self, target: str, scan_input: ScanInput) -> list[str]: return ["mytool", "--target", target] def parse_output(self, raw: str, target: str) -> list[Finding]: findings = [] for line in raw.splitlines(): if "VULN" in line: findings.append(Finding( title="Example finding", severity=Severity.HIGH, description=line, tool=self.name, target=target, )) return findings ``` 2. 在 `vuln_scanner/tools/__init__.py` 中注册它: ``` from vuln_scanner.tools.mytool import MyTool TOOL_REGISTRY: dict[str, type[AbstractTool]] = { ... "mytool": MyTool, } ``` 3. 将二进制文件添加到 `Dockerfile`: ``` RUN pacman -Sy --noconfirm mytool ``` **提示:** - 对于写入文件而不是标准输出的工具,请在 `build_command()` 中使用 `OUTPUT_FILE_SENTINEL` 并重写 `run()` 以调用 `self._run_with_tempfile()`。 - 带有 `applicable_targets = frozenset(TargetType)` (默认值) 的工具会针对所有目标类型运行 —— 请仅对真正通用的工具使用此项。 - 找不到二进制文件 → `ScanStatus.SKIPPED` (在报告中隐藏)。工具错误 → `ScanStatus.FAILED` (显示在附录 A 中)。 ## 开发 ``` # 安装 dev dependencies uv sync # 运行测试(仅限 host-safe — 不执行真实工具) uv run pytest tests/ -v # Lint uv run ruff check . uv run ruff format . ``` **测试类别:** - `tests/test_config.py` — 配置合并和验证 - `tests/test_target_typing.py` — `classify_target()` 和 `applies_to()` - `tests/test_orchestrator_gating.py` — 使用模拟工具进行类型门控 - `tests/test_llm.py` — LLM 功能、模拟客户端、PoC 运行器容器防护 - `tests/test_reports.py` — 所有三种报告器 (Markdown、HTML、JSON) - `tests/test_nmap.py` — nmap 出解析器 **安全规则:** 永远不要在宿主机上运行真正的扫描工具。所有工具执行都在 Docker 容器内针对隔离的目标容器进行。`PocRunner` 强制执行此操作 —— 它会在执行任何 PoC 脚本之前检查 `VS_IN_CONTAINER=1`,并且 Docker 镜像中内置了此变量。 ## DefectDojo 集成 当配置了 `api_key` 和 `product_name` 后,发现的结果将被自动推送。 **获取你的 API key:** 1. 在 http://localhost:8080 打开 DefectDojo 2. 登录 (默认:`admin` / `admin`) 3. 前往 **Profile → API v2 Key** **手动推送:** ``` VS_DEFECTDOJO_API_KEY=your-key \ VS_DEFECTDOJO_PRODUCT="My App" \ uv run vuln-scanner --targets 192.168.1.1 ```
标签:Docker容器, LIDS, Petitpotam, Python, 大语言模型分析, 安全工具集成, 实时处理, 密码管理, 插件系统, 攻击面发现, 无后门, 自动化安全评估, 计算机取证, 请求拦截, 逆向工具