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
http2smugl — Detecta e explora vulnerabilidades de contrabando de requisições HTTP através da conversão de HTTP/2 para HTTP/1.1, utilizando técnicas automatizadas de contrabando de cabeçalhos para identificar discrepâncias de análise no backend. | Kitploit
Ferramentas/GitHubGitHub/neex/http2smugl
Análise de VulnerabilidadesExploração de Aplicações WebSegurança WebTestes de Penetração
GitHubneex/http2smugl

http2smugl

Detecta e explora vulnerabilidades de contrabando de requisições HTTP através da conversão de HTTP/2 para HTTP/1.1, utilizando técnicas automatizadas de contrabando de cabeçalhos para identificar discrepâncias de análise no backend.

Ver Repositório
56274há 1 anoRevisado pelo Kitploit

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

http2smugl

Esta ferramenta ajuda a detectar e explorar o contrabando de requisições HTTP em casos em que pode ser alcançado via conversão HTTP/2 -> HTTP/1.1 pelo servidor frontend.

O esquema é o seguinte:

  1. Um atacante envia uma requisição HTTP/2 maliciosa ao servidor alvo, que chamamos de frontend.
  2. A requisição é (presumivelmente) convertida para HTTP/1.1 e transmitida para outro servidor, o backend.

O atacante quer encontrar uma requisição que seja vista como duas requisições separadas pelo servidor backend.

Se a conexão HTTP/1.1 entre frontend<->backend usar keep-alive, o frontend pode enviar requisições de outros usuários para a mesma conexão. Se formos capazes de "envenenar" a conexão com uma requisição parcial que vem após uma legítima, podemos recuperar a requisição de outro usuário.

Outros cenários possíveis incluem contornar a proteção e reescritas do servidor frontend, envenenamento de cache ou engano de cache.

Para mais informações sobre o Contrabando de Requisições HTTP, consulte a Portswigger Web Security Academy.

Por que focar em HTTP/2?

No HTTP/2, todos os nomes e valores dos cabeçalhos HTTP são binários. Isso significa que tecnicamente eles podem conter espaços adicionais ou até mesmo quebras de linha.

RFC7540#10.3 afirma que implementações que traduzem requisições HTTP/2 para HTTP/1 devem cuidar das limitações no conjunto de caracteres que surgem dessa conversão; a maioria das implementações de fato os rejeita. Apesar disso, esperamos encontrar algumas que permitam tais cabeçalhos. Eles irão corromper a requisição HTTP/1.1 convertida para o backend.

Outro ponto é que algumas correções recentes relacionadas ao Contrabando de Requisições HTTP podem ser implementadas apenas para parsers HTTP/1.1.

Em geral, esperamos que existam implementações de HTTP/2 que não estejam muito cientes das pesquisas recentes sobre Contrabando de Requisições HTTP em HTTP/1.1 e não incluam mitigações correspondentes.

Você encontrou uma única vulnerabilidade com isso?

Surpreendentemente, sim!

Encontrei a possibilidade de contrabandear um cabeçalho com um caractere de espaço através do Cloudflare, abrindo assim uma porta para contrabando entre Cloudflare e cliente (caso o software de um cliente do Cloudflare aceite e faça trim nos nomes dos cabeçalhos). Aqui está o post no blog.

Há também outro relatório de bug bounty que ainda não é público. Ele faz uso do fato de que softwares personalizados não filtram quebras de linha em cabeçalhos HTTP2, e o contrabando acontece 100% (consigo ver requisições de outros usuários).

No entanto, entendo que esse tipo de vulnerabilidade deve ser frustrantemente raro: ao contrário do HTTP/1.1, não existem tantas implementações de HTTP/2, e a maioria delas é feita com segurança em mente, rejeitando cabeçalhos suspeitos ou inválidos.

Algoritmo de detecção

A ferramenta possui um subcomando que tenta detectar automaticamente se um alvo é vulnerável ao ataque de Contrabando de Requisições HTTP. O algoritmo por trás dessa funcionalidade é descrito nesta seção.

