Um PDF pode conter malware? Como verificar antes de abrir

Os quatro marcadores que tornam um documento ativo em vez de estático, como lê-los à mão, e onde termina uma verificação em nível de bytes e começa um antivírus.

Pode. Um PDF não é uma imagem passiva de uma página. O formato consegue embutir JavaScript, declarar ações que rodam automaticamente na abertura, pedir ao leitor que execute programas externos e carregar arquivos inteiros dentro de si. Cada uma dessas capacidades se anuncia nos dicionários de objetos do arquivo, o que significa que você pode ler o que um documento pretende fazer antes que qualquer leitor o execute. Esta página mostra a verificação manual, o que cada marcador significa e a versão automatizada.

O escopo, dito com todas as letras. Uma verificação estrutural lê o que o documento pede ao leitor para fazer. Ela não decodifica cargas úteis, não emula JavaScript e não compara assinaturas de vírus. Isso é trabalho de antivírus, e as duas verificações respondem perguntas diferentes. "Este extrato bancário carrega JavaScript e uma ação de abertura automática" é um fato que vale agir, independentemente de algum scanner reconhecer a carga útil.

Quatro chaves de dicionário são toda a superfície ativa de um PDF, e as três primeiras se anunciam antes de qualquer leitor executar coisa alguma.
A CHAVE O QUE ELA PEDE AO LEITOR QUANDO ISSO ACONTECE /OpenAction uma ação disparada quando o documento abre antes de qualquer clique /JavaScript /JS executar o script embutido no arquivo na abertura ou num evento /Launch executar um programa externo ou abrir outro arquivo se o leitor aceitar o aviso /EmbeddedFile carregar um arquivo inteiro dentro do PDF quando alguém o extrai Presença não é malícia. Formulário de órgão público, nota fiscal eletrônica e portfólio usam exatamente estas mesmas chaves.

Historicamente, exploits de PDF também viveram em estruturas malformadas: fontes, imagens e fluxos construídos para derrubar um parser específico. Nada nesta página abre o arquivo: toda verificação lê bytes sem renderizá-los.

1. Como um PDF se torna ativo

Quatro chaves de dicionário transformam um documento estático em um que faz coisas:

  • /JavaScript e /JS: script embutido, executado pelos leitores que o suportam (o Acrobat suporta; a maioria dos visualizadores de navegador restringe bastante).
  • /OpenAction: uma ação executada automaticamente no instante em que o documento abre, antes de o usuário fazer qualquer coisa. O mecanismo clássico de entrega é uma OpenAction apontando para um JavaScript embutido.
  • /Launch: um pedido para executar um programa externo ou abrir outro arquivo. Leitores modernos avisam ou recusam, mas a intenção fica registrada no arquivo de todo jeito.
  • /EmbeddedFile. Um arquivo completo carregado dentro do PDF, de qualquer tipo, extraível pelo leitor.

Historicamente, exploits de PDF também viveram em estruturas malformadas : fontes, imagens e fluxos construídos para derrubar um parser específico. É exatamente por isso que nada nesta página envolve abrir o arquivo: toda verificação abaixo lê bytes sem renderizá-los.

2. Verificar à mão com o pdfid

A ferramenta padrão para a primeira olhada é o pdfid, de Didier Stevens: um pequeno script Python que conta os nomes interessantes de um arquivo sem fazer parsing, de propósito, para que um documento malformado não consiga explorar a própria ferramenta que o inspeciona:

Um arquivo que faz coisas ao ser aberto

$ pdfid.py extrato.pdf
 /JS                    1
 /JavaScript            1
 /OpenAction            1
 /Launch                0
 /EmbeddedFile          0

Contagens diferentes de zero em /JS, /JavaScript, /OpenAction ou /Launch são a deixa para olhar mais de perto (o pdf-parser.py, do mesmo autor, extrai os objetos de fato), ou simplesmente para não abrir o arquivo fora de um sandbox. Uma ressalva acompanha a abordagem de contagem: o pdfid casa os nomes em qualquer lugar dos bytes brutos, então um PDF sobre JavaScript (esta página impressa em PDF, por exemplo) pode gerar contagens a partir do próprio texto. A posição importa: um marcador só significa alguma coisa numa posição real de chave de dicionário, que é o que um parser estrutural verifica.

Os mesmos onze caracteres significam coisas opostas conforme a posição em que aparecem.
POSIÇÃO DE CHAVE << /Type /Action /S /JavaScript /JS (app.alert…) >> Isto o leitor executa. DENTRO DO TEXTO DA PÁGINA BT /F1 11 Tf (um PDF pode conter /JavaScript) Tj ET Isto é só uma palavra impressa. o pdfid conta os dois: ele casa nomes nos bytes brutos, sem fazer parsing um parser estrutural conta só o primeiro

O pdfid não faz parsing de propósito, para que um documento malformado não consiga explorar a ferramenta que o inspeciona. Essa classe de falso positivo é o preço dessa escolha, e ela é deliberada.

3. O que cada marcador significa num fluxo de documentos

