
Variedade de algoritmos de hash usados em malware
O HashDB é uma biblioteca de algoritmos de hash de origem comunitária usados em malware.
O HashDB pode ser usado como uma biblioteca de hash independente, mas também alimenta o HashDB Lookup Service mantido pela OALabs. Esse serviço permite que analistas revertam hashes e recuperem nomes de API e valores de string com hash.
O HashDB pode ser clonado e usado em seus scripts de engenharia reversa como qualquer módulo Python padrão. Segue um exemplo de código.
>>> import hashdb
>>> hashdb.list_algorithms()
['crc32']
>>> hashdb.algorithms.crc32.hash(b'test')
3632233996
A OALabs mantém um HashDB Lookup Service gratuito que pode ser usado para consultar uma tabela de hash para qualquer hash listado na biblioteca do HashDB. As tabelas de hash incluem o conjunto completo de APIs do Windows, além de muitas strings comuns usadas em malware. Você pode até adicionar suas próprias strings!
O serviço de consulta do HashDB possui um plugin para IDA Pro que pode ser usado para automatizar consultas de hash diretamente pelo IDA! O cliente pode ser baixado do GitHub aqui.
O HashDB depende do apoio da comunidade para manter nossa biblioteca de hashes atualizada! Nosso objetivo é que os colaboradores gastem no máximo cinco minutos adicionando um novo hash, do primeiro commit ao PR. Para alcançar esse objetivo, oferecemos o seguinte processo simplificado.
Certifique-se de que o algoritmo de hash ainda não existe… sabemos que parece óbvio, mas apenas verifique novamente.
Crie um branch com um nome descritivo.
Adicione um novo arquivo Python ao diretório /algorithms com o nome do seu algoritmo de hash. Tente usar o nome oficial do algoritmo ou, se ele for exclusivo, use o nome do malware ao qual ele é exclusivo.
Use o seguinte modelo para configurar seu novo algoritmo de hash. Todos os campos são obrigatórios e diferenciam maiúsculas de minúsculas.
#!/usr/bin/env python
DESCRIPTION = "your hash description here"
# Type can be either 'unsigned_int' (32bit) or 'unsigned_long' (64bit)
TYPE = 'unsigned_int'
# Test must match the exact hash of the string 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
TEST_1 = hash_of_string_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
def hash(data):
# your hash code here
Revise seu estilo Python; usamos Flake8 no Python 3.9. Você pode testar os seguintes comandos de lint localmente a partir da raiz do repositório git.
pip install flake8
flake8 ./algorithms --count --select=E9,F63,F7,F82 --show-source --statistics
Teste seu código localmente usando nossa suíte de testes. Execute os seguintes comandos localmente a partir da raiz do repositório git. Observe que você deve executar o pytest como um módulo, em vez de diretamente, caso contrário ele não detectará nosso diretório de testes.
pip install pytest
python -m pytest
Abra um pull request — seu novo algoritmo será automaticamente colocado na fila de testes e, se for bem-sucedido, será mesclado.
É isso! Além de seu novo hash estar disponível na biblioteca do HashDB, uma nova tabela de hash será gerada para o HashDB Lookup Service e você poderá começar a reverter hashes imediatamente!
PRs com alterações fora do diretório /algorithms não fazem parte do nosso CI automatizado e serão submetidos a uma análise extra.
Todos os hashes devem ter uma descrição válida no campo DESCRIPTION.
Todos os hashes devem ter um tipo unsigned_int ou unsigned_long no campo TYPE. O HashDB atualmente só aceita hashes unsigned de 32 ou 64 bits.
Todos os hashes devem ter o hash da string ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 no campo TEST_1.
Todos os hashes devem incluir uma função hash(data) que aceite uma string de bytes e retorne um hash da string.
Alguns algoritmos de hash fazem o hash do nome do módulo e da API separadamente e combinam os hashes para criar um único hash de módulo+API. Um exemplo disso é o hash ROR13 do Metasploit padrão. Esses algoritmos não funcionam com a wordlist padrão e exigem uma wordlist personalizada que inclua tanto o nome do módulo quanto a API. Para lidar com isso, permitimos algoritmos personalizados que só retornam um hash válido para algumas palavras.
Adicionar um hash de API personalizado requer os seguintes componentes adicionais.
O campo TEST_1 deve ser definido como 4294967294 (-1).
O algoritmo de hash deve retornar o valor 4294967294 para todos os hashes inválidos.
Um campo adicional TEST_API_DATA_1 deve ser adicionado com uma palavra de exemplo válida para o algoritmo.
Um campo adicional TEST_API_1 deve ser adicionado com o hash do campo TEST_API_DATA_1.
Um grande agradecimento à equipe FLARE pelo trabalho com o shellcode_hashes. Há muitos anos, este projeto definiu o padrão para reversão rápida e fácil de hashes de malware e ainda é uma ferramenta extremamente útil. Então, por que duplicá-lo?
Francamente, tudo se resume à wordlist e à acessibilidade. Vimos uma mudança drástica em direção ao uso de hashes para todos os tipos de strings em malware atualmente, e o método antigo de aplicar hash a todas as exportações de DLLs do Windows simplesmente não é mais suficiente. Queríamos uma solução que pudesse processar continuamente milhões de chaves e valores de registro, nomes de arquivos e nomes de processos. E queríamos que esses dados estivessem disponíveis por meio de uma API REST para que pudéssemos usá-los em nossos fluxos de automação, não apenas em nossas ferramentas de análise estática. Dito isso, não existiríamos sem o shellcode_hashes, então crédito onde o crédito é devido 🙌