Para realizar um ataque de Contrabando de Requisições HTTP, na verdade precisamos primeiro "contrabandear" um único cabeçalho (seja Content-Length ou Transfer-Encoding). Isso significa que precisamos enviar um cabeçalho que a) controle onde o corpo da requisição termina e b) não seja processado pelo frontend, mas seja processado pelo backend.

Isso geralmente é conseguido modificando um cabeçalho de alguma forma: adicionando espaços ou tabulações ao final do seu nome, substituindo o valor por um semiequivalente, etc.

A ideia básica do algoritmo de detecção de vulnerabilidade é detectar se o servidor realmente processa um cabeçalho contrabandeado como se fosse Content-Length ou Transfer-Encoding. Fazemos isso enviando múltiplas requisições: algumas com valores válidos e outras com valores inválidos para o cabeçalho. Em seguida, tentamos detectar se há uma maneira de distinguir as respostas desses dois grupos.

É por isso que a saída da ferramenta não contém as palavras "vulnerável/invulnerável": ela apenas informa se consegue distinguir as respostas que vieram das requisições desses dois grupos.

A ferramenta considera dois conjuntos de respostas HTTP como distinguíveis se pelo menos uma das duas condições a seguir for atendida:

  1. Os conjuntos de seus códigos de resposta não se intersectam
  2. Os conjuntos de comprimentos das respostas são separáveis entre si (por exemplo, todas as respostas "válidas" são mais longas que 1000 bytes e todas as "inválidas" são mais curtas).

Os timeouts são tratados como um valor de código de status único, não igual a nenhum outro; assim, a ferramenta substitui o esquema clássico de "detectar por tempo".

Vamos considerar um exemplo. Suponha que estamos tentando contrabandear o cabeçalho transfer-encoding substituindo o traço por um sublinhado.

Se parecer que o servidor responde com status 400 toda vez que enviamos transfer_encoding:zalupa e trava quando é transfer_encoding:chunked, podemos dizer que o servidor provavelmente processa o cabeçalho como o valor para transfer encoding. Teoricamente, poderia ser o servidor frontend ou backend.

O primeiro caso não é interessante, pois poderíamos enviar a versão não contrabandeada do cabeçalho de qualquer forma, e o segundo é o que procuramos. Como tudo acontece sobre HTTP/2, o primeiro caso é evitável na maioria das vezes: o servidor HTTP/2 determina o final do corpo da requisição de outra forma, não relacionada aos cabeçalhos da requisição, e nunca espera que o corpo esteja no formato chunked do HTTP/1.1 (aquele com comprimentos de chunk hexadecimais).

As variações concretas das técnicas de detecção são:

  1. Enviamos uma versão contrabandeada de Transfer-Encoding: chunked (por exemplo, transfer_encoding:chunked) e corpos diferentes: válido é 0\r\n\r\n e inválido é 999\r\n.

    Caso as respostas sejam diferentes, podemos ter certeza de que o servidor backend recebe e processa o cabeçalho contrabandeado. Não há razão para o frontend fazer isso: HTTP/2 não usa o formato chunked que enviamos, então seria inválido.

    Esperamos que o backend trave (ou seja, a requisição expire) para as requisições inválidas, pois ele aguarda a chegada de mais dados.

    Esta é a variante de detecção mais confiável: se o servidor travar ao ler o corpo, algo provavelmente deu errado, já que não há uso para transfer encoding HTTP/1.1 em uma requisição HTTP/2.

  2. Enviamos uma versão contrabandeada de Transfer-Encoding e corpos diferentes novamente: 0\r\n\r\n como corpo válido e X\r\n\r\n como inválido.

    O caso é o mesmo que acima, mas em vez de ler o corpo, esperamos que o backend pelo menos o valide.

  3. Enviamos uma versão contrabandeada do cabeçalho Content-Length com valores 1 e -1.

