O Cabeçalho DEX: Identificando um Executável Dalvik Disfarçado de PNG
O desafio
Uma amostra de malware mobile foi entregue como icon.png dentro dos assets de um app, mas nunca aparece como imagem. Abra-a no visualizador hexadecimal, compare os primeiros bytes com as assinaturas de referência e digite o tipo real do arquivo.
O que você vai aprender
- Reconhecer os magic bytes do DEX 64 65 78 0A ('dex\n') e o campo de versão que os segue
- Ler os bytes iniciais como ASCII para identificar um formato pela sua assinatura imprimível
- Explicar por que o Android carrega código pelo cabeçalho DEX, e não pela extensão do arquivo
- Diferenciar DEX de PNG, ELF e ZIP usando suas assinaturas distintas
- Tratar arquivos com nomes de imagem dentro dos assets do app como possíveis esconderijos de código
Habilidades testadas
Pré-requisitos
- Familiaridade básica com apps Android distribuídos como arquivos APK
- Facilidade para converter bytes hexadecimais em seus caracteres ASCII
Como funciona
Apps Android são distribuídos como APKs (que são, eles mesmos, arquivos ZIP), e o código compilado da aplicação vive dentro de um arquivo .dex - um executável Dalvik. Todo DEX começa com um magic fixo: os bytes 64 65 78 0A formam dex seguido de uma quebra de linha, e os quatro bytes seguintes (30 33 35 00 aqui) são a string de versão 035 terminada por um null. Esse cabeçalho de oito bytes é como o runtime reconhece o bytecode que pode carregar.
O arquivo neste desafio se chama icon.png, o que sugere uma imagem, mas um PNG de verdade começa com 89 50 4E 47. Os bytes reais são o magic do DEX, então o nome é um disfarce deliberado. Como o Android (e as ferramentas de qualquer analista) identifica código executável pelo cabeçalho, e não pela extensão, colocar bytes de DEX dentro de um icon.png esconde o payload à vista dentro dos assets de um app, mantendo-o carregável.
A lista de referência inclui deliberadamente formatos binários parecidos. 7F 45 4C 46 é ELF (binários Linux/nativos), 50 4B 03 04 é o container ZIP/APK, e 89 50 4E 47 é o PNG que ele finge ser. Apenas a assinatura 64 65 78 0A corresponde a um executável Dalvik.
Erros comuns
- Confiar na extensão .png. O nome promete uma imagem, mas o cabeçalho é a fonte da verdade e ele não é um PNG.
- Confundir DEX com ELF. Ambos são formatos executáveis, mas o ELF começa com
7F 45 4C 46('\x7fELF'), não64 65 78 0A. - Ler apenas o hexadecimal e ignorar o ASCII. A coluna ASCII mostra
dexdiretamente, que é o indício mais rápido. - Responder 'APK' ou 'ZIP'. O app que contém o arquivo pode ser um APK/ZIP, mas o cabeçalho deste arquivo específico é um DEX puro, não um ZIP (
50 4B 03 04).
Como se proteger
Defensores mobile devem classificar cada asset pelo seu conteúdo real e tratar arquivos com formato de código em locais que não são de código como um sinal de alerta.
- Escaneie o conteúdo do APK com um detector de tipo baseado em conteúdo e sinalize qualquer magic de DEX encontrado fora das entradas
classes*.dexesperadas. - Alerte sobre arquivos com extensão de imagem (
.png,.jpg) dentro deassets/oures/raw/cujos magic bytes sejam de formatos executáveis. - Bloqueie o carregamento dinâmico de código a partir dos assets do app onde a plataforma permitir, e audite qualquer uso de
DexClassLoader. - Mantenha uma baseline de assinaturas conhecidas como boas para que payloads DEX renomeados ou anexados se destaquem durante a revisão.