
Proxy MITM HTTP/HTTPS baseado em Go com interceptação de HTTP/2 e HTTP/1.1, geração de certificados CA local/por host, tunelamento CONNECT/WebSocket, cache em disco, painel administrativo, captura de tráfego, políticas de bloqueio e varredura opcional de ameaças com suporte de IA, incluindo redação, quarentena e registro de auditoria.
Um proxy Man‑in‑the‑Middle (MITM) HTTP/HTTPS leve e amigável para desenvolvedores, escrito em Go. Suporta HTTP/1.1 e HTTP/2, tunelamento CONNECT, tunelamento WebSocket (ws/wss), cache de respostas em disco com filtros flexíveis e recarga de configuração em tempo real.

O Go MITM Proxy é um proxy de interceptação destinado a depuração, testes, aprendizado e interceptação controlada de tráfego HTTP(S). Quando o MITM está habilitado, ele gera dinamicamente certificados folha por host assinados por uma CA local, permitindo que o proxy descriptografe e inspecione o tráfego HTTPS. Ele também pode funcionar como um túnel TCP transparente quando o MITM está desabilitado ou para domínios/portas excluídos.
Importante: Este aplicativo realiza interceptação Man-in-the-Middle (MITM) ativa, incluindo a geração e o uso de certificados TLS para descriptografar tráfego HTTPS. Dependendo da sua jurisdição e ambiente de rede, interceptar tráfego sem consentimento claro e prévio de todos os usuários afetados pode ser ilegal e pode violar privacidade, políticas de trabalho ou requisitos regulatórios.
Antes de usar este software em qualquer ambiente que não seja sua própria máquina local:
Todos os usuários de qualquer rede onde este proxy possa interceptar tráfego devem ser claramente informados de que a interceptação e inspeção de HTTP(S) ocorrerá. O consentimento deve ser explícito e, idealmente, documentado.
Não execute este software em redes que você não possua, administre ou tenha autorização explícita para testar ou monitorar.
Muitas regiões possuem leis rigorosas que regulamentam a interceptação, o registro e o armazenamento de dados de usuários (ex.: GDPR, CCPA, leis de escuta telefônica). Você é responsável por garantir que seu uso esteja em conformidade com todos os regulamentos aplicáveis.
A chave privada da CA gerada (geralmente ca-key.pem) permite que seu detentor se passe por qualquer domínio para usuários que confiem no certificado correspondente.
Este proxy foi projetado para desenvolvimento, depuração, testes controlados ou fins educacionais — não para monitoramento oculto ou vigilância não autorizada.
Ao usar este software, você reconhece e aceita total responsabilidade por garantir que seu uso seja legal, ético e devidamente comunicado a todos os usuários afetados.
Pré-requisitos:
Clone e compile: ```bash git clone https://github.com/Welfordian/mitm-proxy.git cd mitm-proxy go build ./
Isso produz um binário mitm-proxy (ou mitm-proxy.exe no Windows) na raiz do projeto.
## Início Rápido
1) Execute o proxy com as configurações padrão (escuta em :8080): ```bash
./mitm-proxy
Na primeira inicialização, uma CA local será criada e salva em ca-cert.pem e ca-key.pem.
Configure seu navegador ou curl para usar o proxy em http://localhost:8080.
Confie no certificado CA gerado (ca-cert.pem) no seu sistema operacional/navegador para permitir a interceptação HTTPS. Veja Confiando na CA Local.
Visite um site HTTPS através do proxy e observe os logs. Use o modo verboso para mais detalhes: ```bash ./mitm-proxy --verbose
## Usage
### Command-line Flags
- --config string: Caminho para o arquivo config.json
- --listen string: Endereço de escuta (substitui a configuração)
- --ca-cert string: Caminho para o certificado CA existente (substitui a configuração)
- --ca-key string: Caminho para a chave CA existente (substitui a configuração)
- --mitm bool: Ativar interceptação MITM (padrão true; definir como false força o tunelamento)
- --verbose bool: Ativar registro detalhado (verbose)
- --watch-config bool: Monitorar o config.json em busca de alterações e aplicar automaticamente (padrão true)
- --admin-enabled bool: Ativar API/dashboard administrativo local (padrão true)
- --admin-addr string: Endereço de escuta da API/dashboard administrativo (padrão 127.0.0.1:9090)
- --admin-token string: Token bearer administrativo (gerado na inicialização se omitido)
- --admin-read-token string: Token bearer somente leitura para acesso administrativo GET/HEAD/OPTIONS
- --admin-ui bool: Servir a interface administrativa incorporada (padrão true)
- --admin-store string: Caminho do armazenamento SQLite administrativo (padrão dashboard.db)
As flags da CLI substituem os valores do arquivo de configuração quando indicado.
### Configuration (config.json)
Um exemplo de config.json está incluído no repositório: ```json
{
"listen_addr": ":8080",
"proxy_name": "MITM-Proxy",
"ca_cert_path": null,
"ca_key_path": null,
"ca_cert_output_path": "ca-cert.pem",
"ca_key_output_path": "ca-key.pem",
"enable_mitm": true,
"admin_enabled": true,
"admin_addr": "127.0.0.1:9090",
"admin_token": "",
"admin_read_token": "",
"admin_ui": true,
"admin_store": "dashboard.db",
"excluded_domains": [],
"blocked_ports": [25, 445, 3389],
"blocked_domains": [],
"blocked_ips": [],
"block_action": "deny",
"block_response_status": 403,
"traffic_capture": {
"store_bodies": false,
"max_body_bytes": 32768,
"redact_bodies": true,
"store_headers": true,
"redacted_headers": ["Authorization", "Cookie", "Proxy-Authorization", "Set-Cookie", "X-Api-Key"],
"store_cookies": true,
"redacted_cookies": []
},
"proxy_auth": {
"enabled": false,
"realm": "MITM Proxy",
"require_auth_for_loopback": false,
"default_action": "allow"
},
"verbose_logging": true,
"log_requests": true,
"max_idle_conns": 200,
"idle_conn_timeout_seconds": 90,
"tls_handshake_timeout_seconds": 10,
"min_tls_version": "1.2",
"tls_next_protos": ["h2", "http/1.1"],
"cache": {
"enabled": true,
"directory": "/var/cache/mitm-proxy",
"include_domains": [],
"exclude_domains": [],
"include_extensions": ["jpg", "png", "webp", "css", "js"],
"exclude_extensions": [],
"ttl": 3600
}
}
Notas:
O servidor de administração serve o painel em http://127.0.0.1:9090/admin/ por padrão. As rotas da API exigem Authorization: Bearer <token>; para uso no navegador local, /admin/?token=<token> armazena o token no armazenamento local do navegador.
A cobertura inicial do painel/API inclui:
O painel inclui uma confirmação de uso responsável na primeira execução. A chave privada da CA nunca é exposta por meio da API de administração.
O estado do painel é armazenado em SQLite em dashboard.db por padrão. As configurações alteradas pelo painel são aplicadas imediatamente e gravadas de volta no arquivo JSON configurado, ou em config.json quando o proxy foi iniciado com os padrões.
O frontend de administração é um aplicativo Vite/React em internal/admin/ui. Seu build de produção é emitido para internal/admin/ui/dist e embutido no binário Go. Para atualizar os assets do painel:```bash
cd internal/admin/ui
npm install
npm run build
### Encadeamento de Proxy Upstream
O tráfego de saída pode ser encadeado através de um proxy upstream HTTP ou HTTPS, como Burp, ZAP ou um proxy de saída corporativo. Quando ativado, o encaminhamento normal de HTTP(S), túneis pass-through CONNECT, WebSockets e envios do Repeater utilizam o proxy upstream, a menos que um host corresponda a `no_proxy`.```json
{
"upstream_proxy": {
"enabled": true,
"url": "http://127.0.0.1:8080",
"username": "",
"password_env": "UPSTREAM_PROXY_PASSWORD",
"no_proxy": ["localhost", "127.0.0.1", "*.internal"],
"chain_tunnels": true,
"apply_to_repeater": true
}
}
Apenas URLs de proxy upstream http:// e https:// são suportadas na v1. Se a autenticação Basic for necessária, defina username e forneça a senha por meio da variável de ambiente nomeada; credenciais incorporadas na URL são rejeitadas e nunca são exibidas nas configurações do painel. Se o proxy upstream estiver habilitado, mas indisponível, as solicitações afetadas falham visivelmente em vez de recorrerem silenciosamente a conexões diretas.
A visualização Access Control do painel gerencia usuários de proxy do cliente e regras de ACL ordenadas de permitir/negar. Os usuários de proxy são armazenados em SQLite com hashes de senha bcrypt; senhas em texto simples são aceitas apenas ao criar ou redefinir um usuário e nunca são retornadas pela API.
Ative a autenticação Basic do proxy por meio de proxy_auth em config.json ou na visualização Settings. Quando habilitado, os clientes devem enviar Proxy-Authorization: Basic ... a menos que clientes de loopback estejam isentos. As regras de ACL são avaliadas por prioridade e podem corresponder a nome de usuário, IP/CIDR de origem, host ou host curinga, porta ou faixa de portas, método e escopo de pesquisa. Listas de correspondência vazias significam "qualquer".
Proxy-Authorization é removida antes do encaminhamento, encadeamento upstream, captura de tráfego, consulta de cache, verificação de ameaças e clonagem no Repeater. O tráfego capturado inclui a atribuição proxy_user quando disponível, e a caixa de pesquisa do Traffic pode corresponder a nomes de usuário de proxy.
A visualização Repeater do painel permite que pesquisadores de segurança clonem tráfego HTTP capturado em casos editáveis salvos. Um caso armazena o método, URL, cabeçalhos, amostra do corpo, tempo limite e o ID opcional do fluxo de tráfego de origem. Cada envio armazena uma execução com status, duração, cabeçalhos de resposta, uma amostra limitada do corpo da resposta e qualquer erro upstream.
Os corpos de solicitação capturados são pré-preenchidos apenas quando traffic_capture.store_bodies estava habilitado no momento da captura. Se a redação do corpo foi habilitada, o repeater recebe a amostra redigida; corpos não capturados permanecem vazios e podem ser editados manualmente.
O endpoint legado POST /api/traffic/{id}/replay permanece disponível para reprodução única, enquanto o repeater é destinado à mutação repetível de solicitações e comparação de respostas.
A visualização Pentest Toolkit do painel constrói mapas passivos de alvos a partir do tráfego capturado. A reconstrução de um mapa analisa apenas o tráfego armazenado para o escopo selecionado, agrupa endpoints por caminho normalizado, extrai parâmetros de consulta/corpo/cookie/cabeçalho, registra parâmetros refletidos e interessantes e adiciona dicas passivas, como cabeçalhos de segurança ausentes, lacunas de atributos de cookie, CORS permissivo e erros detalhados.
Os mapas de pentest são persistidos em SQLite e podem ser excluídos de forma independente. O kit de ferramentas nunca envia solicitações, rastreia, faz fuzzing nem modifica alvos; as evidências de endpoints podem ser clonadas no Repeater para testes manuais.
A visualização Scopes do painel permite que pesquisadores definam limites de alvos nomeados com host, substring da URL e padrões opcionais de método. Os escopos habilitados são correspondidos automaticamente quando o tráfego é capturado; fluxos correspondentes, casos clonados no Repeater e eventos do verificador de ameaças recebem um único scope_id.
O seletor global de escopo filtra as visualizações Traffic, Repeater e Threat Scanner entre todo o tráfego, um escopo habilitado selecionado ou itens fora do escopo. Excluir um escopo limpa os valores de scope_id relacionados sem excluir o tráfego capturado, os casos do Repeater, as execuções ou os dados de ameaças.
Os filtros de escopo estão disponíveis em GET /api/traffic, GET /api/repeater/cases e GET /api/threats/events com scope_id=<id> ou scope_id=__out_of_scope__. Adicione include_out_of_scope=true para incluir linhas sem escopo ao lado de um escopo selecionado.
A visualização AI Copilot do painel armazena notas de pesquisa geradas por IA vinculadas ao Traffic, casos do Repeater, execuções, escopos ou eventos de ameaças. Os detalhes do Traffic podem pedir ao copiloto para explicar uma solicitação ou sugerir os próximos testes manuais; o Repeater pode sugerir testes para um caso salvo ou comparar as duas execuções mais recentes.
O copiloto é apenas consultivo. Ele nunca envia tráfego, edita casos do Repeater, altera escopos, altera configurações nem remove dados. O tráfego fora do escopo pode ser explicado, mas sugestões ativas de teste são intencionalmente omitidas.
Ative-o por meio de ai_copilot em config.json ou na visualização Settings:```json
{
"ai_copilot": {
"enabled": true,
"provider": "openai",
"model": "gpt-5.4-nano",
"timeout_ms": 10000,
"max_body_bytes": 32768,
"redact_before_ai": true,
"openai_api_key_env": "OPENAI_API_KEY"
}
}
A chave da API OpenAI é lida da variável de ambiente configurada e não é armazenada no painel de controle nem no arquivo de configuração. Cabeçalhos confidenciais, amostras de corpo e valores de consulta são ocultados antes do envio do contexto de IA quando `redact_before_ai` está habilitado. As notas salvas incluem o modelo, o hash do prompt, o resumo e a saída estruturada da IA, não o prompt completo.
### Varredura de Ameaças com IA
O scanner de ameaças pode inspecionar solicitações e respostas HTTP com heurísticas locais e, quando configurado, solicitar uma segunda opinião à OpenAI antes de bloquear tráfego suspeito.
1. Crie uma chave da API OpenAI e exponha-a ao processo do proxy:```powershell
$env:OPENAI_API_KEY = "sk-..."
No macOS/Linux:```bash export OPENAI_API_KEY="sk-..."
2. Ative o scanner em `config.json`:```json
{
"threat_scanner": {
"enabled": true,
"mode": "suspicious_only",
"provider": "openai",
"model": "gpt-5.4-nano",
"second_opinion_model": "gpt-5.4-mini",
"scan_requests": true,
"scan_responses": true,
"max_body_bytes": 131072,
"max_ai_body_bytes": 32768,
"ai_timeout_ms": 750,
"block_threshold": 0.85,
"warn_threshold": 0.65,
"require_ai_confirmation_for_block": true,
"block_critical_local_on_ai_failure": true,
"fail_open": true,
"scan_content_types": [
"text/html",
"text/plain",
"application/json",
"application/javascript",
"text/javascript",
"application/xml"
],
"skip_content_types": [
"image/",
"video/",
"audio/",
"font/",
"application/octet-stream"
],
"trusted_domains": [
"accounts.google.com",
"login.microsoftonline.com",
"github.com"
],
"allowlist_domains": [],
"malicious_domains": [],
"malicious_file_hashes": [],
"threat_intel_updated": "",
"quarantine_dir": "quarantine",
"debug_log_path": "threats.log",
"redact_before_ai": true,
"store_bodies": false,
"openai_api_key_env": "OPENAI_API_KEY"
}
}
The dashboard's **Threat Scanner** view shows scanned request/response counts, AI call counts, detections, verdict details, top local rules, and override actions.
Scanner modes:
- `suspicious_only`: default; local heuristics decide when to call AI.
- `all_text`: calls AI for text-like traffic.
- `paranoid`: also calls AI for text-like traffic and is intended for high-sensitivity testing.
- `metadata_only`: uses headers, URL, host, and metadata without AI body review.
- `off`: disables scanning.
Useful safety and privacy controls:
- `redact_before_ai`: redacts common secrets and personal data before sending evidence to OpenAI.
- `max_ai_body_bytes`: limits the body sample included in AI evidence.
- `require_ai_confirmation_for_block`: prevents local heuristics from blocking unless AI confirms, except where `block_critical_local_on_ai_failure` is enabled for critical local evidence.
- `fail_open`: allows traffic when the scanner fails, unless stricter blocking settings apply.
- `trusted_domains` and `allowlist_domains`: reduce false positives for known-good hosts.
- `malicious_domains` and `malicious_file_hashes`: add local threat-intel hits without waiting for AI.
- `debug_log_path`: writes scanner decisions to a local JSONL-style log for debugging.
To use a different environment variable name for the API key, set `openai_api_key_env` and export that variable before starting the proxy. Do not put API keys directly in `config.json`.
### Trusting the Local CA
To intercept HTTPS, import and trust ca-cert.pem in your OS/browser:
- macOS: Keychain Access → login/system → Certificates → import ca-cert.pem → set Always Trust.
- Windows: certmgr.msc → Trusted Root Certification Authorities → Certificates → import ca-cert.pem.
- Linux (varies): e.g., update-ca-certificates, or browser‑specific store (Firefox: Settings → Privacy & Security → Certificates → View → Authorities → Import).
Without trusting the CA, browsers will show certificate warnings for intercepted sites.
### Using the Proxy
Set your HTTP/HTTPS proxy to the listen address (default http://localhost:8080).
Examples with curl: ```bash
# HTTP
curl -x http://localhost:8080 http://example.com/
# HTTPS (after trusting the CA for full MITM)
curl -x http://localhost:8080 https://example.com/
# Disable MITM and tunnel only
./mitm-proxy --mitm=false
# Change listen address
./mitm-proxy --listen=127.0.0.1:9090
Notas sobre WebSocket:
O cache é baseado em arquivos e só considera requisições HTTP GET quando habilitado. A seleção é controlada por:
Em caso de cache hit, as respostas incluem:
O diretório de cache é garantido na inicialização e em alterações de configuração. Se nenhum diretório for definido, o padrão é ./cache.
go build ./ ./mitm-proxy --config ./config.json
O servidor se vincula ao listen_addr configurado e lida com HTTP + HTTPS com ALPN.
## Roteiro
- Autenticação de proxy (Basic/NTLM) e ACLs
- Suporte a proxy upstream/encadeamento
- Geração de arquivos PAC e scripts auxiliares
- UI para inspecionar fluxos e entradas de cache
- Controles de impressão digital TLS e estilo JA3
- Endpoints de métricas/saúde e integração com Prometheus
## Contribuindo
Issues e pull requests são bem-vindos. Para mudanças significativas, abra uma issue primeiro para discutir escopo e design.
Estilo de código: mantenha as mudanças mínimas e focadas; prefira clareza e funções pequenas e componíveis.