Décrypter un fichier dont on a oublié la méthode de chiffrement utilisée

Décrypter un fichier dont on a oublié la méthode de chiffrement utilisée
Ça peut arriver à tout le monde (je n'ai pas fait ce tuto par hasard :D) de trouver sur son disque dur un fichier que l'on a chiffré nous-même, mais dont on a oublié la méthode avec laquelle on l'a chiffré. Autrement dit, pour déchiffrer ce fichier il manque :
- Le mot de passe
- La méthode de chiffrement (des ou blowfish par exemple)
La méthode très artisannale vue ici permet de bruteforcer via une sorte d'attaque par dictionnaire le fichier pour le rendre lisible. Pour l'instant, j'utilise un script perl qui ne fonctionne que pour les chiffrements symmétriques, mais il est sûrement possible d'étendre les fonctionnalités de ce script dans le futur. Le vrai but de ce programme est d'utiliser en chaine la fonction de déchiffrement de openssl avec des mots de passes probables.
Attention : il ne s'agit pas ici d'un tuto de “hacking” car pour utiliser cette méthode, vous avez plus ou moins besoin de vous souvenir du mot de passe utilisé pour chiffrer le fichier.
Les préparatifs
Mettons que le fichier à décrypter soit nommé “fichierChiffré”. Le script perl qui j'ai écrit est disponnible en pièce jointe. Il pourra être amélioré dans ke futur.
Il faut dans un premier temps indiquer à ce script, basé sur openssl, les différentes méthodes de chiffrement existantes. Pour cela, on récupère le dernier paragraphe de la sortie de la commande “openssl help”, qui devrait dessembler à ça :
Cipher commands (see the `enc' command for more details) aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb aes-256-cbc aes-256-ecb base64 bf bf-cbc bf-cfb bf-ecb bf-ofb camellia-128-cbc camellia-128-ecb camellia-192-cbc camellia-192-ecb camellia-256-cbc camellia-256-ecb cast cast-cbc cast5-cbc cast5-cfb cast5-ecb cast5-ofb des des-cbc des-cfb des-ecb des-ede des-ede-cbc des-ede-cfb des-ede-ofb des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb des-ofb des3 desx rc2 rc2-40-cbc rc2-64-cbc rc2-cbc rc2-cfb rc2-ecb rc2-ofb rc4 rc4-40 seed seed-cbc seed-cfb seed-ecb seed-ofb zlib
La première étape consiste donc à copier/coller dans un fichier que l'on nomme “types.txt” ce paragraphe ci-dessus, à l'exception de la première ligne (Cipher commands blablabla.). “types.txt” doit être placé au même endroit que le fichier à déchiffrer et que le script perl. Je le laisse également en pièce jointe au cas où le format change un jour.
Execution
Avant d'executer le script, il faut lui renseigner les mots de passes probables : on effectue ici une attaque par dictionnaire, il faut donc créer ce dictionnaire ! Ouvrez le script perl avec un éditeur de texte, et indiquez à la ligne suivante les mots de passes que vous avez l'habitude d'utiliser, ceux qui sont susceptibles d'avoir chiffré le fichier.
(@PASSES)=();
Cette ligne doit se trouver dans les alentours de la ligne 14 du fichier et doit être écrite de la forme (avec autant de mots de passe que l'on désire) :
(@PASSES)=(“monmotdepasse1”,”0000”,”superman”);
Si le mot de passe contient des caractères spéciaux, ajouter un '\' devant. Exemple : "J\'aimeLes\$"
Pour lancer le script de decryptage (je parle ici de décryptage et non de déchiffrement puisqu'on ne connait pas la méthode de chiffrement) :
perl decryptage.pl fichierChiffré sortie
fichierCrypté est bien évidemment le fichier à décrypter, et sortie est le nom du dossier (sera créé si inexistant) dans lequel seront générées les tentatives de déchiffrement.
L'opération est assez rapide, il m'a fallu moins de 1 seconde pour 450 tentatives de déchiffrement. Les tentatives sont visibles dans le dossier de sortie indiqué au lancement du script :
$ ls sortie/ z0 z11 z121 z133 z145 z157 z26 z38 z5 z61 z73 z85 z97 z1 z110 z122 z134 z146 z158 z27 z39 z50 z62 z74 z86 z98 z10 z111 z123 z135 z147 z16 z28 z4 z51 z63 z75 z87 z99 z100 z112 z124 z136 z148 z17 z29 z40 z52 z64 z76 z88 z101 z113 z125 z137 z149 z18 z3 z41 z53 z65 z77 z89 z102 z114 z126 z138 z15 z19 z30 z42 z54 z66 z78 z9 z103 z115 z127 z139 z150 z2 z31 z43 z55 z67 z79 z90 z104 z116 z128 z14 z151 z20 z32 z44 z56 z68 z8 z91 z105 z117 z129 z140 z152 z21 z33 z45 z57 z69 z80 z92 z106 z118 z13 z141 z153 z22 z34 z46 z58 z7 z81 z93 z107 z119 z130 z142 z154 z23 z35 z47 z59 z70 z82 z94 z108 z12 z131 z143 z155 z24 z36 z48 z6 z71 z83 z95 z109 z120 z132 z144 z156 z25 z37 z49 z60 z72 z84 z96
Il est intéressant de remarquer que tout le script est basé sur l'utilisation de openssl (voir à la fin du script). On y remarque la commande suivante dans une double boucle for (pour chaque mot de passe / pour chaque type de chiffrement):
system("openssl $type -d -k $pass -in $input -out $output/z$i 2>/dev/null");
system permet de lancer une ligne de commande de votre shell, l'option “-d” signifie qu'il faut déchiffrer, et non chiffrer, le fichier, et -k indique le mot de passe avec lequel il faut déchiffrer le fichier. Les messages d'erreurs ne sont pas affichés (cas où le mot de passe est incorrect) grâce à la reditrection de flux 2>/dev/null. Cela permet de rediriger les erreurs (2) vers le fichier “trou noir” (/dev/null).
Récupérer le résultat
Ce script génère deux sorties qu'il faut savoir lire.
Dans un premier temps, il faut voir si le déchiffrement a réussi. Pour cela, si “sortie” est le dossier de sortie que vous avez spécifié au lancement du script, faire :
file sortie/* | grep UTF-8
Cette commande a listé les fichiers lisibles pour l'humain, qui devraient être de la forme “sortie/zXX” suivi de “UTF-8 Unicode text”.
$ file files/* | grep UTF-8 files/z236: UTF-8 Unicode text files/z237: UTF-8 Unicode text
Ansi, si la commande suivante montre un texte bien compréhensible :
cat sortie/zXX
alors vous avez déchiffré votre fichier (zXX doit être le même que celu irenvoyé par la commande file).
cat sortie/z247
Si la commande file n'a rien affiché, c'est soit que le déchiffrement n'a pas fonctionné (mauvais mot de passe ou méthode de chiffrement inconnue), soit que le fichier d'origine n'était pas encodé en UTF-8. Pour cela faire la commande :
file sortie/* | grep -v data
Et essayez de repérer et afficher les fichiers dont le format vous semble cohérent à ce qu'aurait pu être le fichier d'origine.
Dans un second temps, vous serez peut-être curieux de savoir comment le fichier avait été chiffré. Pour cela, ouvrez le fichier “passes” avec un éditeur de texte, et cherchez le numero de fichier listé avec la commande “file” précédente. A côté apparaissent les informations sur le fichier (chiffrement utilisé, suivit du mot de passe utilisé).
231 : seed ( 0000 ) 232 : seed-cbc ( 0000 ) 233 : seed-cfb ( 0000 ) 234 : seed-ecb ( 0000 ) 235 : seed-ofb ( 0000 ) 236 : aes-128-cbc ( superman ) 237 : aes-128-ecb ( superman ) 238 : aes-192-cbc ( superman ) 239 : aes-192-ecb ( superman )
Quelques précautions d'après-usage
Comme vous l'avez remarqué, vos mots de passe les plus utilisés sont indiqués dans deux fichiers : le script perl et le fichier “passes”. Je conseille très fortement de remmetre la ligne du fichier script perl à son original :
(@PASSES)=();
Ensuite, effacer le fichier “passes” :
rm passes
Conclusion
Nous avons utilisé une attaque par dictionnaire contre nous même pour décrypter un fichier chiffré. Come nous avons nous-même écrit le dictionnaire avec les mots de passes potentiellement à l'origine du chiffrement, il est théoriquement impossible par cette méthode de déchiffrer un fichier que nous n'avons pas nous-même chiffré (sauf si vous devinez le mot de passe utilisé par la victime). En réalité, un pirate utilise un dictionnaire déjà tout fait recueillant les mots de passe les plus utilisés (statistiquement) par l'utilisateur lambda, et connait déjà la méthode de chiffrement utilisée, et les serveurs se protègent de ce type d'attaque.
PS: Le fichier que j'ai trouvé et qui m'a fait utiliser cette méthode s'est révélé être une ancienne liste d'idées de cadeaux :)
Fichier attaché | Taille |
---|---|
![]() | 1.27 Ko |
![]() | 972 octets |
Commentaires
plop
C'est bien bourrin, c'est en Perl, j'adore