Une autopsie montrera: Résolvez un crackme léger et écrivez un générateur de clé

Bonne journée, lecteur. Je voudrais vous parler de l'algorithme pour résoudre un crackme léger et partager le code du générateur. Ce fut l'un des premiers crackme que j'ai résolu.



Dans l'immensité du réseau, notre pod a été trouvé. C'est crackme . Naturellement, il est nécessaire de l'étudier. Pour l'autopsie, nous avons besoin de:



  • Un peu d'assembleur
  • Logique avec dĂ©bogueur (IDA PRO)


Faisons un médicament à partir du venin du serpent australien en utilisant Python. Ne perdons pas de temps.



image







Ce crackme n'est pas très compliqué. Considérez l'algorithme pour générer une clé sur la clé correcte 8365-5794-2566-0817 . Dans IDA Pro, j'ai ajouté des commentaires sur le code.



Examen du patient



À première vue, le comportement est normal. Extension .Exe. Pas emballé. Commençons.











Qu'Est-ce que c'est? Nécessite une clé. Besoin de guérir :)



Autopsie du patient



S'il y avait une erreur, il y avait une inscription «Fail, Serial is invalid!». Prenons un endroit où il est utilisé dans le programme.







Nous voyons 1 fonction key_check_func avant la branche conditionnelle. Examinons-la.



Un arbre intéressant s'avère.







Nous définissons un point d'arrêt et commençons le débogage.



La clé doit comporter 19 caractères.







Ensuite, le programme vérifie la présence d'un tiret dans la clé tous les 5 caractères, entrant dans la boucle 3 fois.











Après avoir vérifié la présence d'un tiret, le programme examine si le bloc de touches (1/4 clé) se compose de chiffres. Il y a une hypothèse pour comprendre quel chiffre a été transféré au compilateur pour exécuter la commande add eax, 0FFFFFFD0h







Par exemple, ajoutez 8 (38h) avec ce nombre. Le nombre résultant est trop grand ( 10000008h) et à la fin est 8, par conséquent, il est coupé. Reste 8. C'est le chiffre que nous avons donné. Cela se produit 4 fois dans un cycle.







Maintenant quoi? De nos jours, les codes de chaque chiffre du bloc coché sont ajoutés les uns aux autres, mais les 4 derniers chiffres sont ajoutés 3 fois de suite. Le montant résultant est à nouveau additionné. Le code du dernier chiffre du bloc + le montant résultant est 150h. Le résultat est ajouté à r10d. Ce cycle entier est répété 4 fois pour chaque bloc clé.







Dans notre cas, considérons l'exemple du premier bloc de la clé 8365: 38h (8) + 33h (3) + 36h (6) + 35h (5) + 35h (5) + 35h (5) = 140h + 35h - 150h = 25h. 25 est ajouté à r10d et écrit en mémoire. Marquons cet endroit comme A. La somme des autres blocs de la clé est également égale à 25h. Par conséquent, nous multiplions 25h * 4 = 94.



Ensuite, un décalage au niveau du bit vers la droite de 2 octets se produit. Nous marquerons cet endroit pour nous-mêmes comme B.







Nous avons une valeur désignée comme A (25h) et B (25h). Par la suite, ces chiffres seront comparés. Ils doivent être les mêmes. Cette opération se produit pour chaque bloc clé.







La dernière chose que fait le programme est de vérifier si les nombres dans les blocs sont similaires. Tout d'abord, les chiffres du 1er bloc sont comparés aux chiffres du 2e bloc. Puis vérifiez 2 blocs avec 3 blocs. Contrôle final 3 blocs avec 4 blocs. Toute cette vérification ne se fait pas immédiatement, mais progressivement dans un cycle.











L'analyse est terminée. Le patient a été étudié.



Il est temps de guérir



Nous allons utiliser quelque chose d'inhabituel pour générer la clé. Python + Bibliothèque aléatoire.

Le code lui-mĂŞme est ci-dessous. Commentaires dans le code:



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()



Nous lançons.







Entrez la clé et voyez.







Le patient est guéri.



Merci pour l'attention. J'attends vos commentaires et critiques avec impatience. Ne sois pas malade.



All Articles