Malware e forense
Escreva uma regra YARA contra um arquivo de teste inofensivo
Escreva uma primeira regra YARA que case com um arquivo inofensivo e não com outro, e aprenda por que toda regra precisa de testes positivos e negativos.
Como hashes identificam arquivos, por que o SHA-256 substituiu o MD5, como o NSRL filtra softwares conhecidos e o risco de enviar arquivos ao VirusTotal.
Uma função de hash criptográfico recebe uma entrada de qualquer tamanho e devolve um valor de tamanho fixo, chamado digest. O SHA-256 sempre devolve 256 bits, que você lê como 64 caracteres hexadecimais. A mesma entrada sempre gera o mesmo digest. Se você alterar um único caractere, o digest muda por completo. O NIST define o Secure Hash Standard na FIPS 180-4, que cobre o SHA-256 e os demais algoritmos SHA, e diz que os digests servem para detectar se uma mensagem foi alterada.
Para quem faz análise, a ideia útil é simples. Um digest é um rótulo curto e repetível para uma sequência exata de bytes. Duas pessoas que calculam o hash do mesmo arquivo em máquinas diferentes devem obter o mesmo digest. Por isso os hashes aparecem em relatórios de incidentes, feeds de inteligência de ameaças e páginas de download de software.
Um hash identifica bytes, não um nome. Um arquivo chamado fatura.pdf e outro chamado setup.exe têm o mesmo digest se os bytes forem idênticos. Renomear um arquivo não muda o digest. O nome mostra como alguém chamou o arquivo. O digest mostra quais bytes você tem de fato.
O MD5 produz um digest de 128 bits e foi muito usado em checksums durante anos. Pesquisadores mostraram depois que o MD5 é vulnerável a ataques de colisão, ou seja, alguém pode montar duas entradas diferentes que geram o mesmo digest MD5. O SHA-1 tem um problema parecido, com outra construção.
Para um arquivo que você baixou por conta própria, uma colisão acidental é muito improvável. A preocupação é a colisão intencional. Um atacante que consegue fabricar um segundo arquivo com o mesmo digest pode trocá-lo pelo arquivo que você já confia, e o digest nos seus registros continua batendo. Quando colisões são práticas, um digest igual já não prova que os dois arquivos são o mesmo, e essa prova é justamente o que você precisa de um hash.
A regra de trabalho é direta. Use SHA-256 para identificação, para registros de evidência e para tudo o que talvez precise defender depois. Você ainda vai encontrar MD5 e SHA-1 em feeds antigos, ferramentas antigas e relatórios antigos. Trate esses valores como chaves de busca, e não como prova de que dois arquivos batem.
Um investigador não lê todos os arquivos de um disco. A primeira pergunta útil é quais arquivos já são conhecidos. A National Software Reference Library (NSRL), mantida pelo NIST, reúne softwares e cria perfis de arquivos que entram em um Reference Data Set (RDS). O RDS é uma coleção de assinaturas digitais de aplicações de software conhecidas e rastreáveis. Ele inclui hashes de softwares legítimos e também de algumas aplicações que podem ser maliciosas, como ferramentas de esteganografia e scripts de invasão. Investigadores usam esse conjunto para comparar arquivos de computadores apreendidos com perfis conhecidos, separando softwares de rotina dos arquivos que podem importar.
Conjuntos de hashes são um filtro, e respondem a uma pergunta estreita: este arquivo exato está no conjunto? Um arquivo que não está no conjunto pode ser uma ferramenta própria, um documento ou malware. Um arquivo que está no conjunto é um arquivo conhecido, o que não é a mesma coisa que um arquivo seguro. Um conjunto criado a partir de uma versão de um programa não vai bater com outra versão do mesmo programa.
Você pode montar uma versão pequena dessa mesma ideia para o seu ambiente. Calcule o hash dos arquivos que vêm em uma imagem limpa de notebook, guarde a lista com a versão e a data, e compare as máquinas novas com ela. O que não bater recebe uma segunda olhada. Essa comparação não prova nada por si só, mas reduz o trabalho aos arquivos que são diferentes.
A comparação de hashes é exata. Se um único byte muda, o digest muda. Isso leva a três regras.
Quando um digest bate com um valor conhecido como bom, os bytes são idênticos ao arquivo daquele conjunto. Isso é uma evidência forte sobre os bytes. Não diz o que o programa faz em execução, e os mesmos bytes podem se comportar de outro jeito com outra configuração ou outras entradas.
Quando um arquivo foi modificado, o digest não bate, mesmo que a mudança seja trivial. Um instalador recompilado, um binário com patch, um valor de configuração alterado ou um arquivo de texto salvo com outra quebra de linha geram um digest novo. A diferença mostra que os bytes são diferentes. Ela não mostra se a mudança é nociva ou inofensiva. Para decidir isso, você precisa de outro método.
Quando um digest bate com um valor conhecido como malicioso, você sabe que aquele arquivo exato já foi visto antes. Uma variante nova é outro arquivo, com outro digest, então uma lista de hashes maliciosos não a encontra. Uma busca sem resultados para uma amostra nova também não é um veredicto sobre ela.
Um mesmo programa também pode ter digests diferentes entre versões. O Bloco de Notas do Windows é um bom exemplo: o digest pode mudar de uma build do Windows para outra. Um hash sem a versão ao lado diz muito pouco, então registre a versão toda vez que registrar um digest.
O VirusTotal permite buscar um arquivo pelo hash. Você cola um SHA-256, MD5 ou SHA-1 na caixa de busca, e o site mostra uma página para qualquer arquivo que ele já conheça com aquele digest. Uma busca por hash envia o digest para o serviço. Ela não envia o arquivo.
Enviar é outra ação. A documentação do VirusTotal diz que qualquer usuário pode selecionar um arquivo do próprio computador e enviá-lo ao VirusTotal. Diz também que os relatórios de análise são compartilhados com a comunidade pública do VirusTotal, que o conteúdo de arquivos enviados pode ser compartilhado com clientes premium do VirusTotal e que os resultados básicos são compartilhados com quem enviou e entre os parceiros que examinam o arquivo.
Enviar é uma decisão de publicação. Depois que o arquivo sai da sua máquina, você não consegue desfazer isso e não controla quem recebe. Para uma amostra de malware público, compartilhar pode ajudar outros defensores. Para um arquivo com dados de cliente, um contrato não assinado, código-fonte de um cliente, um banco de senhas ou registros pessoais, compartilhar pode quebrar um contrato, violar a lei de proteção de dados e expor alguém que nunca concordou com isso.
A regra para trabalho de campo é curta. Nunca envie arquivos confidenciais ou de clientes ao VirusTotal nem a qualquer outro scanner público. Confira a política da sua empresa ou do seu cliente antes de enviar qualquer amostra para qualquer lugar. Se um digest é tudo o que você precisa, busque o digest. Se você precisa de um veredicto sobre uma amostra que não pode compartilhar, use uma ferramenta que você controla, como um sandbox local ou um serviço interno aprovado pela sua organização.
A busca por hash também tem consequências. O serviço recebe o digest, e o digest de um arquivo de cliente pode revelar o que você está procurando. Verifique a política para buscas por hash também, principalmente em um caso ativo.
Você precisa de um computador com terminal. Vai calcular o hash de programas do sistema e de um arquivo que você mesmo criar, e depois buscar um digest conhecido e inofensivo no VirusTotal. Não vai enviar nada. Use apenas arquivos da sua própria máquina.
No Linux, rode:
sha256sum /bin/lsNo macOS, rode:
shasum -a 256 /bin/lsNo Windows, abra o PowerShell e rode:
Get-FileHash C:\Windows\System32\notepad.exe -Algorithm SHA256No Windows com Git Bash, você também pode fazer a mesma verificação pelo terminal:
sha256sum /c/Windows/System32/notepad.exeNa máquina onde testamos este artigo, Windows 11 com Git Bash, estes foram os resultados observados:
$ sha256sum /bin/ls
b45981580702029cfeeffc8ca69e2a4d1e9c68914009e94c31ffec9cbc544aa5 */bin/lsAlgorithm : SHA256
Hash : 468FFE129C395ABF6B21A09EFDF261910A95FB98AA982EAD73CAA7B2B684577E
Path : C:\Windows\System32\notepad.exe$ sha256sum /c/Windows/System32/notepad.exe
468ffe129c395abf6b21a09efdf261910a95fb98aa982ead73caa7b2b684577e */c/Windows/System32/notepad.exeO digest do ls vem da cópia do ls que acompanha o Git Bash, então ele não vai bater com o ls do seu Linux ou macOS. O digest do Notepad é o mesmo nos dois shells, porque a única diferença é a capitalização das letras hexadecimais. Compare os digests sem diferenciar maiúsculas de minúsculas. Na mesma máquina, o Notepad também reportou a versão de arquivo 10.0.26100.9949 e tamanho de 360448 bytes. Anote isso ao lado do digest, porque outra build do Windows pode gerar outro digest para o mesmo nome de programa.
Rode isto no Git Bash ou em qualquer shell POSIX:
echo 'lab' > a.txt && sha256sum a.txt && echo 'lab.' > a.txt && sha256sum a.txtA saída observada foi:
b76025a9ca630b026d630d59a18cf414f5724d2bbf5dc4b11dd165c9c1ea8e01 *a.txt
d233123b7c71a1b7234066f700e03452959ce5bb0b4802f0cbd2c2437004a879 *a.txtA única mudança foi um ponto. Os dois digests têm 64 caracteres e não compartilham nenhum padrão visível. O comando echo também acrescenta uma quebra de linha, então o primeiro arquivo contém lab seguido de uma quebra, e o segundo contém lab. seguido de uma quebra. Você pode conferir os bytes exatos com od -c a.txt. Quebras de linha são um motivo comum para duas cópias do "mesmo texto" gerarem digests diferentes. Um arquivo salvo no Windows com quebras CRLF gera um digest diferente do mesmo texto salvo com LF.
Abra o navegador e vá até https://www.virustotal.com/gui/search/ seguido do SHA-256 do Notepad que você calculou no passo 1. Também dá para colar o digest na caixa de busca do site. Não arraste nenhum arquivo para a página e não clique em nenhum controle de envio.
Na nossa execução, o endereço de busca levou a uma página de arquivo para aquele digest, mas a página primeiro mostrou uma verificação reCAPTCHA. Não concluímos a verificação, então os resultados do relatório não aparecem neste artigo. Se quiser ver os resultados, conclua a verificação por conta própria. O VirusTotal pede isso para bloquear tráfego automatizado, e essa decisão cabe ao site, não a nós.
Quando a página carregar, anote quatro coisas:
Depois anote o que a página não diz. Um resultado sem detecções significa que nenhum mecanismo marcou aquele digest naquele momento. Não prova que o arquivo é seguro. A página também não diz nada sobre a sua cópia, a não ser que os digests batam, e não diz o que o programa faz quando roda.
Calcular o hash do arquivo errado. Um download pode ser copiado, renomeado ou convertido antes de você olhar para ele. Calcule o hash do arquivo exato que você está investigando, registre o caminho e a hora do cálculo, e confira se qualquer cópia tem o mesmo digest do original.
Tratar MD5 ou SHA-1 como prova. Use SHA-256 para identificação. Guarde digests antigos apenas como chaves de busca.
Ler um resultado limpo como seguro. Um digest sem detecções pode ser um malware novo, um malware direcionado ou um arquivo que nenhum mecanismo viu ainda. Limpo quer dizer "não marcado", e nada além disso.
Confiar no nome do arquivo. Nomes são fáceis de trocar. O identificador é o digest, e o nome é só um rótulo.
Enviar o arquivo para ver do que se trata. Esse é o erro que causa incidentes reais. Uma busca por hash responde à pergunta sobre um arquivo conhecido. Um envio publica o próprio arquivo.
Esquecer a versão. O mesmo nome de programa pode gerar vários digests. Registre a versão e a build ao lado de cada digest, senão o digest perde o sentido depois.
Calcule os digests de todos os arquivos de uma pasta e salve-os em um manifesto, para detectar mudanças depois. No Linux ou no macOS, rode sha256sum * > manifesto.txt dentro da pasta. Guarde o manifesto junto com a evidência e recalcule os digests depois para ver o que mudou. O comando é padrão, mas não o executamos no laboratório deste artigo, então confira a saída na sua máquina.
Leia a FIPS 180-4 para ver as definições exatas dos algoritmos SHA e os tamanhos de saída. Leia a página da NSRL para entender como um conjunto de dados de referência é montado e usado na prática. Leia a documentação do VirusTotal sobre como os envios são tratados antes de usar qualquer scanner público no seu trabalho.
O próximo passo é escrever uma regra de detecção contra um arquivo que você controla. O artigo Escreva uma regra YARA contra um arquivo de teste inofensivo mostra como casar padrões em vez de digests inteiros, o que cobre os casos que um hash exato não cobre.
Leitura relacionada: Criptografia, codificação e hash, comparados e o artigo anterior desta série, Primeira análise no Ghidra com um binário que você compila.
Malware e forense
Escreva uma primeira regra YARA que case com um arquivo inofensivo e não com outro, e aprenda por que toda regra precisa de testes positivos e negativos.