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
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.