Depois do Último Byte: Encontrando um Arquivo Grampeado em uma Imagem
O desafio
Uma caixa de recrutamento recebeu um currículo com uma foto de perfil anexada. O gateway checou o anexo, encontrou uma imagem válida, gerou uma miniatura para a fila de moderação e deixou passar. A miniatura está correta. O arquivo não: um decodificador JPEG para em um marcador de dois bytes específico e ignora tudo o que vem depois, e este arquivo continua por mais sessenta e sete bytes. Leia o que foi grampeado no fim e diga o nome do arquivo que ele carrega. Os 217 bytes estão abaixo, os quatro primeiros estão destacados, e é a coluna ASCII à direita que entrega este arquivo, sem decodificar nada.
O que você vai aprender
- Reconhecer o marcador de fim de imagem do JPEG e o que os decodificadores fazem com ele
- Identificar uma segunda assinatura de arquivo dentro de um único arquivo
- Localizar o nome de uma entrada ZIP a partir do layout do cabeçalho local do arquivo
- Explicar por que um arquivo pode ser dois formatos válidos ao mesmo tempo
- Descrever a diferença entre validar um arquivo e identificá-lo
Habilidades testadas
Pré-requisitos
- Leitura de hexadecimal e ASCII lado a lado
- O que é uma assinatura de arquivo
Como funciona
A maioria dos formatos é interpretada do início e para quando diz que terminou. O JPEG é uma sequência de marcadores que termina em FF D9, e todo decodificador trata isso como o fim do arquivo, independentemente de quantos bytes restam. O ZIP é o contrário: um leitor começa pela cauda, encontra o registro de fim do diretório central e segue os offsets de volta para dentro do arquivo.
Coloque um ZIP depois do FF D9 de um JPEG e os dois parsers ficam satisfeitos com os mesmos bytes. Um visualizador de imagens renderiza uma foto, uma ferramenta de arquivamento lista uma entrada, e nenhum dos dois está sendo enganado. O arquivo realmente é os dois. Renomear a extensão já é suficiente para trocar qual dos dois você recebe.
Os gateways caem nessa por causa da pergunta que fazem. Validar que um anexo é um JPEG bem formado retorna um sim sincero, e uma miniatura prova isso. Identificar o arquivo significa perguntar o que mais existe ali, o que exige ler até o fim em vez de parar onde o primeiro formato diz para parar.
Erros comuns
- Responder ZIP ou arquivo compactado. O formato é como você encontra a resposta, não a resposta. O rótulo pede um nome.
- Ler o nome no início do cabeçalho PK. Trinta bytes de campos vêm antes. Comece a contar a partir da assinatura e a coluna ASCII vai mostrar onde o texto começa.
- Assumir que o arquivo está corrompido. As duas partes são estruturalmente válidas, e é exatamente por isso que ele passou.
- Parar na miniatura. A imagem é real e renderiza corretamente. Ela está ali para ser vista.
Como se proteger
Inspecione o arquivo inteiro, não apenas a parte que o primeiro parser diz ser o arquivo todo.
- Compare o tamanho declarado da imagem com o tamanho no disco. Bytes finais depois do
FF D9já são um achado por si só e custam apenas uma comparação para detectar. - Recodifique as imagens enviadas no lado do servidor em vez de armazenar o que chegou. Decodificar e recodificar descarta tudo o que o decodificador ignorou, incluindo o arquivo anexado.
- Escaneie os anexos por toda assinatura presente, não só a do offset zero, e trate um segundo contêiner como um evento de quarentena.
- Não confie na extensão nem no tipo MIME informado pelo remetente. Os dois são apenas rótulos, e os bytes aqui contradizem ambos.