Ao enviar múltiplos pares de requisições válidas/inválidas, podemos reduzir a chance de falsos positivos aleatórios. Por outro lado, podemos parar cedo se percebermos que não há como separar as respostas das requisições "válidas" das respostas das "inválidas".

Técnicas de contrabando

A ferramenta tenta empregar múltiplas técnicas de contrabando modificando um cabeçalho de várias maneiras. Nenhuma delas é nova e ao mesmo tempo óbvia.

Espaços

Para contrabandear um cabeçalho, anexamos um espaço a ele. É o método mais comum e clássico. Esperamos que o cabeçalho não seja processado pelo frontend, mas seja enviado como está para o backend, que remove o espaço.

A ferramenta tenta uma variedade de caracteres como espaços: inclui , \t, \v, \x00 e os Unicode.

Sublinhado

Para contrabandear um cabeçalho, substituímos o traço (-) por um sublinhado (_). Se o backend for inspirado em CGI de alguma forma, pode converter cabeçalhos como Header-Name para a forma HEADER_NAME; assim, o traço se tornará sublinhado de qualquer forma. Ao determinar como parsear o corpo, esse backend supostamente solicita o valor de CONTENT_LENGTH / TRANSFER_ENCODING de seu dicionário de cabeçalhos, e ele estará lá.

Quebras de linha

Este é específico do HTTP/2. Como HTTP/2 é um protocolo binário, podemos tentar enviar quebras de linha no nome ou valor do cabeçalho. O padrão proíbe, mas esperamos encontrar uma implementação que ainda aceite isso.

Durante a conversão HTTP/2 -> HTTP/1.1, o cabeçalho se divide em dois cabeçalhos diferentes, o que significa que a requisição parecerá diferente para o backend.

Para contrabandear um cabeçalho, colocamos seu nome e valor após uma quebra de linha: um cabeçalho com o nome "Transfer-Encoding" e o valor "chunked" se torna um com o nome "fake" com o valor "fake\r\ntransfer-encoding: chunked".

Caracteres UTF

Suponha que o backend use alguma linguagem de alto nível e não realize validação suficiente dos cabeçalhos. Nesse caso, ele pode converter os nomes para maiúsculas antes de fazer qualquer outra coisa e fazer isso usando funções que lidam com Unicode. Felizmente, TRANSFER-ENCODING contém a letra S, que é ſ (\u017f) em maiúscula.

Da mesma forma, podemos procurar por um backend que converta o valor de Transfer-Encoding para minúsculas: enviamos chunKed em vez de chunked com \u212a em vez de K.

Claro, é necessário que o frontend passe nomes/valores de cabeçalho UTF-8 para o backend.

Uso

Para instalar a ferramenta, execute go install github.com/neex/http2smugl@latest.

A ferramenta contém dois subcomandos: request e detect. O primeiro é apenas para criar requisições HTTP/2: a maioria das ferramentas de cliente não aceita cabeçalhos inválidos, então é útil ter uma que envie a entrada do usuário ao servidor como está.

O outro é detect. Ele tenta várias técnicas de contrabando de requisições HTTP para detectar se o alvo é vulnerável. O algoritmo de detecção é complicado; agradeço se você ler e me enviar seus comentários. Ele está descrito abaixo na seção correspondente.

http2smugl request

Use este subcomando para enviar uma requisição http2 (provavelmente um pouco malformada). O primeiro parâmetro é a URL, e os outros são apenas cabeçalhos no formato nome:valor (note que não há espaço após os dois pontos). A escapada com barra invertida é suportada: você pode usar códigos de escape \r,\n e \xXX. Por exemplo, para enviar um nome de cabeçalho que contenha dois pontos, use \x3a (ex.: nome\x3acom\x3adoispontos:valor).

http2smugl detect

Este subcomando tenta detectar o contrabando de requisições HTTP usando várias técnicas. Para usá-lo, basta executar http2smugl detect [URL HTTPS].

O comando só produzirá saída se conseguir detectar que o servidor interpreta um cabeçalho contrabandeado. Para entender o que isso significa, leia a seção correspondente.

