Scanner de Avaliação de Vulnerabilidades com Geração de Relatórios
Uma plataforma automatizada de avaliação de vulnerabilidades que orquestra 86 ferramentas de segurança de código aberto, agrega e deduplica descobertas, executa uma camada opcional de análise LLM compatível com OpenAI para triagem, agrupamento e remediação, gera scripts de prova de conceito e produz relatórios profissionais em Markdown, HTML e JSON — tudo a partir de uma única imagem Docker BlackArch Linux.
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)
Todas as ferramentas de varredura e a execução de PoC são executadas dentro de um contêiner Docker **BlackArch Linux** — nada é instalado no host.
---
## Ferramentas
86 ferramentas organizadas por categoria. Cada ferramenta declara os tipos de alvo que suporta; o orquestrador ignora automaticamente combinações incompatíveis.
### Varredura de Rede e Portas
| Tool | Notes |
|------|-------|
| `nmap` | Varredura completa de portas com detecção de serviço/versão |
| `rustscan` | Scanner de portas rápido, alimenta o nmap |
| `masscan` | Scanner TCP/UDP de alta velocidade |
| `naabu` | Scanner de portas com detecção de serviços |
| `netdiscover` | Descoberta de hosts baseada em ARP |
### Aplicações Web
| Tool | Notes |
|------|-------|
| `nuclei` | Scanner de vulnerabilidades baseado em templates |
| `nikto` | Scanner de má configuração do servidor web |
| `wapiti` | Scanner de vulnerabilidades web caixa-preta |
| `ffuf` | Fuzzer web rápido (diretórios, parâmetros, cabeçalhos) |
| `feroxbuster` | Descoberta de conteúdo com recursão |
| `gobuster` | Forçador bruto de URI/DNS/vhost |
| `wfuzz` | Fuzzer de aplicações web |
| `dalfox` | Scanner de XSS com análise de parâmetros |
| `xsstrike` | Mecanismo avançado de detecção de XSS |
| `commix` | Explorador de injeção de comandos |
| `sqlmap` | Injeção SQL automatizada e tomada de controle |
| `nosqlmap` | Scanner de injeção NoSQL |
| `httpx` | Sondagem e fingerprinting HTTP |
| `whatweb` | Fingerprinter de tecnologias web |
| `wafw00f` | Detecção e fingerprinting de WAF |
| `wpscan` | Scanner de vulnerabilidades WordPress |
| `acunetix` | Scanner de vulnerabilidades web (baseado em API) |
| `arachni` | Scanner de segurança para aplicações web |
| `zap` | Scanner DAST OWASP ZAP |
| `wapiti` | Scanner de vulnerabilidades caixa-preta |
| `drheader` | Analisador de cabeçalhos de segurança HTTP |
| `humble` | Verificador de segurança de cabeçalhos HTTP |
| `hakrawler` | Rastreador web rápido para URLs e endpoints |
| `katana` | Framework de rastreamento web de próxima geração |
| `gau` | Coletor de URLs conhecidas (AlienVault, WaybackMachine) |
| `jsluice` | Extrator de segredos e URLs de JavaScript |
| `corscanner` | Scanner de má configuração de CORS |
| `crlfuzz` | Scanner de injeção CRLF |
| `smuggler` | Detector de contrabando de requisições HTTP |
| `linkfinder` | Descoberta de endpoints em código JavaScript/HTML |
| `cariddi` | Rastreador web com detecção de segredos e endpoints |
### API e GraphQL
| Tool | Notes |
|------|-------|
| `kiterunner` | Descoberta de rotas de API com arquivos kite |
| `graphql_cop` | Auditor de segurança GraphQL |
| `restler` | Fuzzer de API REST com estado |
| `apifuzzer` | Fuzzer baseado em OpenAPI/Swagger |
| `cherrybomb` | Linter de segurança de especificações OpenAPI |
| `arjun` | Descoberta de parâmetros HTTP |
| `paramspider` | Mineração de parâmetros a partir do wayback/fontes |
### DNS e Reconhecimento
| Tool | Notes |
|------|-------|
| `amass` | Enumeração de subdomínios (passiva + ativa) |
| `subfinder` | Enumeração passiva rápida de subdomínios |
| `dnsx` | Conjunto de ferramentas de resolução e sondagem DNS |
| `dnsrecon` | Enumeração DNS e transferência de zona |
| `fierce` | Reconhecimento DNS e descoberta de hosts |
| `theharvester` | OSINT: e-mails, nomes, hosts, subdomínios |
| `puredns` | Forçador bruto de subdomínios rápido com filtragem de curingas |
| `alterx` | Mecanismo de permutação de subdomínios |
| `waybackurls` | Coleta de URLs históricas da Wayback Machine |
| `httprobe` | Sondador de hosts HTTP/HTTPS ativos |
### TLS / SSL
| Tool | Notes |
|------|-------|
| `testssl` | Auditoria de configuração TLS e suítes de cifras |
| `sslyze` | Scanner TLS (suítes de cifras, Heartbleed, ROBOT) |
| `sslscan` | Scanner de serviços SSL/TLS |
| `tlsx` | Sondagem TLS rápida |
| `tls_attacker` | Ferramenta de ataque ao protocolo TLS |
| `ssh_audit` | Auditor de configuração SSH e algoritmos |
### SMB e Serviços de Rede
| Tool | Notes |
|------|-------|
| `smbmap` | Enumeração de compartilhamentos SMB e permissões |
| `enum4linux` | Enumeração SMB/NetBIOS |
| `crackmapexec` | Avaliação de Active Directory e SMB |
| `openvas` | Scanner de vulnerabilidades OpenVAS |
### SAST e Análise de Código
| Tool | Notes |
|------|-------|
| `bandit` | SAST Python — antipadrões de segurança comuns |
| `semgrep` | SAST multilíngue com regras da comunidade |
| `gosec` | Verificador de segurança Go |
| `bearer` | SAST de fluxo de dados com regras de privacidade e segurança |
| `horusec` | Mecanismo SAST multilíngue |
| `brakeman` | Scanner SAST Ruby on Rails |
| `flawfinder` | Análise estática C/C++ para falhas comuns |
| `dependency_check` | Scanner de vulnerabilidades de dependências OWASP |
| `pip_audit` | Verificador de vulnerabilidades de pacotes Python |
### Análise de Composição de Software (SCA)
| Tool | Notes |
|------|-------|
| `osv-scanner` | Scanner do banco de dados de Vulnerabilidades de Código Aberto |
| `npm-audit` | Auditoria de vulnerabilidades de pacotes Node.js |
| `govulncheck` | Verificador de vulnerabilidades de módulos Go |
### Detecção de Segredos
| Tool | Notes |
|------|-------|
| `gitleaks` | Scanner de segredos no histórico do Git |
| `trufflehog` | Localizador de segredos profundo baseado em entropia |
| `secretfinder` | Segredos em arquivos JS e endpoints |
| `detect-secrets` | Scanner de segredos baseado em baseline |
| `noseyparker` | Scanner de segredos de alta velocidade com regras de padrões |
### IaC e Configuração
| Tool | Notes |
|------|-------|
| `checkov` | Scanner IaC para Terraform/K8s/Dockerfile |
| `tfsec` | Análise estática Terraform |
| `terrascan` | Scanner de segurança IaC multi-nuvem |
| `hadolint` | Linter de boas práticas para Dockerfile |
### Infraestrutura em Nuvem
| Tool | Notes |
|------|-------|
| `prowler` | Avaliação da postura de segurança AWS/GCP/Azure |
| `kube-bench` | Verificador do CIS Kubernetes Benchmark |
### Contêiner e Cadeia de Suprimentos
| Tool | Notes |
|------|-------|
| `trivy` | Scanner de vulnerabilidades de imagens de contêiner + sistema de arquivos |
| `grype` | Correspondente de vulnerabilidades de contêineres e pacotes |
---
## Seleção por Tipo de Alvo
O orquestrador classifica cada alvo em um ou mais tipos e executa apenas ferramentas que declaram suporte para esse tipo. Isso elimina ruído, por exemplo, de ferramentas SMB executadas contra URLs web.
| Tipo | Exemplo | Ferramentas que correspondem |
|------|---------|-----------------|
| `HOST` | `example.com` | Ferramentas de DNS, SSL, web, SMB |
| `IP` | `10.0.0.1` | Ferramentas de rede, portas, SMB |
| `CIDR` | `10.0.0.0/24` | Scanners de rede |
| `URL` | `https://app.example.com` | Ferramentas de web, API, SSL |
| `PATH` | `/src/myapp` | Ferramentas de SAST, SCA, segredos, IaC |
| `REPO` | `https://github.com/org/repo` | Ferramentas de segredos, SAST, SCA |
| `IMAGE` | `myapp:latest` | Scanners de contêineres |
| `CLOUD` | `aws:profile=prod`, `arn:aws:…` | Ferramentas de postura em nuvem (prowler, kube-bench, terrascan) |
A classificação é automática — basta passar a string do alvo; o scanner descobre o tipo.
Formatos de alvo em nuvem reconhecidos:
- AWS ARN: `arn:aws:iam::123456789012:root`
- Forma abreviada de perfil nomeado: `aws:profile=production`
- Projeto GCP: `projects/my-project-id`
- UUID de assinatura do Azure: `00000000-0000-0000-0000-000000000000`
---
## Modos de Varredura
| Modo | Descrição |
|------|-------------|
| `paranoid` | Máximo stealth — sondagem passiva, pegada mínima |
| `passive` | Sem ataques ativos — apenas enumeração e captura de banner **(padrão)** |
| `active` | Verificações padrão de vulnerabilidades habilitadas |
| `aggressive` | Varredura completa: todos os templates, força bruta, temporização rápida |
---
## Varredura Autenticada
As credenciais são encaminhadas para todas as ferramentas web aplicáveis (nuclei, ffuf, feroxbuster, gobuster, nikto, sqlmap, dalfox, wpscan, wapiti, katana, hakrawler, arjun, wfuzz, corscanner, kiterunner, httpx).
### Credenciais globais
Aplicadas a todos os alvos, a menos que exista uma sobreposição por alvo.
**Via config:**```toml
[scan.auth]
bearer_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
username = "admin"
password = "secret"
[scan.auth.cookies]
session = "abc123"
[scan.auth.headers]
X-API-Key = "my-api-key"
Através de variáveis de ambiente (somente global):```bash VS_AUTH_BEARER_TOKEN=eyJ... VS_AUTH_USERNAME=admin VS_AUTH_PASSWORD=secret
**Via CLI** (apenas global):```bash
vuln-scanner --targets https://app.example.com \
--auth-bearer eyJ... \
--auth-cookie session=abc123 \
--auth-header X-API-Key=secret
Ao verificar vários alvos que exigem credenciais diferentes, defina substituições por alvo em [scan.auth.targets."<target>"]. Uma entrada correspondente substitui completamente a configuração global para esse alvo — não há mesclagem. A autenticação por alvo é somente por arquivo de configuração (variáveis de ambiente e flags de CLI definem apenas o padrão global).```toml
[scan.auth]
bearer_token = "default-token"
[scan.auth.targets."https://app.example.com"] bearer_token = "app-specific-jwt"
[scan.auth.targets."https://admin.example.com"] [scan.auth.targets."https://admin.example.com".cookies] session = "s%3Aabc123" csrftoken = "xyz789"
[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"
**Resolução:** `per-target config > global config`
---
## Análise com LLM
Quando uma chave de API está presente, a camada de LLM é ativada automaticamente. Ela executa quatro passagens sobre os resultados da varredura:
| Pass | Nome | O que faz |
|------|------|-------------|
| 1 | **Triagem** | Atribui CWE, confiança, sinalizador de falso positivo, resumo de explorabilidade e elabora um PoC para cada descoberta |
| 2 | **Geração de PoC** | Escreve scripts Python/Bash autônomos que confirmam a descoberta usando ferramentas já presentes no contêiner |
| 3 | **Mitigação** | Produz mitigações concretas de curto prazo e remediações permanentes, opcionalmente informadas pelas evidências do PoC |
| 4 | **Agrupamento** | Agrupa descobertas por causa raiz, escreve remediações compartilhadas e produz um resumo executivo |
### Configuração do provedor
O cliente de LLM é compatível com a API da OpenAI — funciona com OpenAI, Azure OpenAI, Ollama, vLLM, LM Studio, OpenRouter e qualquer outro endpoint compatível.```toml
[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
# Sampling parameters (all OpenAI-compatible)
temperature = 0.2
top_p = 0.95
max_tokens = 4096
# top_k and other non-standard params go in extra_body:
# [llm.extra_body]
# top_k = 40
Exemplo do Ollama:```toml [llm] base_url = "http://localhost:11434/v1" api_key = "ollama" model = "llama3.2"
**Exemplo vLLM:**```toml
[llm]
base_url = "http://localhost:8000/v1"
api_key = "token-abc123"
model = "meta-llama/Meta-Llama-3-8B-Instruct"
Cada capacidade de LLM é um recurso nomeado, ativável/desativável globalmente e sobrescrevível por ferramenta ou por categoria.
| Recurso | Padrão | Descrição |
|---|---|---|
logs_analysis | on | Alimentar a saída bruta da ferramenta para o LLM |
enrich | on | Triagem de CWE / confiança / falso-positivo / explorabilidade |
classify | on | Classificar o tipo de achado e o risco |
cluster | on | Agrupar achados por causa raiz |
mitigation | on | Gerar mitigação e remediação |
generate_poc | on | Escrever scripts de PoC como ativos do relatório |
execute_poc | off | Executar PoCs no contêiner (requer VS_IN_CONTAINER=1) |
false_positive_filter | on | Suprimir prováveis falsos positivos do relatório |
Configuração global de recursos:```toml [llm.features] generate_poc = true execute_poc = false # enable only inside Docker
[llm.features.tool.bandit] generate_poc = false
[llm.features.category.web] logs_analysis = false
**Precedência de recursos:** `tool override > category override > global`
### Prompts personalizados
Todos os prompts de LLM são substituíveis:```toml
[llm.prompts]
enrich_system = "You are a senior penetration tester..."
mitigation_user = "Write remediation steps for: {title}..."
# Available placeholders: {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"]
---
## Geração e Execução de PoC
### Geração (sempre segura para o host)
O LLM escreve scripts Python e/ou Bash autocontidos para cada achado. Os scripts usam ferramentas já presentes na imagem BlackArch (`curl`, `sqlmap`, `nuclei`, `dalfox`, etc.) e são gravados em `<report>_assets/poc/`. A geração nunca executa código — ela apenas grava arquivos.```toml
[llm.poc]
languages = ["python", "bash"]
only_severities = ["critical", "high", "medium"]
max_pocs = 20
allow_git_clone = false # permit cloning official exploit PoCs from GitHub
A execução do PoC é controlada por duas proteções independentes:
execute_poc = true em [llm.features]VS_IN_CONTAINER=1 (embutida na imagem Docker)O runner recusa silenciosamente se qualquer uma das proteções estiver ausente, portanto não pode executar no host. Uma lista de bloqueio estática rejeita scripts que contenham padrões destrutivos (rm -rf /, mkfs., fork bombs, etc.) antes da execução.```bash
VS_LLM_FEATURE_EXECUTE_POC=true docker compose ... run --rm scanner ...
---
## Sistema de Plugins
Coloque um arquivo `.py` definindo uma ou mais subclasses de `AbstractTool` em `./plugins/` (ou `~/.vuln-scanner/plugins/`) e eles serão descobertos automaticamente na inicialização — nenhuma alteração de código é necessária.
**Ordem de descoberta** (as entradas posteriores substituem em caso de colisão de nomes):
1. `./plugins/` (relativo ao CWD)
2. `~/.vuln-scanner/plugins/`
3. Diretórios extras configurados por meio de `[plugins] dirs` ou `--plugin-dir`
**Exemplo de plugin** (`plugins/my_scanner.py`):```python
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]:
...
Config:```toml [plugins] enabled = true dirs = ["/opt/company-scanners"]
**CLI:**```bash
vuln-scanner --plugin-dir /opt/company-scanners --targets https://app.example.com
As ferramentas de plugins são registradas globalmente, mas o controle de tipos (type-gating) do orquestrador determina contra quais alvos cada plugin realmente é executado. Um plugin que declara applicable_targets = frozenset({TargetType.URL}) nunca será disparado contra um IP ou um caminho de sistema de arquivos.
Para restringir um plugin a strings de alvo específicas além do controle de tipos (por exemplo, executar apenas contra um host de staging conhecido), retorne ScanStatus.SKIPPED dentro de run():```python
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)
Não há filtro de plugin por alvo em nível de configuração — essa lógica pertence ao próprio plugin.
---
## Formatos de Relatório
Três formatos são gerados em paralelo. Selecione qualquer combinação:```toml
[report]
formats = ["markdown", "html", "json"]
output_dir = "./reports"
Ou via CLI: --formats markdown html json
.md)Relatório profissional estruturado seguindo as convenções da indústria de pentest:
Achados de múltiplas ferramentas que relatam o mesmo problema no mesmo alvo são deduplicados em uma única entrada exibindo todas as ferramentas contribuintes.
.html)Relatório autocontido de arquivo único (sem dependências externas) com:
.json)Dump estruturado completo do modelo Assessment — achados, enriquecimento por LLM, agrupamentos, estatísticas, registros de PoC. Adequado para ingestão em pipelines de CI/CD e ferramentas a jusante.
O script poc.sh inicia o DefectDojo, três alvos vulneráveis e o scanner em um único comando.
Pré-requisitos: docker, o plugin docker compose, curl, `python3````bash
./poc.sh
| Etapa | Ação |
|------|--------|
| 1 | Verifica pré-requisitos |
| 2 | Carrega `.env` (copia de `.env.example` se ausente) |
| 3 | Inicia a stack DefectDojo |
| 4 | Aguarda a API do DefectDojo ficar pronta |
| 5 | Obtém o token da API por meio das credenciais de administrador |
| 6 | Inicia os contêineres de alvos vulneráveis |
| 7 | Aguarda cada alvo ficar acessível |
| 8 | Constrói a imagem Docker do scanner |
| 9 | Executa o scanner, gera relatórios, envia para o DefectDojo |
| 10 | Exibe o resumo com URLs e instruções de desmontagem |
**Com análise de LLM:**```bash
# Copy the example env and add your key
cp .env.example .env
# Edit .env: set OPENAI_API_KEY and VS_LLM_MODEL
./poc.sh
Substituir modo de varredura:```bash SCAN_MODE=active ./poc.sh
**Desmontagem:**```bash
docker compose down -v
docker compose -f docker-compose.target.yaml down -v
poc.sh)| App | URL | Descrição |
|---|---|---|
| OWASP Juice Shop | http://localhost:3000 | Aplicativo Node.js moderno que cobre o OWASP Top 10 |
| WebGoat | http://localhost:8888/WebGoat | Aplicativo Java/Spring intencionalmente inseguro |
Sistemas públicos e intencionalmente vulneráveis mantidos por pentest-ground.com. Nenhuma configuração necessária — escaneie diretamente para validar ferramentas e geração de PoC.
| Sistema | URL | Tipo | Classes de Vulnerabilidades |
|---|---|---|---|
| DVWA | https://pentest-ground.com:4280 | Aplicativo Web Clássico | CSRF, XSS, SQLi |
| DVGQL | https://pentest-ground.com:5013 | API GraphQL | CMDi, XSS, SQLi |
| RestFlaw | https://pentest-ground.com:9000 | API REST | SQLi, Injeção de Código, XXE |
| GuardianLeaks | https://pentest-ground.com:81 | Aplicativo Web | XSS, SSRF, Injeção de Código |
| 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 |
---
## scanner.sh — Wrapper do Docker
`scanner.sh` é a interface recomendada para o uso diário na execução do scanner. Ele envolve o `docker compose run` para que você nunca precise digitar a invocação do compose manualmente — basta passar alvos e flags diretamente.```bash
./scanner.sh [OPTIONS] [-- SCANNER_ARGS...]
| Flag | Description |
|---|---|
-t, --targets HOST... | Um ou mais alvos de varredura (URL, IP, CIDR, caminho, imagem) |
-m, --mode MODE | Modo de varredura: passive | active | aggressive | paranoid |
-c, --config FILE | Arquivo de configuração a montar (padrão: ./config.toml) |
-f, --formats FMT | Formatos de relatório, separados por vírgula: markdown,html,json; repetível |
--no-llm | Desativar o enriquecimento por LLM |
--llm-model MODEL | Substituição do modelo LLM (ex.: gpt-4o, claude-sonnet-4-5) |
--llm-min-severity SEV | Severidade mínima para LLM: info|low|medium|high|critical |
--include-tools TOOLS | Lista separada por vírgulas de ferramentas para executar |
--exclude-tools TOOLS | Lista separada por vírgulas de ferramentas para ignorar |
-e, --env KEY=VALUE | Passar uma variável de ambiente extra para o contêiner |
-b, --build | Reconstruir a imagem Docker antes de executar |
-n, --no-defectdojo | Ignorar a integração com DefectDojo |
--shell | Abrir um shell interativo dentro do contêiner em vez de varrer |
-h, --help | Mostrar ajuda |
Tudo após -- é encaminhado literalmente para o entrypoint do scanner, ignorando toda a lógica do wrapper.
./scanner.sh
./scanner.sh -t https://app.example.com 192.168.1.0/24 -m active
./scanner.sh -c /path/to/prod.toml
./scanner.sh -t https://app.example.com --llm-model gpt-4o
./scanner.sh -t https://app.example.com --include-tools nuclei,dalfox,ffuf
./scanner.sh --build -t https://app.example.com -m active
./scanner.sh -- --targets https://t.example.com --mode aggressive --formats markdown html json
./scanner.sh --shell ./scanner.sh --build --shell
### O que faz automaticamente
- Carrega o `.env` (copia de `.env.example` se estiver ausente)
- Copia `config.example.toml` → `config.toml` se não existir nenhuma configuração
- Cria a rede Docker `vuln_scanner_network` se não estiver presente
- Monta um arquivo `--config` personalizado no contêiner em `/app/config.toml`
- Reconstrói a imagem quando `--build` é passado
---
## Configuração
Copie o modelo anotado:```bash
cp config.example.toml config.toml
Referência completa:```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
[scan.auth] bearer_token = "" # Authorization: Bearer username = "" # HTTP Basic username password = "" # HTTP Basic password login_url = "" # Form-based login URL
[tools] exclude = ["nikto"] # skip specific tools by name
[categories] include = ["web", "ssl"] # limit to these categories; empty = all
[plugins] enabled = true
[report] formats = ["markdown", "html", "json"] output_dir = "./reports"
[defectdojo] url = "http://localhost:8080" api_key = "" product_name = "My Product" engagement_name = "Automated Scan"
[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
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
[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
**Precedência de mesclagem de configuração:** `CLI > env vars > config.toml > defaults`
---
## Variáveis de Ambiente
### Núcleo
| Variável | Flag CLI | Descrição |
|----------|----------|-------------|
| `VS_TARGETS` | `--targets` | Lista de alvos separada por espaços |
| `VS_MODE` | `--mode` | Modo de varredura |
| `VS_TIMEOUT` | `--timeout` | Tempo limite por ferramenta (segundos) |
| `VS_RATE_LIMIT` | `--rate-limit` | Limite de taxa (req/s) |
| `VS_MAX_CONCURRENT` | `--max-concurrent` | Slots paralelos de ferramentas |
| `VS_INCLUDE_TOOLS` | `--include-tools` | Ferramentas na lista de permissões por nome |
| `VS_EXCLUDE_TOOLS` | `--exclude-tools` | Ferramentas na lista de bloqueio por nome |
| `VS_INCLUDE_CATEGORIES` | `--include-categories` | Categorias na lista de permissões |
| `VS_EXCLUDE_CATEGORIES` | `--exclude-categories` | Categorias na lista de bloqueio |
| `VS_OUTPUT_DIR` | `--output-dir` | Diretório de saída dos relatórios |
### Relatórios
| Variável | Flag CLI | Descrição |
|----------|----------|-------------|
| `VS_FORMATS` | `--formats` | Formatos de relatório: `markdown html json` |
### LLM
| Variável | Flag CLI | Descrição |
|----------|----------|-------------|
| `OPENAI_API_KEY` | — | Chave de API (variável de ambiente padrão, usada como fallback) |
| `OPENAI_BASE_URL` | — | URL base de fallback (para endpoints não-OpenAI) |
| `VS_LLM_ENABLED` | `--no-llm` | `auto` \| `true` \| `false` |
| `VS_LLM_MODEL` | `--llm-model` | Nome do modelo (obrigatório quando ativo) |
| `VS_LLM_TEMPERATURE` | — | Temperatura de amostragem |
| `VS_LLM_MAX_TOKENS` | — | Máximo de tokens de saída |
| `VS_LLM_FEATURE_<NAME>` | `--llm-feature NAME=on` | Alternância global de recursos, ex.: `VS_LLM_FEATURE_GENERATE_POC=false` |
| `VS_LLM_FEATURE_EXECUTE_POC` | `--llm-poc-execute` | Habilita execução de PoC (somente contêiner) |
### Varredura Autenticada
| Variável | Flag CLI | Descrição |
|----------|----------|-------------|
| `VS_AUTH_BEARER_TOKEN` | `--auth-bearer` | Token Bearer (`Authorization: Bearer …`) |
| `VS_AUTH_USERNAME` | `--auth-user` | Nome de usuário HTTP Basic |
| `VS_AUTH_PASSWORD` | `--auth-pass` | Senha HTTP Basic |
| `VS_AUTH_LOGIN_URL` | `--auth-login-url` | URL de login baseado em formulário |
Cookies e cabeçalhos extras devem ser definidos via arquivo de configuração ou flags CLI `--auth-cookie` / `--auth-header`.
### Plugins
| Variável | Flag CLI | Descrição |
|----------|----------|-------------|
| `VS_PLUGINS_ENABLED` | `--no-plugins` | Habilita/desabilita descoberta automática de plugins |
| `VS_PLUGINS_DIRS` | `--plugin-dir` | Diretórios extras de plugins (separados por espaços) |
### DefectDojo
| Variável | Flag CLI | Descrição |
|----------|----------|-------------|
| `VS_DEFECTDOJO_URL` | `--defectdojo-url` | URL base do DefectDojo |
| `VS_DEFECTDOJO_API_KEY` | `--defectdojo-api-key` | Token de API |
| `VS_DEFECTDOJO_PRODUCT` | — | Nome do produto |
| `VS_DEFECTDOJO_ENGAGEMENT` | — | Nome do engajamento |
---
## Estrutura do Projeto```
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)
│ └── <tool>.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.yaml # DefectDojo stack
docker-compose.scanner.yaml # Scanner service
docker-compose.target.yaml # Vulnerable test targets (Juice Shop, WebGoat)
scanner.sh # Convenience wrapper — runs the scanner via docker compose
poc.sh # End-to-end quick-start script (DefectDojo + targets + scanner)
Para ferramentas pontuais ou privadas, use o Sistema de Plugins — coloque um arquivo .py em ./plugins/ sem alterações de código. Para ferramentas que devem acompanhar o projeto:
vuln_scanner/tools/mytool.py:```python
from vuln_scanner.tools.abstract import AbstractTool
from vuln_scanner.tools.enums import Severity, TargetType
from vuln_scanner.tools.models import Finding, ScanInputclass 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. Registre-o em `vuln_scanner/tools/__init__.py`:```python
from vuln_scanner.tools.mytool import MyTool
TOOL_REGISTRY: dict[str, type[AbstractTool]] = {
...
"mytool": MyTool,
}
Dockerfile:```dockerfile
RUN pacman -Sy --noconfirm mytool**Dicas:**
- Para ferramentas que gravam em um arquivo em vez de stdout, use `OUTPUT_FILE_SENTINEL` em `build_command()` e sobrescreva `run()` para chamar `self._run_with_tempfile()`.
- Ferramentas com `applicable_targets = frozenset(TargetType)` (o padrão) são executadas em todos os tipos de alvo — use isso apenas para ferramentas genuinamente universais.
- Binário não encontrado → `ScanStatus.SKIPPED` (oculto do relatório). Erro de ferramenta → `ScanStatus.FAILED` (mostrado no Apêndice A).
---
## Desenvolvimento```bash
# Install with dev dependencies
uv sync
# Run tests (host-safe only — no real tool execution)
uv run pytest tests/ -v
# Lint
uv run ruff check .
uv run ruff format .
Categorias de teste:
tests/test_config.py — mesclagem e validação de configuraçãotests/test_target_typing.py — classify_target() e applies_to()tests/test_orchestrator_gating.py — type-gating com ferramentas simuladas (mocks)tests/test_llm.py — recursos de LLM, cliente simulado, proteção de contêiner do PoC runnertests/test_reports.py — todos os três geradores de relatórios (Markdown, HTML, JSON)tests/test_nmap.py — parser de saída do nmapRegra de segurança: nunca execute ferramentas reais de varredura no host. Toda a execução de ferramentas acontece dentro do contêiner Docker contra os contêineres de destino isolados. O PocRunner aplica essa regra — ele verifica VS_IN_CONTAINER=1 antes de executar qualquer script PoC, e a imagem Docker já embute essa variável.
Os resultados (findings) são enviados automaticamente quando api_key e product_name estão configurados.
Obtenha sua chave de API:
admin / admin)Envio manual:```bash
VS_DEFECTDOJO_API_KEY=your-key
VS_DEFECTDOJO_PRODUCT="My App"
uv run vuln-scanner --targets 192.168.1.1