O clique que você nunca deu: encontrando o /OpenAction em um PDF malicioso
O desafio
O financeiro encaminhou uma fatura de fornecedor e o gateway de e-mail colocou o arquivo em quarentena. O primeiro reflexo é verificar se a extensão está mentindo sobre o arquivo, e desta vez ela não está: a assinatura é honesta, isto é mesmo um PDF. O problema está mais adiante. O dicionário de catálogo no topo do arquivo declara duas coisas que uma fatura comum não tem motivo algum para carregar. Uma delas apenas informa que há um script anexado, e um leitor cuidadoso ainda pediria confirmação antes de executá-lo. A outra é a chave que entrega o controle a esse script no instante em que o documento é aberto, sem que ninguém clique em nada. Leia a coluna ASCII e diga o nome dessa segunda chave.
O que você vai aprender
- Ler o cabeçalho de um PDF e confirmar que uma assinatura é genuína
- Localizar o dicionário de catálogo e suas chaves em uma visualização hexadecimal bruta
- Diferenciar /OpenAction de /JavaScript e explicar por que apenas uma delas é o achado
- Explicar por que uma assinatura de arquivo honesta não prova nada sobre o comportamento de um documento
- Nomear as chaves irmãs que produzem o mesmo efeito (/AA e /Launch)
Habilidades testadas
Pré-requisitos
- Leitura de um dump hexadecimal com coluna ASCII
- Noção básica de assinatura de arquivo
Como funciona
Um PDF é um conjunto de objetos numerados. O primeiro que o leitor carrega é o catálogo, marcado como /Type /Catalog, e ele descreve o que o documento é e o que deve acontecer com ele.
Entre as chaves que um catálogo pode carregar está /OpenAction. Ela aponta para uma ação que o leitor executa automaticamente no instante em que o documento é aberto. Ela existe por motivos legítimos: pular para um destino nomeado, definir o nível de zoom, tocar um som. Ela também aceita uma ação cujo tipo é /S /JavaScript.
Esse é todo o truque. /JavaScript descreve o que é o payload. /OpenAction decide quando ele roda. Um arquivo que carrega apenas a primeira precisa que um humano clique em algo. Um arquivo que carrega as duas não precisa de nada.
A assinatura é irrelevante para isso. %PDF- no offset 0 está correta aqui, e é exatamente por isso que verificar apenas a assinatura é um controle fraco: o arquivo não está fingindo ser outra coisa, ele é honestamente um PDF que honestamente pede para executar código.
Erros comuns
- Responder /JavaScript. É genuinamente suspeito, mas sozinho só significa que há um script anexado. Formulários interativos trazem script que dispara com um clique e nunca toca em nada. É o gatilho, não o payload, que torna isso automático.
- Procurar uma assinatura forjada. Os primeiros oito bytes parecem os de qualquer outro desafio de tipo de arquivo, então o instinto é compará-los com a lista de referência e parar por aí. Aqui eles batem, e bater é o ponto.
- Passar os olhos pelo painel hexadecimal em vez da coluna ASCII. Todo o dicionário de objeto é texto imprimível. Ler a coluna da direita é mais rápido do que decodificar bytes à mão.
- Supor que um leitor sempre vai pedir confirmação. Alguns leitores pedem confirmação antes de executar script do documento, muitos leitores mais antigos e embarcados não pedem, e um painel de pré-visualização de e-mail é o pior caso.
Como se proteger
A correção não é bloquear PDFs. É parar de tratar uma assinatura válida como um veredito.
- Faça parsing, não sniffing. Pontue os anexos pela estrutura de objetos.
/OpenAction,/AA,/Launch,/EmbeddedFilee/RichMediaem uma fatura recebida já valem quarentena sozinhos. - Desative o script de documento no leitor que você implanta, e desligue o painel de pré-visualização para e-mail externo, para que abrir seja sempre um ato deliberado.
- Achate na ingestão. Renderizar um PDF recebido em imagens, ou reconstruí-lo através de um sanitizador, remove toda chave de ação e mantém a fatura legível.
- Alerte sobre a combinação. Uma única chave de script é ruidosa sozinha;
/OpenActionresolvendo para uma ação/JavaScripté um sinal de alta confiança que vale a pena acionar um alerta.