Suporte a HTTP/3

Um suporte experimental para HTTP/3 (quic) foi implementado. No entanto, não sugiro usá-lo, pois não encontrei nenhum bug relacionado ao HTTP/3.

Para usar HTTP/3 com o subcomando request, forneça o proto https+h3:// na URL em vez de apenas https. O mesmo é suportado no comando detect.

Há também uma flag --try-http3 para o subcomando request, que altera o comportamento caso o protocolo não seja especificado na URL (apenas hostname). Se a flag estiver presente, o comando tentará o proto https+h3 para tais entradas na linha de comando ou no arquivo de alvos (assim como HTTP/2). Ex.: http2smugl detect --try-http3 www.example.com tentará tanto HTTP/3 quanto HTTP/2, mas http2smugl detect --try-http3 https://www.example.com/ ainda tentará apenas HTTP/2.

Falsos positivos conhecidos

Nesta seção, descrevo alguns casos em que a ferramenta diz que as respostas são "distinguíveis", mas nenhuma vulnerabilidade poderia existir.

ELB

O Elastic Load Balancer da Amazon implementa múltiplas mitigações contra Contrabando de Requisições HTTP. Embora nem todas rejeitem a requisição por padrão, o ELB não reutiliza uma conexão após enviar uma requisição com cabeçalhos "suspeitos". Portanto, um ataque real não é possível.

Para detectar se você está lidando com ELB, você pode usar o cabeçalho de resposta Server. Se ele estiver filtrado, você pode enviar uma requisição com o cabeçalho content__length (note dois sublinhados) e valor -1: se for 400, provavelmente é ELB ou outro WAF (veja abaixo).

Apache Traffic Server

O Apache Traffic Server é usado principalmente no Yahoo. Ele processa HTTP/2 de forma incomum: converte-o para HTTP/1.1 na memória e depois re-interpreta a requisição resultante. Assim, embora um cabeçalho tecnicamente possa ser "contrabandeado", não há como resultar em uma vulnerabilidade: você poderia enviar os mesmos bytes em uma conexão HTTP/1.1.

A maneira mais fácil de detectar se você está lidando com ATS (além do cabeçalho Server) é enviando uma requisição TRACE. Se um cabeçalho Max-Forwards: 0 estiver presente na requisição, o ATS retornará uma resposta para requisições TRACE por padrão sem encaminhá-la ao backend.

Microsoft IIS

Parece que o Microsoft IIS suporta decodificar codificação chunked dentro de corpos HTTP/2. Esse é um comportamento estranho; no entanto, é inofensivo do ponto de vista de segurança.

Para detectar se você está lidando com IIS, você pode enviar uma requisição com um cabeçalho "transfer-encoding:chunked" e um corpo chunked incorreto. Se você vir Microsoft-HTTPAPI ou algo assim no cabeçalho Server, é isso.

Outros WAFs

Os WAFs tentam detectar cabeçalhos suspeitos - é o trabalho deles. Às vezes, isso resulta na ferramenta dizendo "distinguível": o WAF pode bloquear algo como content_length:-1 e permitir content_length:1 apenas porque seus filtros acabam tomando essas decisões.

Se você vir um WAF no cabeçalho Server, provavelmente é um falso positivo.

Contatos

Se você tiver alguma ideia sobre este tópico, entre em contato comigo via @emil_lerner no Twitter ou @neexemil no Telegram - ou poste um problema aqui no GitHub.

Baixar ferramenta

Ambos os valores são inválidos do ponto de vista do frontend: há outro mecanismo para determinar o comprimento do corpo em HTTP/2, e nenhum corpo de requisição é realmente enviado em ambos os casos. Se as respostas forem diferentes, supomos que foi o servidor backend que parseou os cabeçalhos.

Este método é o menos confiável: o frontend pode emitir erros diferentes quando Content-Length tem um valor inválido e quando não corresponde ao comprimento real.