Journal Programme qui se vérifie lui-même pour voir s'il a été modifié

Posté par  . Licence CC By‑SA.
Étiquettes :
4
2
oct.
2024

Je vous propose un challenge intéressant avec un début de réponse: comment écrire un programme qui se teste lui-même pour savoir s'il n'a pas été modifié.
(bien sûr cela ne compte pas d'utiliser la date de modification du fichier)

Bien entendu "cela ne peut pas marcher car on peut toujours modifier le programme pour enlever l'étape de vérification" et le sujet a sans doute été maintes fois abordés de manière bien plus complexe par ceux qui luttent contre le piratage ou la tricherie.

Mais j'ai trouvé l'idée rigolote d'essayer d'inclure un checksum du code dans le code lui-même.

J'ai donc implémenté cela en utilisant l'algorithme Luhn mod N et cela donne ça en Python 3:

import argparse, string

def GenerateCheckCharacter(codepoints, text):
    factor = 2
    summation = 0
    n = len(codepoints)

    for i in range(len(text)-1, -1, -1):
        codePoint = codepoints.index(text[i])
        addend = factor * codePoint
        factor = 1 if (factor == 2) else 2
        addend = int(addend / n) + (addend % n)
        summation += addend

    remainder = summation % n
    checkCodePoint = (n - remainder) % n

    return codepoints[checkCodePoint]

def ValidateCheckCharacter(codepoints, text):
    factor = 1
    summation = 0
    n = len(codepoints)

    for i in range(len(text)-1, -1, -1):
        codePoint = codepoints.index(text[i])
        addend = factor * codePoint
        factor = 1 if (factor == 2) else 2
        addend = int(addend / n) + (addend % n)
        summation += addend

    remainder = summation % n
    return (remainder == 0)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Luhn mod N algorithm demonstration')
    parser.add_argument('--codepoints', type=str, nargs='?', default = string.printable, help='Verify file')
    parser.add_argument('--generate', type=str, nargs='?', default = None, help='Generate check character to add at the end of the file')
    parser.add_argument('--verify', type=str, nargs='?', default = None, help='Verify file')
    args = parser.parse_args()

    if args.generate:
        filename = args.generate
    elif args.verify:
        filename = args.verify
    else:
        filename = __file__

    with open(filename) as fp:
        text = fp.read()[:-1]

    if args.generate:
        character = GenerateCheckCharacter(args.codepoints, text)
        print(f"Character to add at the end of the file: '{character}' (character code {args.codepoints.index(character)})")
    else:
        character = text[-1]
        print(f"Character found at the end of the file: '{character}' (character code {args.codepoints.index(character)})")
        print(f"File is verified: {ValidateCheckCharacter(args.codepoints, text)}")

    print("Script ended successfully")
    # <

Vous pouvez donc voir le "checksum" à la fin du code. Notez bien que j'enlève le vrai dernier caractère (retour à la ligne) pour l'algorithme.
Si on modifie le code, le "checksum" va changer et la vérification ne marchera plus.

Ce que je n'ai pas réussi à faire, c'est de me passer d'ajouter ce dernier caractère.
Normalement le dernière caractère c'est un retour à ligne et si on est malin on peut modifier astucieusement le dernier print pour que le "checksum" corresponde exactement à un retour à la ligne.

J'image qu'il faut tenter une approche "brute-force" en générant des phrases autour de variations ("Script ended perfectly", "Script executed without issues", "No errors detected", etc.). Mais pour l'instant cela dépasse mes compétences, mais si vous voulez tenter…
Ce serait vraiment rigolo car cela rendrait vraiment le programme assez mystérieux pour les non-initiés.

Voilà, j'ai trouvé cet algorithme Luhn Mod N assez sympathique et je souhaitais partager cela avec vous.
Peut-être que vous avez d'autres algorithmes dans ce genre pour la même utilisation ?

  • # Rigolo.

    Posté par  (site web personnel) . Évalué à 3 (+1/-0).

    On peut rajouter des espaces, tabs, du dead code partout pour changer le checksum.
    C'est souvent comme ca que les attaques de collision sont generees.

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.