Identifica o tipo de criptografia (MD5, SHA-256) de uma string.

Contexto

Um Hash é o resultado de uma função matemática que transforma qualquer volume de dados em uma string de comprimento fixo. No Pentest, você raramente encontrará senhas em texto claro; você encontrará hashes. O objetivo deste módulo é:

  • Identificar o Algoritmo: Determinar se a string é um MD5, SHA-1, SHA-256, etc.
  • Direcionar o Ataque: Saber o tipo de hash é obrigatório para configurar ferramentas de quebra como John the Ripper ou Hashcat.
  • Análise de Segurança: Identificar se a aplicação usa algoritmos obsoletos e vulneráveis (como MD5 ou SHA-1) que sofrem de colisões.

Possibilidades de Implementação

  • Análise por Comprimento e Caracteres: A forma mais rápida. Cada algoritmo gera uma string com um número específico de caracteres (ex: MD5 sempre tem 32 caracteres hexadecimais).
  • Expressões Regulares (Regex): Utilizar padrões para validar se a string contém apenas caracteres permitidos pelo algoritmo (geralmente [a-f0-9]).
  • Assinaturas Específicas: Identificar "salts" ou prefixos comuns em sistemas específicos (como o prefixo $6$ para SHA-512 no Linux).

Código

Este módulo utiliza a biblioteca nativa re (Regular Expressions) para validar a estrutura da string informada

import re

def identify_hash(hash_string):
    """
    Analisa o comprimento e o padrão de uma string para identificar o provável algoritmo de hash.
    """
    hash_string = hash_string.strip()
    length = len(hash_string)

    # Dicionário de padrões: { "Algoritmo": r"Regex" }
    patterns = {
        "MD5": r"^[a-fA-F0-9]{32}$",
        "SHA-1": r"^[a-fA-F0-9]{40}$",
        "SHA-224": r"^[a-fA-F0-9]{56}$",
        "SHA-256": r"^[a-fA-F0-9]{64}$",
        "SHA-384": r"^[a-fA-F0-9]{96}$",
        "SHA-512": r"^[a-fA-F0-9]{128}$",
        "MySQL v4.1+": r"^\*[a-fA-F0-9]{40}$",
        "BCrypt": r"^\$2[ayb]\$.{56}$"
    }

    print(f"[*] Analisando hash: {hash_string}")
    print(f"[*] Comprimento detectado: {length} caracteres")

    found = False
    for name, pattern in patterns.items():
        if re.match(pattern, hash_string):
            print(f"[!] POSSÍVEL ALGORITMO: {name}")
            found = True

    if not found:
        print("[-] Não foi possível identificar o algoritmo com precisão.")

def main():
    print("=" * 60)
    print("Módulo: Hash Identifier | Projeto: 30 Lessons in Python")
    print("=" * 60)

    # Exemplos de teste
    hashes_to_test = [
        "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8", # SHA-256
        "79c2b4643f4201191028e925408d25e6",                               # MD5
        "$2y$12$D9v1uA.R/tN0XmQzI8GvHeXz8pL3zV.yYm9X8QzI8GvHeXz8pL3zV"      # BCrypt
    ]

    for h in hashes_to_test:
        identify_hash(h)
        print("-" * 30)

if __name__ == "__main__":
    main()

Observações

  • Colisões de Comprimento: Alguns hashes têm o mesmo tamanho (ex: NTLM e MD5 possuem 32 caracteres). Nesses casos, a ferramenta deve listar ambos como possíveis.
  • Hashes com Salt: Algoritmos modernos como Argon2 ou BCrypt incluem informações extras na string, tornando a identificação via Regex muito mais precisa.
  • Valor Arquitetural: Em seu projeto, destaque que a identificação é apenas o primeiro passo; o passo seguinte seria o uso de tabelas Rainbow Tables ou ataques de dicionário para encontrar a senha original.