Una autopsia mostrará: resuelva un crackme ligero y escriba un generador de claves

Buen día, lector. Me gustaría contarles sobre el algoritmo para resolver un crackme ligero y compartir el código del generador. Este fue uno de los primeros crackme que resolví.



En la inmensidad de la red, se encontró nuestra cápsula. Esto es crackme . Naturalmente, es necesario estudiarlo. Para la autopsia necesitamos:



  • Un poco de ensamblador
  • Lógica con depurador (IDA PRO)


Hagamos una medicina con el veneno de la serpiente australiana usando Python. No perdamos tiempo.



imagen







Este crackme no es muy complicado. Considere el algoritmo para generar una clave en la clave correcta 8365-5794-2566-0817 . En IDA Pro, agregué comentarios sobre el código.



Examen del paciente



A primera vista, el comportamiento es normal. Extensión .Exe. No empacado. Empecemos.











¿Qué es? Requiere una llave. Necesito curar :)



Autopsia del paciente



Si había un error, había una inscripción "¡Fallo, la serie no es válida!". Tomemos un lugar donde se usa en el programa.







Vemos 1 función key_check_func antes de la rama condicional. Examinemosla.



Resulta un árbol interesante.







Establecemos un punto de interrupción y comenzamos a depurar.



La clave debe tener 19 caracteres.







Luego, el programa verifica la presencia de un guión en la clave cada 5 caracteres, ingresando al ciclo 3 veces.











Después de verificar la presencia de un guión, el programa examina si el bloque de teclas (tecla 1/4) consta de números. Existe una suposición para entender qué dígito se pasó al compilador que ejecuta el comando. add eax, 0FFFFFFD0h







Por ejemplo, agregue 8 (38h) con el número dado. El número resultante es demasiado grande ( 10000008h) y al final es 8, por lo tanto, se corta. Sigue siendo 8. Esta es la cifra que dimos. Esto sucede 4 veces en un ciclo.







¿Ahora que? Hoy en día, los códigos de cada dígito del bloque marcado se agregan entre sí, pero los últimos 4 dígitos se agregan 3 veces seguidas. La cantidad resultante se vuelve a sumar. El código del último dígito del bloque + el importe resultante es 150h. El resultado se agrega a r10d. Este ciclo completo se repite 4 veces para cada bloque de teclas.







En nuestro caso, considere el ejemplo del primer bloque de la clave 8365: 38h (8) + 33h (3) + 36h (6) + 35h (5) + 35h (5) + 35h (5) = 140h + 35h - 150h = 25h. 25 se agrega a r10d y se escribe en la memoria. Marquemos este lugar como A. La suma de otros bloques de la clave también es igual a 25h. Por lo tanto, multiplicamos 25h * 4 = 94.



A continuación, se produce un desplazamiento bit a bit a la derecha de 2 bytes. Marcaremos este lugar para nosotros como B.







Tenemos un valor designado como A (25h) y B (25h). Posteriormente, se compararán estos números. Deben ser iguales. Esta operación se produce para cada bloque de teclas.







Lo último que hace el programa es comprobar si los números de los bloques son similares. Primero, los dígitos del primer bloque se comparan con los dígitos del segundo bloque. Luego marque 2 bloques con 3 bloques. Verificación final 3 bloques con 4 bloques. Toda esta verificación no ocurre de inmediato, sino gradualmente en un ciclo.











Se acabó el análisis. El paciente ha sido estudiado.



Es hora de una cura



Usaremos algo inusual para generar la clave. Python + biblioteca aleatoria.

El código en sí está a continuación. Comentarios en el código:



import random

def gen_key_part():
    #  
    num1 = str(random.randint(0, 9))
    num2 = str(random.randint(0, 9))
    num3 = str(random.randint(0, 9))
    num4 = str(random.randint(0, 9))

    #    (1 )
    final = num1 + num2 + num3 + num4
    return final

def sum_ord(key_part):
    #      
    num1 = key_part[0]
    num2 = key_part[1]
    num3 = key_part[2]
    num4 = key_part[3]

    #    crackme
    sum = ord(num1) + ord(num2) + ord(num3) + ord(num4) + ord(num4) + ord(num4)
    sum_final = ord(num4) + sum - 336
    return sum_final

def shr(key):
    #    
    a = key[0:4]
    b = key[5:9]
    c = key[10:14]
    d = key[15:19]

    #      crackme
    x = sum_ord(a) + sum_ord(b) + sum_ord(c) + sum_ord(d)
    x = x >> 2
    return x

def check_key(key):
    i = 0 # 
    while i != 4:
        #  i    1  4.      
        first = 0 + i
        second = 5 + i
        third = 10 + i
        four = 15 + i

        #           ( ,  A  B)
        if sum_ord(key[0:4]) != shr(key) or sum_ord(key[5:9]) != shr(key) or sum_ord(key[10:14]) != shr(key) or sum_ord(key[15:19]) != shr(key):
            return False

        #     
        if int(key[first]) == int(key[second]):
            return False
        if int(key[second]) == int(key[third]):
            return False
        if int(key[third]) == int(key[four]):
            return False
        i += 1 # #  

def generate_key():
    #  
    key = gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part()

    #     true  false
    while True: #
        if check_key(key) == False:
            #     
            key = gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part() + '-' + gen_key_part()
            print('Checking this key -> ' + key)
        else:
            #  
            print('This is the correct key -> ' + key)
            break


#  ,  
if __name__ == "__main__":
    generate_key()



Lanzamos.







Ingrese la clave y vea.







El paciente está curado.



Gracias por la atención. Espero sus comentarios y críticas. No te enfermes.



All Articles