O contexto decide a severidade. Num formulário distribuído por uma autoridade fiscal, JavaScript faz parte do pacote. Num extrato bancário, num holerite ou num comprovante de residência (documentos que são gerados, artefatos equivalentes a impressos), não há razão legítima para script ou uma ação de execução existir. Um marcador exige a sua própria ressalva: uma /OpenAction sozinha normalmente nem é conteúdo ativo. Na esmagadora maioria dos arquivos ela carrega um destino ("abrir na página 1, ajustar à largura"), que geradores comuns escrevem por rotina; quando em vez disso carrega um script, o marcador de JavaScript aparece junto. A pergunta "este PDF é perigoso?" e a pergunta "este PDF foi adulterado?" se sobrepõem aqui: conteúdo ativo num documento gerado é evidência de que algo além do gerador escreveu no arquivo.

A severidade acompanha o que o arquivo consegue fazer, e uma OpenAction sozinha quase nunca é conteúdo ativo.
O QUE O ARQUIVO PODE FAZER SEVERIDADE REPORTADA script embutido: /JavaScript, /JS média ação de execução: /Launch média arquivo embutido: /EmbeddedFile baixa /OpenAction que só carrega um destino info O contexto decide o resto. Num formulário de autoridade fiscal, script faz parte do pacote. Num extrato ou num holerite, não.

“Abrir na página 1, ajustar à largura” é o conteúdo típico de uma /OpenAction, e geradores comuns o escrevem por rotina. Quando ela carrega um script em vez de um destino, o marcador de JavaScript aparece junto.

4. Causas legítimas: a maioria dos PDFs ativos é inofensiva

Formulários interativos validam campos com JavaScript. PDFs de governo e de seguradoras preenchem datas sozinhos na abertura. Padrões de nota fiscal eletrônica (ZUGFeRD, Factur-X) anexam XML legível por máquina como arquivo embutido. Um /EmbeddedFile é o propósito do formato. Portfólios carregam documentos inteiros dentro de um PDF de capa. Por isso um contador de marcadores é uma ferramenta de triagem, não um veredicto: o achado é "este documento pede ao leitor que execute coisas", e se isso é normal depende inteiramente do que o documento afirma ser.

5. O que um antivírus acrescenta, e quando usar um

Uma verificação estrutural diz que existe uma carga útil; um scanner tenta dizer se essa carga é reconhecidamente hostil: casamento de assinaturas, heurísticas, às vezes detonação num sandbox. Para um arquivo que você recebeu pessoalmente e pretende abrir, o VirusTotal roda cerca de setenta motores e é o segundo passo certo (com a ressalva óbvia de que enviar documentos confidenciais a um multiscanner público é compartilhá-los). Para um pipeline que recebe documentos de clientes, as duas camadas respondem perguntas de negócio diferentes: o scanner protege a sua infraestrutura; a verificação estrutural protege a sua decisão: ela sinaliza que o extrato que carrega script não é o artefato que um banco gera, com ou sem assinatura reconhecida.

As duas camadas não são graus da mesma verificação: cada uma responde a uma pergunta que a outra não faz.
VERIFICAÇÃO ESTRUTURAL “o que este documento pede ao leitor para fazer?” lê bytes, não abre, não executa, não decodifica carga útil Protege a sua decisão. ANTIVÍRUS E MULTISCANNER “esta carga é reconhecidamente hostil?” casamento de assinaturas, heurísticas, às vezes sandbox Protege a sua infraestrutura. Nenhuma das duas responde a pergunta da outra, e nenhuma torna a outra dispensável. Ressalva do lado direito: enviar documento confidencial a um multiscanner público é compartilhá-lo.

6. Filtrar uploads automaticamente

A Tamperlens reporta conteúdo ativo como uma das suas dezenove famílias de sinais: active-content dispara com JavaScript, OpenAction, ações Launch e arquivos embutidos, trazendo as posições dos objetos como evidência. Ponderada pelo que o arquivo pode fazer: script e ações de execução pontuam média, anexos pontuam baixa, e uma OpenAction de navegação sozinha é reportada apenas como info. A detecção é restrita a posições genuínas de chave de dicionário em objetos analisados: um /JS que apenas aparece no texto de uma página não dispara, o que elimina a classe de falsos positivos que a contagem bruta de bytes carrega.

O motor nunca executa nem abre nada do que inspeciona: os documentos são lidos em memória como bytes, nenhum JavaScript roda, nenhum arquivo embutido é extraído, nada é gravado em disco. O mesmo POST devolve as outras dezoito famílias (histórico de revisões, divergências de metadados, cobertura de assinatura), então um pipeline de upload recebe a triagem de segurança e a triagem de adulteração num único relatório.

Verifique um PDF agora, de graça

Arraste um arquivo para o verificador da página inicial, sem conta, relatório completo incluindo conteúdo ativo. O arquivo é enviado por HTTPS, processado em memória e nunca gravado em disco, num servidor em Helsinque, na Finlândia (privacidade); nenhum JavaScript é executado e nenhum arquivo embutido é extraído. Quando quiser isso na sua pipeline, uma chave de API com 50 documentos por mês é gratuita: veja o guia da API ou crie uma conta.

A Tamperlens reporta sinais de risco, não veredictos de autenticidade, e não é um antivírus. Sinais podem ter causas legítimas; combine-os com a sua própria lógica de decisão.

Leitura relacionada