Share
## https://sploitus.com/exploit?id=564D9FC2-08CD-5262-ACF4-FC0BB7A88577
# pentest-confirm-mcp

**Model Context Protocol (MCP) server for authorized penetration testing with anti-false-positive confirmation.**
**Servidor MCP para pentest autorizado com confirmação anti-falso-positivo.**

[![version](https://img.shields.io/badge/version-2.1.0-blue.svg)](./CHANGELOG.md)
[![python](https://img.shields.io/badge/python-3.12+-brightgreen.svg)](https://www.python.org/)
[![license](https://img.shields.io/badge/license-MIT-yellow.svg)](./LICENSE)
[![mcp](https://img.shields.io/badge/MCP-stdio-purple.svg)](https://modelcontextprotocol.io/)

> 🇬🇧 **English** section below · 🇧🇷 **Português** section on top

---

## 🇧🇷 Português

### O que é

`pentest-confirm-mcp` é um servidor **Model Context Protocol** (MCP) que expõe **21 ferramentas de pentest** para clientes como Claude Code, Claude Desktop, Cursor, ou qualquer cliente que fale MCP stdio.

O diferencial dele é a **arquitetura anti-falso-positivo**: analisadores puros (sem rede) que **confirmam por contraste** — dois requests, um com payload benigno e outro com canário — só reportam vulnerabilidade quando o padrão é reprodutível. Você não gasta tempo perseguindo achados que não existem.

### Por que isso importa?

Scanners tradicionais geram muito ruído. Um XSS "detectado" porque um `` aparece no body pode ser só uma tag natural da página. `pentest-confirm-mcp` só marca `CONFIRMADO` quando:

- **XSS refletido**: o canário aparece cru na resposta do payload **E não** na resposta de controle.
- **SQLi baseado em erro**: aparece erro SQL na resposta com aspa **E** desaparece com a aspa+comentário (balanceada).
- **SQLi baseada em tempo**: `sleep_ms` >> `baseline_ms` **E** `control_ms` (SLEEP(0)) é próximo do baseline — descarta latência de rede.

Findings ambíguos viram `SUSPEITO` (0.55 confidence) ou `PISTA` (0.30). Só `CONFIRMADO` tem 0.95.

### Instalação

#### Opção 1 — Via Docker/Podman (recomendado)

```bash
git clone https://github.com/rafaeltondin/pentest-confirm-mcp.git
cd pentest-confirm-mcp
docker build -f Dockerfile -t pentest-confirm:2.1.0 .
docker build -f Dockerfile.mcp -t pentest-confirm:2.1.0-mcp .
```

Para incluir `hydra` (brute force) e `searchsploit` (CVE lookup):

```bash
docker build -f Dockerfile.full -t pentest-confirm:2.1.0-full .
```

#### Opção 2 — Localmente com venv

```bash
git clone https://github.com/rafaeltondin/pentest-confirm-mcp.git
cd pentest-confirm-mcp
python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python -m pentest_confirm.mcp_server   # roda o server MCP via stdio
```

Dependências de sistema (opcionais):
- `nmap` — para `nmap_scan` e enum de portas do `full_scan`
- `hydra` — para `hydra_brute`
- `searchsploit` — para `searchsploit_lookup`
- `dig` (bind9-dnsutils) — para `dns_enum`

Sem elas, as tools respectivas retornam erro amigável.

### Configuração no cliente MCP

#### Claude Code

Adicione ao `~/.claude/settings.json`:

```json
{
  "mcpServers": {
    "pentest_confirm": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "pentest-confirm:2.1.0-mcp"]
    }
  }
}
```

Ou apontando pro venv local:

```json
{
  "mcpServers": {
    "pentest_confirm": {
      "command": "/caminho/absoluto/.venv/bin/python",
      "args": ["-m", "pentest_confirm.mcp_server"],
      "cwd": "/caminho/pentest-confirm-mcp"
    }
  }
}
```

#### Claude Desktop

Idem, `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) ou o path equivalente do seu SO.

### Sanidade em 1 comando

Depois de configurar, na conversa com o cliente MCP, peça:

> "Rode `self_test_full` do pentest_confirm."

Se responder `all_ok: true`, todos os analisadores puros passaram — o server está saudável.

### As 21 ferramentas

#### Análise pura (sem rede)

| Tool | O que faz | Quando usar |
|---|---|---|
| `analyze_security_headers` | Detecta CSP/HSTS/X-Content-Type-Options/X-Frame-Options ausentes | Após coletar headers de uma resposta |
| `analyze_dir_listing` | Detecta autoindex ativo (`Index of /` + `...",
  "response_headers": {"Server": "Apache/2.4.41"}
}
```

Retorna `{tech: {...}, searchsploit_hint: ["Server Apache/2.4.41", ...]}`. Passe as hints pro `searchsploit_lookup`.

#### 6) Regressão do próprio server

```json
// tool: self_test_full
{}
```

Retorna `{self_test_rc: 0, all_ok: true, extra_checks: {xss_confirm: true, xss_no_fp: true, sqli_error: true}}`.

### Fluxo padrão sugerido

```
1. self_test_full                            → sanidade
2. dns_enum + whois_lookup + tls_inspect     → OSINT
3. full_scan max_phase=recon do_nmap=false   → panorama HTTP
4. Se WordPress → analyze_wordpress via full_scan
5. Achou params? full_scan max_phase=validacao (XSS+SQLi confirmados)
6. Autorização por escrito? → full_scan max_phase=exploracao authorized=true
7. Banner suspeito? → searchsploit_lookup  
```

### Segurança

Este projeto foi desenhado para **pentest autorizado**:

- Bloqueia alvos em redes privadas por default (`allow_private=False`).
- Tools ofensivas exigem `authorized=True` explícito.
- `hydra_brute` faz TCP preflight — evita gasto em porta fechada.
- Rate-limit configurável, com respeito a `Retry-After` em 429/503.
- LGPD: `cnpj_lookup` redige CPF de sócios por default (`redact_pii=True`).

**Use apenas contra sistemas de sua propriedade ou com autorização por escrito.**

### Contribuindo

Bugs, features ou padrões novos de detecção: abra uma issue ou PR. Regra de ouro: **toda mudança em analisador deve vir com caso no `run_self_test()`**.

### Licença

MIT.

---

## 🇬🇧 English

### What it is

`pentest-confirm-mcp` is a **Model Context Protocol** (MCP) server exposing **21 pentest tools** to MCP-speaking clients (Claude Code, Claude Desktop, Cursor, etc).

Its key trait is the **anti-false-positive architecture**: pure (non-network) analyzers that **confirm by contrast** — two requests, one with a benign value and one with a canary — only report vulnerabilities when the pattern is reproducible. You don't chase findings that aren't real.

### Why it matters

Traditional scanners are noisy. A "detected" XSS just because `` appears in the body might be a normal page tag. `pentest-confirm-mcp` only marks `CONFIRMADO` when:

- **Reflected XSS**: canary appears raw in the *payload* response **AND** not in the *control* response.
- **Error-based SQLi**: SQL error appears with the quote **AND** disappears when the query is balanced (`'--`).
- **Time-based blind SQLi**: `sleep_ms` >> `baseline_ms` **AND** `control_ms` (SLEEP(0)) sits near baseline — rules out uniform network latency.

Ambiguous findings become `SUSPEITO` (0.55 confidence) or `PISTA` (0.30). Only `CONFIRMADO` is 0.95.

### Install

#### Option 1 — Docker / Podman

```bash
git clone https://github.com/rafaeltondin/pentest-confirm-mcp.git
cd pentest-confirm-mcp
docker build -f Dockerfile -t pentest-confirm:2.1.0 .
docker build -f Dockerfile.mcp -t pentest-confirm:2.1.0-mcp .
```

For `hydra` (brute) + `searchsploit`:

```bash
docker build -f Dockerfile.full -t pentest-confirm:2.1.0-full .
```

#### Option 2 — Local venv

```bash
python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python -m pentest_confirm.mcp_server
```

### MCP client config

Claude Code (`~/.claude/settings.json`):

```json
{
  "mcpServers": {
    "pentest_confirm": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "pentest-confirm:2.1.0-mcp"]
    }
  }
}
```

### The 21 tools

| Tool | Category | Description |
|---|---|---|
| `analyze_security_headers` | Pure | Detects missing CSP/HSTS/X-Content-Type-Options/X-Frame-Options |
| `analyze_dir_listing` | Pure | Detects active autoindex |
| `analyze_reflected_xss` | Pure | Reflected XSS by contrast (canary in payload, absent in control) |
| `analyze_sqli_error` | Pure | Error-based SQLi via three-way (base/quote/balanced) |
| `analyze_time_based_sqli` | Pure | Blind time-based with anti-network-latency control (`SLEEP(0)`) |
| `analyze_open_redirect` | Pure | 3xx redirect to a controlled external canary host |
| `analyze_stack_trace` | Pure | Python/Java/PHP/Rails/Node/.NET/Oracle/FastAPI/Django leak |
| `analyze_cookie_flags` | Pure | Cookies missing HttpOnly / Secure / SameSite |
| `fingerprint_tech` | Pure | Tech heuristics + `searchsploit_hint` |
| `whois_lookup` | OSINT | WHOIS via raw TCP/43 (no apt) |
| `dns_enum` | OSINT | Enum A/AAAA/MX/NS/TXT/CNAME/SOA/CAA + AXFR test |
| `enum_subdomains_crtsh` | OSINT | Subdomains via CT logs + hackertarget fallback |
| `cnpj_lookup` | OSINT (BR) | Brazilian CNPJ lookup — BrasilAPI + ReceitaWS |
| `company_footprint` | OSINT (BR) | Correlates domain ↔ CNPJ ↔ owners |
| `nmap_scan` | Network | Port scan + service detection |
| `tls_inspect` | Network | TLS cert (SAN, expiry, self-signed, protocol) |
| `searchsploit_lookup` | Network | Banner → CVE via local searchsploit |
| `hydra_brute` | Offensive | Brute with 60 default creds (gated by `authorized=True`) |
| `full_scan` | Offensive | Full 5-phase orchestrator (`authorized=True` for exploration) |
| `self_test` | Regression | Anti-FP internal test suite (24 cases, no network) |
| `self_test_full` | Regression | `self_test` + XSS/SQLi analyzer smoke |

### Usage examples

**1) Sanity check:**

```json
// tool: self_test_full
{}
```

Should return `{all_ok: true}`.

**2) Recon-only full scan (no nmap, no subs):**

```json
{
  "target_url": "https://your-target.com/",
  "max_phase": "recon",
  "do_nmap": false,
  "do_subs": false
}
```

**3) Authorized exploitation-phase scan:**

```json
{
  "target_url": "https://your-target.com/",
  "authorized": true,
  "max_phase": "exploracao",
  "do_nmap": true,
  "do_subs": true,
  "stealth": true
}
```

### Security

Designed for **authorized penetration testing** only:

- Private-network targets blocked by default (`allow_private=False`).
- Offensive tools require explicit `authorized=True`.
- `hydra_brute` runs a TCP preflight — no wasted attempts on closed ports.
- Configurable rate-limit; respects `Retry-After` on 429/503.
- LGPD: `cnpj_lookup` redacts partner CPF by default.

**Only use against systems you own or have written permission to test.**

### License

MIT.

---

## Contributing / Contribuindo

PRs welcome. Any change to a pure analyzer must include a case in `run_self_test()`.
Contribuições são bem-vindas. Qualquer mudança em analisador deve vir com caso em `run_self_test()`.

## Changelog

See [CHANGELOG.md](./CHANGELOG.md).

---

*Built with ❤ for the security community. Feedback via GitHub Issues.*