Maior do que diz: encontrando uma bomba de descompressão no cabeçalho de um PNG

Engenharia Reversa & Exploração Binária Nível 3/4 ~4 min 25 de setembro de 2026

O desafio

Toda noite às 02h00 o gerador de miniaturas cai em um único arquivo e derruba o pool de workers inteiro. O arquivo tem 46 KB em disco, é um PNG válido, abre no navegador, e o log de upload o registra como um ícone de 64 por 64. Nada no tamanho em disco explica uma máquina ficando sem memória. Um PNG carrega as dimensões em pixels no cabeçalho, à vista de todos, muito antes de um decodificador tocar nos dados comprimidos. Leia as dimensões no dump e informe a largura real. Os oito primeiros bytes estão destacados, passar o cursor em qualquer byte mostra o offset e o caractere ASCII, e a referência de assinaturas abaixo do dump nomeia cada chunk.

O que você vai aprender

  • Localizar um chunk dentro de um PNG pelo seu tipo ASCII de quatro letras
  • Ler um inteiro big-endian de 4 bytes em um hex dump
  • Explicar por que o tamanho do arquivo em disco não diz nada sobre o tamanho decodificado
  • Reconhecer uma bomba de descompressão como um ataque de recursos, não um arquivo malformado
  • Separar metadados escritos por uma ferramenta da estrutura sobre a qual um decodificador atua

Habilidades testadas

Análise de formato binárioLeitura de hex dumpRaciocínio sobre negação de serviço

Pré-requisitos

  • Conversão de hexadecimal para decimal
  • O que é um cabeçalho de arquivo

Como funciona

Um PNG é uma assinatura seguida por uma sequência de chunks, e todo chunk tem o mesmo formato: um comprimento de 4 bytes, um tipo ASCII de 4 bytes, os dados, e depois um checksum de 4 bytes. Essa regularidade é o que permite navegar por um dump sem um parser. Ache as quatro letras que nomeiam um chunk e você sabe exatamente onde os dados dele começam.

O primeiro chunk é sempre IHDR, e seus primeiros oito bytes são a largura e a altura, cada uma um inteiro big-endian de 32 bits. Big-endian significa que o byte mais significativo é escrito primeiro, então 00 00 75 30 é 0x7530 e não 0x3075. Todo decodificador lê esses oito bytes antes de qualquer outra coisa, porque precisa alocar o buffer de saída antes de poder descomprimir os dados nele.

Essa alocação é o ataque. Tamanho comprimido e tamanho decodificado não têm relação: uma única cor chapada em uma tela enorme comprime para poucos kilobytes e se expande para gigabytes. Qualquer serviço que aceita uma imagem, verifica que o upload é pequeno, e depois a entrega a uma biblioteca já perdeu, porque a biblioteca dimensiona seu buffer a partir do cabeçalho, e o cabeçalho é controlado pelo atacante.

Erros comuns

  • Responder 64. O 64x64 visível na coluna ASCII vive em um chunk de comentário tEXt. É uma anotação, e o log de upload a copiou sem olhar o cabeçalho.
  • Responder 20000. Essa é a altura. A largura vem primeiro no IHDR.
  • Ler os bytes em little-endian. Inteiros de PNG são big-endian, então 00 00 75 30 é 30000, não 807534592.
  • Começar a contar no offset 8. Os offsets 8 a 11 são o comprimento do chunk e 12 a 15 são o tipo. A largura começa no offset 16.
  • Ler o chunk pHYs. Ele guarda pixels por metro, que é resolução, não tamanho.

Como se proteger

Decida se deve decodificar a partir do cabeçalho, antes de decodificar.

  • Faça o parse do IHDR você mesmo e rejeite qualquer coisa acima de um orçamento de pixels. O total de pixels importa mais do que qualquer dimensão isolada: 30000 por 20000 são 600 megapixels, e um limite de 50 megapixels teria barrado isso na porta.
  • Configure os limites que sua biblioteca de imagens já oferece. A maioria delas expõe uma contagem máxima de pixels e recusa arquivos grandes demais se você ativar isso.
  • Faça o trabalho em um processo com um limite rígido de memória, para que um arquivo ruim mate um worker em vez do pool inteiro, e nunca na thread da requisição.
  • Trate todo chunk de texto como decoração não confiável. As dimensões registradas no momento do upload devem vir do seu próprio parse, não de um comentário no arquivo.

Solução completa

Membros Pro e Max desbloqueiam o passo a passo completo.

Assinar Pro

Estatísticas da comunidade

128 resoluções
84% taxa de sucesso
Malekith Primeiro sangue

Hacks de hoje relacionados

32.000+ Hackers Labs reais Grátis
Comece Grátis ou resolva o hack de hoje, sem conta