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 Axioplase ıɥs∀ (site web personnel) . Évalué à 4 (+2/-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.
[^] # Re: Rigolo.
Posté par desktop.ready . Évalué à 1 (+0/-0).
Oui je pourrais faire cela mais c'est beaucoup moins rigolo que de trouver une phrase qui ait du sens et qui permet de tomber sur le checksum qui va bien.
# Réutilise la roue
Posté par flagos . Évalué à 3 (+2/-1).
Si je devais vérifier que rien a été changé, je me baserai juste sur git, c'est fait pour ça.
Mais bon, j'ai bien compris qu'il s'agit d'un exercice.
[^] # Re: Réutilise la roue
Posté par desktop.ready . Évalué à 4 (+3/-0).
Ben l'idée c'est que c'est le programme qui se vérifie lui-même.
Si c'est toi qui doit vérifier et que tu as le code source de départ, un simple "diff" avec le code source de départ suffit, pas besoin de git…
[^] # Re: Réutilise la roue
Posté par flagos . Évalué à 1 (+0/-1).
La différence, subtile, entre diff et git diff, c'est que git t'assure que les checksum des commits et de leur changements matchent l'arborescence que tu as localement. Git fait la vérification que tu cherches, tout seul.
Petit bonus : tu peux même utiliser la signature des commits et vérifier dans ton programme que tous les commits utilisent bien la où les clés que tu connais. Comme ca un attaquant qui fait son commit localement il est contré.
# du coup
Posté par bubar🦥 (Mastodon) . Évalué à 4 (+1/-0). Dernière modification le 02 octobre 2024 à 20:38.
S'il a été modifié il continue de se tester lui même en disant qu'il n'a pas été modifié ? Ou bien une enclave est prévue pour cette fonction ? Je sais pas moi, au hasard hein : peut être une puce d'architecture Arc dans le southbridge contenant la fonction et la clé privée ?
[^] # Re: du coup
Posté par desktop.ready . Évalué à 1 (+0/-0).
Le but c'est que le programme détecte lui-même qu'il a été modifié.
Donc si tu modifies le script (en ajoutant un commentaire par exemple) et exécutes le script que j'ai donné, la vérification va renvoyer un résultat faux.
À partir de là, tu fais ce que tu veux avec le résultat.
# Mais aussi : les quines
Posté par cg . Évalué à 9 (+7/-0).
C'est sans doute le moment de s'intéresser aux Quines, ces programmes qui affichent leur code.
Exemple extrème de quine polyglotte : quine-relay :).
# toto découvre les DRM
Posté par Krunch (site web personnel) . Évalué à 0 (+0/-2).
L'article wikipedia correspondant est https://en.wikipedia.org/wiki/Anti-tamper_software
Les articles connexes sur le cracking ainsi que les archives de phrack (en particulier à partir du numéro 49) peuvent peut-être t'intéresser (bon c'est plutôt orienté attaques évidemment). J'apprécie en particulier la section Notable payloads de l'article Wikipedia sur la Copy Protection.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
[^] # Re: toto découvre les DRM
Posté par desktop.ready . Évalué à 2 (+1/-0).
Oui j'en ai parlé dans la deuxième phrase de ce journal…
C'est un exercice rigolo, pas une tentative de faire un programme impossible à hacker.
# Signature
Posté par barmic 🦦 . Évalué à 3 (+1/-0).
À première vue je partirais sur une signature. J'incorpore dans le programme la clé publique (par exemple en base64) et j'append à la fin du fichier la signature. Le programme s'occupe de scinder les 2 et de vérifier l'un avec l'autre.
Mais évidemment ça se fait casser facilement parce que l'on ne peux pas s'assurer que la vérification elle-même n'est pas compromise sans un tier
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Signature
Posté par aiolos . Évalué à 3 (+1/-0).
En java, il est de bon ton qu'un provider de sécurité (ou JCE = Java Cryptography Extension) soit signé, et son intégrité vérifiée au chargement. C'est documenté ici : https://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/HowToImplAJCEProvider.html#MutualAuth
[^] # Re: Signature
Posté par Axioplase ıɥs∀ (site web personnel) . Évalué à -1 (+0/-3).
Ça n'a aucune sécurité !
1. Modifie le code
2. Calcule la nouvelle signature
3. Colle la nouvelle signature à la fin du code.
[^] # Re: Signature
Posté par barmic 🦦 . Évalué à 3 (+2/-1).
C'est quoi que tu n'a pas compris dans
?
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
# Challenge accepté
Posté par JulienPalard . Évalué à 1 (+0/-0).
Ma version, inspirée des checksums IP qui calculent leur checksum en mettant leur checksum à zéro :
[^] # Re: Challenge accepté
Posté par barmic 🦦 . Évalué à 2 (+0/-0).
Je ne suis pas sûr de comprendre comment le checksum est mis à 0 ?
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Challenge accepté
Posté par Chris K. . Évalué à 2 (+0/-0). Dernière modification le 04 octobre 2024 à 08:20.
Effectivement s'arrêter avant les 4 dernières ligne ne change rien par rapport à ta méthode. Il manque juste 3 lignes à la fin en plus.
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.