- Um operador de blog pessoal envia um Zip Bomb baseado em gzip como resposta HTTP para bots maliciosos, a fim de reduzir varreduras de vulnerabilidades, spam e raspagem de conteúdo
- Aproveitando o fluxo de Accept-Encoding: gzip, deflate usado por navegadores e crawlers legítimos, ele retorna
200 OK e Content-Encoding: gzip para requisições suspeitas
- Um arquivo gzip de 1 MB se expande para cerca de 1 GB ao ser descompactado, e um de 10 MB para cerca de 10 GB, fazendo muitos bots esgotarem a memória ou interromperem a requisição
- O middleware do servidor verifica IPs em blacklist e padrões de spam e, quando encontra uma correspondência, envia um arquivo Zip Bomb pré-gerado e encerra o processamento da requisição
- Não é uma defesa completa, porque pode ser facilmente detectada e contornada, mas é suficiente para bloquear bots simples que atrapalham o servidor com crawling indiscriminado
Tráfego de bots e o contexto do uso de Zip Bomb
- A maior parte do tráfego web vem de bots, e há usos legítimos como leitores de RSS, crawlers de mecanismos de busca e bots de IA em busca de conteúdo novo
- O problema são os bots maliciosos operados por spammers, raspadores de conteúdo e hackers
- Em um antigo emprego, bots encontraram vulnerabilidades no WordPress e inseriram scripts maliciosos no servidor
- Esse servidor depois passou a fazer parte de uma botnet usada para DDoS
- Um dos primeiros sites foi completamente removido da busca do Google por causa de spam gerado por bots
- Depois dessas experiências, ele passou a usar Zip Bombs para proteger o servidor contra bots maliciosos
Como transformar compressão gzip em mecanismo de defesa
- Um Zip Bomb é um arquivo compactado pequeno que, durante a descompactação, se expande para um arquivo muito grande e sobrecarrega a máquina
- No início da web, a compressão gzip foi adotada para reduzir o volume de dados transmitidos em conexões lentas
- Reduzir um arquivo HTML de 50 KB para 10 KB economizava 40 KB de transferência
- Na internet discada, isso podia reduzir o tempo de download da página de 12 para 3 segundos
- Ao fazer uma requisição, o navegador informa por cabeçalhos quais métodos de compressão ele suporta
Accept-Encoding: gzip, deflate
- Se o servidor também oferecer suporte à compressão, ele retorna a versão compactada dos dados esperados
- Bots de web crawling também suportam compressão como gzip para coletar grandes volumes de dados, e essa característica é usada como defesa
Resposta enviada para requisições maliciosas
- Bots que varrem vulnerabilidades de segurança aparecem com frequência no blog, e a maioria é simplesmente ignorada
- Quando uma requisição parece tentar injetar entrada maliciosa ou sondar respostas, ele envia uma resposta gzip junto com
200 OK
Content-Encoding: gzip
- O tamanho do arquivo enviado varia entre 1 MB e 10 MB, dependendo da situação
- Um arquivo de 1 MB cresce para cerca de 1 GB ao ser descompactado
- Um arquivo de 10 MB cresce para cerca de 10 GB ao ser descompactado
- O bot vê o cabeçalho, conclui que é um arquivo compactado e tenta descompactá-lo para inspecionar o conteúdo
- À medida que o arquivo continua se expandindo, ele esgota a memória e o servidor ou script pode travar
- Para scripts persistentes em que 1 MB não basta, ele envia um arquivo de 10 MB, e afirma que nesse caso o script encerra imediatamente
Exemplo de criação do Zip Bomb e aplicação no servidor
- Ao criar um Zip Bomb, é preciso assumir o risco de travar ou danificar o próprio dispositivo
- Um arquivo gzip que se descompacta em 10 GB pode ser gerado com o seguinte comando
dd if=/dev/zero bs=1G count=10 | gzip -c > 10GB.gz
- A composição do comando é a seguinte
dd: comando para copiar ou converter dados
if=/dev/zero: usa como entrada um arquivo especial que gera um fluxo infinito de bytes zero
bs=1G: define o tamanho do bloco como 1 GB
count=10: processa 10 blocos de 1 GB para gerar 10 GB de dados zero
gzip -c > 10GB.gz: compacta os dados de saída com gzip e salva no arquivo 10GB.gz
- Nesse caso, o arquivo resultante tem cerca de 10 MB
- No servidor, foi adicionado um middleware que verifica se a requisição atual é maliciosa
- É mantida uma blacklist de IPs que fazem varreduras repetidas em todo o site
- Também são usados para detecção padrões em que alguém deixa spam e depois volta para verificar se ele apareceu na página
if (ipIsBlackListed() || isMalicious()) {
header("Content-Encoding: gzip");
header("Content-Length: ". filesize(ZIP_BOMB_FILE_10G)); // 10 MB
readfile(ZIP_BOMB_FILE_10G);
exit;
}
- O custo é que, em certas situações, o servidor precisa transmitir um arquivo de 10 MB
- Quando um texto viraliza, ele reduz para um arquivo de 1 MB, que segundo ele também funciona
Limitações e escopo de uso
- Zip Bomb não é uma defesa completa
- Pode ser facilmente detectado
- Também pode ser contornado
- O cliente pode ler apenas parte do conteúdo
- Ainda assim, é suficiente como ferramenta para bloquear bots pouco sofisticados que fazem crawling sem critério e atrapalham o servidor
- Um exemplo do funcionamento pode ser visto em um replay dos logs do servidor: this replay of my server logs
1 comentários
Opiniões do Hacker News
Por volta de 2001, eu tinha uma linha fixa em casa e hospedava várias coisas em uma máquina Linux doméstica
Por causa de uma atualização do Windows NT, muitos sistemas passaram a ativar um recurso de criptografia oportunista que primeiro se conectava a uma determinada porta para negociar s/wan e depois tentava enviar tráfego TCP; eu via esse tipo de tráfego com frequência no firewall, então não dei muita importância
Mas uma máquina específica continuava tentando se conectar a cada poucos segundos, o que ficou muito irritante, e tentei entrar em contato com o administrador, sem sucesso
No fim, avisei algo como “vou iniciar um novo serviço nessa porta e espero que isso não cause problemas”; como não houve resposta, subi nessa porta um servidor que lia de
/dev/urandom, ativavaTCP_NODELAYe afins, e empurrava dados aleatórios o mais rápido possívelA máquina NT mal configurada se conectava, bebia dados aleatórios por uns 5 segundos e sumia; 5 minutos depois voltava, tomava outra dose de buffer overflow e sumia de novo. Esse padrão se repetiu por algumas semanas, até ela desaparecer completamente da internet
Às vezes imagino algum administrador coçando a cabeça, tentando entender por que a máquina NT não parava de reiniciar
Toda requisição deve ter tanto um limite de tempo quanto um limite para a quantidade de dados a consumir
Então criei um PDF de 100 páginas em que todas as páginas eram um grande retângulo preto e o enviei pelo então novo gateway de e-mail para fax; recebi uma ligação furiosa em menos de uma hora, e os faxes pararam
A parte “tentei falar com o administrador da máquina e isso era comum” é especialmente interessante
Depois que deixei o domínio expirar, esse RPi morria a cada 5 minutos e achei que fosse problema de energia; só mais tarde lembrei daquela tarefa CRON
Em milhares de casos, o próprio motivo de rodar esse tipo de serviço em uma máquina NT era “para não precisar de administrador”, e isso não deve ser subestimado
Nos anos 90 e início dos anos 2000, coloquei muitos servidores na internet, e a prática padrão em todo o setor era usar NT para funcionar sem administrador
Quando eu era criança, fiz uma bobagem de brincadeira e coloquei
ln -s /dev/zero index.htmlno meu siteOs navegadores da época não lidavam bem com isso e praticamente travavam; às vezes derrubavam até o sistema do cliente junto
Mais tarde, acho que os navegadores começaram a verificar o conteúdo real e a interromper essas requisições
Só consegui abri-lo finalmente anos depois
squashfs, com cabeçalhos adequados, colocar um conteúdo infinito sem tags de fechamento e fazer o servidor não informar o tamanho do arquivo antes do downloadAlguma ideia?
favicon.icoque derrubava navegadoresAcho que era este: https://freedomhacker.net/annoying-favicon-crash-bug-firefox...
/dev/zipbombHoje em dia, quase todos os navegadores aceitam zstd e brotli, então esse tipo de bomba pode ser ainda mais eficaz agora
This comentário antigo mostrava uma taxa de compressão impressionante de 1,2M:1, e zstd seems to be doing even better
Só que bots talvez não suportem padrões modernos de compressão
Por outro lado, isso pode ser uma boa forma de bloquear bots: como todos os navegadores modernos suportam zstd, aplicar isso à força a user agents de navegadores que não estejam na lista de permissões pode confundir scrapers automaticamente
Ele depende muito de fazer streaming da visão completa do usuário a cada interação, e com brotli sobre SSE é fácil obter taxa de compressão de 200:1[2]
O problema é que um agente malicioso pode solicitar um stream sem compressão
Como brotli é suportado por 98% dos navegadores, não envio dados para clientes que não suportem compressão brotli; muitos scrapers e bots também não a suportam, então isso funciona bastante bem
[1] demo checkboxes
https://checkboxes.andersmurphy.com
[2] artigo sobre brotli SSE
https://andersmurphy.com/2025/04/15/why-you-should-use-brotl...
Isso acontece porque, na primeira geração de gzip, o próprio bloco de dados
0comprimido tem baixa entropia, e zst aninhado reduz um arquivo de 10G para 99 bytesNão quero testar pessoalmente
Embora a parte sobre bots encontrando vulnerabilidades no WordPress e colocando scripts maliciosos no servidor fuja um pouco do tema, é divertida
Fiquei até mais tranquilo ao descobrir que não sou o único a ver um shell PHP ser implantado magicamente no servidor 1 hora depois de instalar o WordPress
Nunca são menos de 3; é sempre garantido
Mesmo que não seja na primeira hora, no momento em que você esquecer um patch, uma hora vai estourar
/wp-loginIsso também acaba sendo uma boa forma de encontrar bots; se vejo um IP pedindo caminhos relacionados a CMS famosos, jogo direto no buraco do iptables
Quando eu dizia “implante seu primeiro servidor nginx hello world”, logo começavam a aparecer requisições estranhas nos logs
Já fiz algo parecido com ssh: descobri uma forma de matar clientes ssh que tentavam adivinhar a senha do root
O preço foi que vários script kiddies passaram a lançar DDoS contra meu pequeno servidor, então acabei mudando para uma abordagem de identificar agentes claramente mal-intencionados e bloquear seus IPs com regras de firewall
Só que, no IPv6, isso está ficando mais difícil
Se você cria suas próprias páginas web, também pode colocar uma zip bomb na página por meio de um link invisível aos olhos humanos
Algo como texto branco em fundo branco, um anchor sem destaque em hover/click; o bot vai baixar e verificar, e crawlers e scrapers de IA também
O problema eram bots muito simples que vagavam pela web enviando spam tosco para todos os formulários que parecessem poder ser publicados
No começo, adicionei um CAPTCHA simples com letras distorcidas, o que bloqueou muitos bots, mas não todos
Pelos logs do servidor, vi que esses bots faziam rapidamente só três requisições: a página com o formulário, a imagem do CAPTCHA e o POST dos dados do formulário; não carregavam CSS nem JS
Então coloquei mais alguns campos no formulário e os escondi com CSS; se qualquer coisa fosse enviada nesses campos, a requisição falhava e a sessão era bloqueada
Além disso, transformei a imagem do CAPTCHA em um fundo CSS e troquei o
srcpor uma imagem transparente; o spam parou completamente e usuários reais não perceberam nadahttps://github.com/skeeto/endlessh
Entre os dois, parece até mais fácil
Zip bombs são divertidas
Certa vez encontrei uma vulnerabilidade em um produto de segurança que fazia com que ele não realizasse corretamente a varredura de malware em arquivos zip acima de certo tamanho, ou em arquivos que os contivessem
Na prática, se você colocasse uma zip bomb dentro de um documento Office XML, esse produto podia deixar passar o arquivo OOXML mesmo que ele contivesse malware facilmente identificável
Implantei isso no lugar do script de honeypot que eu costumava usar, mas não parece estar funcionando bem
Pelos logs do servidor web, os bots não baixam todo o veneno de 10 MB; eles interrompem em vários tamanhos
Até agora, não vi nenhum pegar mais do que cerca de 1,5 MB
Ou será que está funcionando? Talvez eles estejam decodificando em streaming na hora e morrendo
Por exemplo, se o log registrou que ele leu 1,5 MB, pode ter travado ao decodificar isso na memória, na hora, para 1,5 GB
Não há como confirmar
Algo como conteúdo gerado infinitamente, com um monte de referências para outras páginas geradas
Pode ajudar contra
wgetsimples e bots até eles se adaptaremSó acrescentando: eu estou do lado dos bots, mas não me importo de ajudar
Imagino que alguns bots tenham limites rígidos para o tamanho dos recursos que baixam
Como muitos deles são bots irritantes de treinamento/raspagem para LLM, mesmo que uma zip bomb de 800 KB não os mate, ainda pode desperdiçar os recursos computacionais deles
Vale apontar que isso não é um arquivo zip clássico, e sim uma gzip bomb
Não é o método de derrubar antivírus com zips aninhados; funciona como uma página web comum compactada
Há algum tempo, parte da infraestrutura de circumvenção de censura do Tor Project era operada no mesmo site do post de blog sobre zip bombs[0]
Um daqueles arquivos zip foi rastreado pelo Google e entrou em uma lista de domínios maliciosos, o que quebrou uma parte bem importante da ferramenta Snowflake do Tor
Levou semanas para resolver[1]
[0] https://www.bamsoftware.com/hacks/zipbomb/
[1] https://www.bamsoftware.com/hacks/zipbomb/#safebrowsing
Para proteger os uploads da minha aplicação, criei partições temporárias de disco de tamanho fixo, com cerca de 10 MB cada, e descompactava os arquivos nelas
Se alguém enviasse algo grande demais, o dano ficava confinado ali dentro
unzip -p | head -c 10MB