Cryptographic/Compression Algorithms
Last updated
Last updated
Aprenda e pratique Hacking AWS:Treinamento HackTricks AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: Treinamento HackTricks GCP Red Team Expert (GRTE)
Se você se deparar com um código usando deslocamentos à direita e à esquerda, xors e várias operações aritméticas, é altamente provável que seja a implementação de um algoritmo criptográfico. Aqui serão mostradas algumas maneiras de identificar o algoritmo usado sem precisar reverter cada etapa.
CryptDeriveKey
Se esta função for usada, você pode descobrir qual algoritmo está sendo usado verificando o valor do segundo parâmetro:
Consulte aqui a tabela de algoritmos possíveis e seus valores atribuídos: https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id
RtlCompressBuffer/RtlDecompressBuffer
Comprime e descomprime um buffer de dados fornecido.
CryptAcquireContext
De documentação: A função CryptAcquireContext é usada para adquirir um identificador para um contêiner de chave específico dentro de um provedor de serviços criptográficos (CSP) específico. Este identificador retornado é usado em chamadas para funções CryptoAPI que usam o CSP selecionado.
CryptCreateHash
Inicia o processo de hash de um fluxo de dados. Se esta função for usada, você pode descobrir qual algoritmo está sendo usado verificando o valor do segundo parâmetro:
Consulte aqui a tabela de algoritmos possíveis e seus valores atribuídos: https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id
Às vezes é muito fácil identificar um algoritmo graças ao fato de que ele precisa usar um valor especial e único.
Se você pesquisar pela primeira constante no Google, é isso que você obtém:
Portanto, você pode assumir que a função decompilada é um calculador sha256. Você pode pesquisar qualquer uma das outras constantes e obterá (provavelmente) o mesmo resultado.
Se o código não tiver nenhuma constante significativa, pode estar carregando informações da seção .data. Você pode acessar esses dados, agrupar o primeiro dword e pesquisar no Google como fizemos na seção anterior:
Neste caso, se você procurar por 0xA56363C6, você pode descobrir que está relacionado às tabelas do algoritmo AES.
É composto por 3 partes principais:
Estágio de inicialização/: Cria uma tabela de valores de 0x00 a 0xFF (256 bytes no total, 0x100). Esta tabela é comumente chamada de Caixa de Substituição (ou SBox).
Estágio de embaralhamento: Irá percorrer a tabela criada anteriormente (loop de 0x100 iterações, novamente) modificando cada valor com bytes semi-aleatórios. Para criar esses bytes semi-aleatórios, a chave RC4 é usada. As chaves RC4 podem ter entre 1 e 256 bytes de comprimento, no entanto, geralmente é recomendado que seja acima de 5 bytes. Comumente, as chaves RC4 têm 16 bytes de comprimento.
Estágio XOR: Por fim, o texto simples ou cifrado é XORado com os valores criados anteriormente. A função para criptografar e descriptografar é a mesma. Para isso, um loop pelos 256 bytes criados será executado quantas vezes forem necessárias. Isso é geralmente reconhecido em um código decompilado com um %256 (mod 256).
Para identificar um RC4 em um código de desmontagem/decompilado, verifique 2 loops de tamanho 0x100 (com o uso de uma chave) e em seguida um XOR dos dados de entrada com os 256 valores criados anteriormente nos 2 loops, provavelmente usando um %256 (mod 256)
Uso de caixas de substituição e tabelas de pesquisa
É possível distinguir o AES graças ao uso de valores específicos de tabela de pesquisa (constantes). Observe que a constante pode ser armazenada no binário ou criada dinamicamente.
A chave de criptografia deve ser divisível por 16 (geralmente 32B) e geralmente um IV de 16B é usado.
É raro encontrar algum malware usando, mas existem exemplos (Ursnif)
Fácil de determinar se um algoritmo é Serpent ou não com base em seu comprimento (função extremamente longa)
Na seguinte imagem, observe como a constante 0x9E3779B9 é usada (observe que esta constante também é usada por outros algoritmos criptográficos como TEA -Tiny Encryption Algorithm). Observe também o tamanho do loop (132) e o número de operações XOR nas instruções de desmontagem e no exemplo de código:
Como mencionado anteriormente, este código pode ser visualizado dentro de qualquer decompilador como uma função muito longa pois não há saltos dentro dela. O código decompilado pode se parecer com o seguinte:
Portanto, é possível identificar este algoritmo verificando o número mágico e os XORs iniciais, vendo uma função muito longa e comparando algumas instruções da função longa com uma implementação (como o deslocamento à esquerda por 7 e a rotação à esquerda por 22).
Mais complexo do que algoritmos simétricos
Não há constantes! (implementações personalizadas são difíceis de determinar)
KANAL (um analisador de criptografia) falha em mostrar dicas sobre RSA, pois depende de constantes.
Na linha 11 (esquerda) há um +7) >> 3
que é o mesmo que na linha 35 (direita): +7) / 8
A linha 12 (esquerda) está verificando se modulus_len < 0x040
e na linha 36 (direita) está verificando se inputLen+11 > modulusLen
3 funções: Inicializar, Atualizar, Finalizar
Funções de inicialização semelhantes
Inicializar
Você pode identificar ambos verificando as constantes. Note que o sha_init tem 1 constante que o MD5 não tem:
Transformação MD5
Observe o uso de mais constantes
Menor e mais eficiente, pois sua função é encontrar alterações acidentais nos dados
Usa tabelas de pesquisa (para que você possa identificar constantes)
Verifique as constantes da tabela de pesquisa:
Um algoritmo de hash CRC se parece com:
Constantes não reconhecíveis
Você pode tentar escrever o algoritmo em Python e procurar por coisas semelhantes online
O gráfico é bastante extenso:
Verifique 3 comparações para reconhecê-lo: