Dans cet article, nous allons voir comment craquer une archive chiffrée protégée par un mot de passe en utilisant :

  • L’attaque à clair connu de Biham et Kocher sur des archives Zip (PKZIP) basées sur la méthode de chiffrement ZipCrypto Store (peut être étendu à ZipCrypto Deflate).
  • Une attaque classique par liste de mots sur d’autres archives chiffrées telle que les archives Zip (WinZip) basées sur la méthode de chiffrement AES (128,192,256), 7-Zip ou encore RAR.

Alors que la plupart des logiciels n’utilisent que les ZIP chiffrés en AES (ou utilisent la méthode de chiffrement AES par défaut), certains logiciels continuent cependant à générer des archives chiffrés en ZipCrypto par défaut. En cause le système d’exploitation Microsoft Windows qui ne permet pas de générer (sans installation d’un logiciel tiers) de Zip chiffré et ne sait déchiffrer que les archives Zip utilisant ZipCrypto, ce qui fait que cette méthode de chiffrement ancienne et dépréciée est toujours utilisée de nos jours.

Note : Cet article est aussi disponible en anglais 🇬🇧.

Zip

ZipCrypto

Les anciennes archives ZIP chiffrées sont sensibles à l’attaque à clair connu de Biham et Kocher (en anglais Known-Plaintext Attack ou KPA) si elles utilisent la méthode de chiffrement ZipCrypto Store. C’est également possible si l’archive utilise ZipCrypto Deflate mais reste plus difficile du fait que les fichiers sont compressés avant le chiffrement.

Pour vérifier quel algorithme de chiffrement est utilisé, vous pouvez utiliser 7z :

$ 7z l -slt archive.zip | grep Method
Method = ZipCrypto Store

$ 7z l -slt archive.zip | grep Method
Method = ZipCrypto Deflate

$ 7z l -slt archive.zip | grep Method
Method = AES-256 Deflate

Note : pour générer une archive ZIP en utilisant ZipCrypto Store, nous pouvons utiliser l’ancien utilitaire zip : zip -e -0 archive.zip logo_acceis.svg ou 7z : 7z a -tzip -mx0 -p -mem=ZipCrypto archive.zip logo_acceis.svg.

Pour réaliser cette attaque, il faut au moins 12 octets de texte en clair connu et au moins 8 d’entre eux doivent être contigus. Plus le texte connu contigu est grand, plus l’attaque est rapide.

Ce qui est bien, c’est que le format Zip ne peut pas protéger les noms de fichiers, donc même si l’archive est chiffrée, nous pouvons toujours lister les noms de fichiers, récupérer l’extension pour comprendre quel type de document est stocké et cibler la signature du fichier fixe (alias les magic bytes) si vous ne connaissez pas le contenu des fichiers chiffrés.

$ 7z l archive.zip

7-Zip [64] 17.04 : Copyright (c) 1999-2021 Igor Pavlov : 2017-08-28
,Utf16=on,HugeFiles=on,64 bits,8 CPUs x64)

Scanning the drive for archives:
1 file, 1694 bytes (2 KiB)

Listing archive: archive.zip

--
Path = archive.zip
Type = zip
Physical Size = 1694

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2022-04-29 11:09:49 .....         3623         1498  logo_acceis.svg
------------------- ----- ------------ ------------  ------------------------
2022-04-29 11:09:49               3623         1498  1 files

Dans cette archive, nous pouvons voir qu’il y a une image SVG. Nous savons que toute image SVG commencera par <?xml version="1.0"?> ou <?xml version="1.0" encoding="utf-8"?> et sera peut-être suivie de <svg xmlns="http://www.w3.org/2000/svg"; ..., mais ne gardons que ce qui est sûr à 100% : <?xml version="1.0" (19 octets de long), ce qui devrait être largement suffisant pour notre attaque.

Nous pouvons obtenir un octet supplémentaire gratuit du CRC. En effet, comme expliqué dans la spécification du format de fichier ZIP, un en-tête de chiffrement de 12 octets est ajouté aux données de l’archive. Le dernier octet de l’en-tête de chiffrement est l’octet le plus significatif du CRC du fichier.

6.1.3 Each encrypted file has an extra 12 bytes stored at the start
of the data area defining the encryption header for that file. The
encryption header is originally set to random values, and then
itself encrypted, using three, 32-bit keys. The key values are
initialized using the supplied encryption password. After each byte
is encrypted, the keys are then updated using pseudo-random number
generation techniques in combination with the same CRC-32 algorithm
used in PKZIP and described elsewhere in this document.

After the header is decrypted, the last 1 or 2 bytes in Buffer
SHOULD be the high-order word/byte of the CRC for the file being
decrypted, stored in Intel low-byte/high-byte order. Versions of
PKZIP prior to 2.0 used a 2 byte CRC check; a 1 byte CRC check is
used on versions after 2.0. This can be used to test if the password
supplied is correct or not.

Nous pouvons obtenir le CRC du fichier en utilisant différents outils :

$ 7z l -slt archive.zip  logo_acceis.svg | grep CRC
CRC = 1916B617
$ unzip -Z -v archive.zip logo_acceis.svg | grep CRC
  32-bit CRC value (hex):                         1916b617

Donc l’octet juste avant le texte en clair (à l’offset -1) est 0x19.

Nous pouvons alors commencer l’attaque en utilisant bkcrack :

$ printf '<?xml version="1.0"' > plain.svg
$ bkcrack -C archive.zip -c logo_acceis.svg -p plain.svg -x -1 19
  • -C : Archive zip contenant le fichier de chiffrement
  • -c : Fichier contenant le texte chiffré (celui que nous ciblons dans l’archive)
  • -p : Fichier contenant le texte en clair connu
  • -x : Texte en clair supplémentaire en hexadécimal commençant à l’offset donné

Cela prend beaucoup de temps (~24 min pour cet exemple) mais nous sommes capables de récupérer les clés de chiffrement.
Bien qu’une attaque par liste de mots serait plus efficace pour des mots de passe faibles, l’avantage de cette méthode KPA est qu’elle peut aider à récupérer des fichiers protégés par des mots de passe beaucoup plus complexes.

$ bkcrack -C archive.zip -c 'logo_acceis.svg' -p plain.bin -x -1 19
bkcrack 1.3.5 - 2022-03-20
[15:07:25] Z reduction using 12 bytes of known plaintext
100.0 % (12 / 12)
[15:07:25] Attack on 573157 Z values at index 6
Keys: 18996980 070e64a5 38e61fb0
86.6 % (496251 / 573157)
[15:31:27] Keys
18996980 070e64a5 38e61fb0

Ensuite, pour récupérer les fichiers originaux, nous avons plusieurs options.

Nous pouvons créer une copie de l’archive avec un mot de passe choisi.

$ bkcrack -C archive.zip -k 18996980 070e64a5 38e61fb0 -U cracked.zip noraj
bkcrack 1.3.5 - 2022-03-20
[15:57:19] Writing unlocked archive cracked.zip with password "noraj"
100.0 % (1 / 1)
Wrote unlocked archive.

Sinon, nous pouvons aussi essayer de craquer les clés pour trouver le mot de passe original.

bkcrack peut effectuer un bruteforce sur les clés mais les options sont limitées et il ne supporte pas les attaques par liste de mots.

$ bkcrack -k 18996980 070e64a5 38e61fb0 -r 8 \?a
bkcrack 1.3.5 - 2022-03-20
[16:16:01] Recovering password
length 0-6...
length 7...
length 8...
[16:16:01] Password
as bytes: 6d 6f 72 70 68 65 75 73
as text: morpheus

En concaténant les trois clés, on obtient la clé principale PKZIP que l’on peut essayer de craquer avec Hashcat.

$ haiti '18996980070e64a538e61fb0'
CRC-96 (ZIP)
PKZIP Master Key [HC: 20500]
PKZIP Master Key (6 byte optimization) [HC: 20510]
Crypt16

$ hashcat -m 20500 hash-hc.txt /usr/share/wordlists/passwords/rockyou.txt

AES

Tout d’abord, nous devons extraire un hash craquable de l’archive Zip. Pour ce faire, nous pouvons utiliser le script zip2john fourni avec le paquet john.

$ zip2john archive.zip
archive.zip/logo_acceis.svg:$zip2$*0*3*0*d56b93462995433968b5f3f76eccbaea*5d55*5aa*27b48e12e3164b4dedd49a676c53392544c2c73eb472aab93ab61ce8968c8bfe7780b5de771f5ec32172c99687cf38ec469c35ffb71b2b1b6d2679fcf173970b59e1b9207adf8c9190e394c3346ced7372e149dc91b84ca8b19321cadffa9f5b75514a2f58e9e840778aa70900507ec8dda645bb8c8e066edf98f8f87feb7a2d10aa084fdb39c696f3c92592ba81c543cc11e2dd969de477321abd7639435495e4f1b26f6badb31bd88792b96757936b47b26ed267685bd9240ee11777c42a10e6a5829e64b2dd1a4ae77d8bf80854450385f6e4fd98ac07ed8e0ed852a682133d81ef903b43d534e6f785172b9f078dad64351efdad6e0348983c0407fef4d87c0090989f158bdfbe97e30710869370c70d95aef04ce815cacf8405baa921e0441dd8d69d7e17aed4b8adbc9651732fc1d5d7a2c7ec99af45e25a4047805ee6a88649eda6e170a682c19b20c5bbfe4f5720f425d4afe71d1954c87b3b910213a3f059db5eedeb696d34773482e43f8067248054b520642648b002534acb732dd0bbec6fa4eeee508b25688b0fa70c64a09bb50dc9ead6aa8410f432b982c529b67161db42c00aeba567682856d610c8768c695b562522dd57456062e947b5fc0f4316b7a2a818274e166508e0211125bafc37cbe590de9b44925149a421d3b8c15b05aa82acbc41a6c20c933d6f0ad605506db122d588e1656c540c1c69d58c5f7532933f479f5db305c7d2575275a666c8ee3b7a37ec7f0fcf53fcbe0176df72e188667de4c503956dea8fcc6ec88c868fc3505c4aea03a46e4c395a673ad7981f943dd9457a847eac7fe6758fe98336ef33ce613ddaede21848be50b062984f42d53abb84b7bad59c8d8e39ab55415700a3a416249d8d35098e59a7152ce304e91c541a46418b986b31580820cd19796a739c485c2445b21c5736e1239198a9faf05fe642e26385f90dc082a74fe560fb269bf90529af46b6986cf1ada22e95cf3dc276dd46fdbd501da78991f251556773543e8e6519c4ed4db2d954dd7e9b82e7694f17be9c75a3d5813347f0f5f7bdc8086a06bbc7510bc30b81e9fb31aec599ce018558e06214b42063386ddde083efe25889f262d25640cba5c2c3088d3cfd08263a89922ab6cf7fb3e5887acb20c851e130391a0034029a4400f4b9118f1fa740868da097b7c4529c55dc02c568c6dee5304ffd461e945c2be22d6d2fe5efe94937834035851d584bf7da08d9db49916bb055fb12983e1bce1be997f9e9b3e2f0650eccb250592f3720ba8ed1ee210b795c022b01326047d5fe23ee10058b43950fdd7520dda0cf3ec5c026d767c5cb40599a24da7c49fb4609b69900ad922680e1f3da25afd0d8581c6ff0dad8897a72f4e9a0540b1ba7d8a4d316714adb0543ef3377feeab47e2b6739db092cbe254afb9f9fbe485b971aca0a4fea5f669bf6f71492508e6bc1ace46aec90533e4fdf3c93fc6a1e0897cfcc965f7457d53045ec2a2d5da2b04249894cf920c91f20a03128adbf7d2a4072b287481d4c7714ad8785fae5713666d1308ea90f07d99951a36f687be95d35f7ec1322f7b92e3a0d6615485461cad911472faae76a6b548fa5226c1cca1187245c3ca7978fb19ccb5911d34a158888d3b6a758def7546a21cc0f4120687edc25f798a0583b768f99d5021d35bfefc4f22e0e909e720dc02f9a2350dc8f41c2e092726dcca4cdc45eb0e0d969312d4ee7a79b6856fb8792868ed3e4b97aecb62c61779658b9b55c5fe4606c086bdf88d88dc24a5ff822ae035093a104839acf0566367e13d4b658249db0d947f37e26dbe67d6fe92313d4c5546576000891e3e46c749848d5dd3cb9110709f75f35fd826650a2787a300303583cbeb06f88fe0209482b403fd8fe0cbc88159d420acb0c2f680e96a43087c170a9f07b93748b36359f5a522d0f2354f4d540e0fc45e9f7de99aced9d9ee0ba64dc9b61bc4d9111f439c6d9d79f50b1e3143e259a5a09094dd4a8d946b24564919e5350ed83562df37e2419620c29b0d72f7639d6*d4a4e58a92cbb2a72f38*$/zip2$:logo_acceis.svg:archive.zip:archive.zip
$ zip2john archive.zip > hash.txt

Nous pouvons utiliser haiti pour déterminer le type de hash (que nous connaissons déjà) et la référence correspondante pour Hashcat (HC) et John the Ripper (JtR) :

$ haiti $(cut -d ':' -f 2 hash.txt)
WinZip [HC: 13600] [JtR: zip]

Maintenant, nous pouvons essayer une attaque bruteforce de liste de mots sur le hash avec JtR.

# ~56k essais par seconde sur ma machine (Intel i5-1145G7 @ 2.6 GHz), crack instantané pour le mot de passe morpheus
john hash.txt -w=/usr/share/wordlists/passwords/rockyou.txt --format=zip

Si nous voulons essayer avec HC, nous devons retirer le nom du fichier du hash :

$ cut -d ':' -f 2 hash.txt > hash-hc.txt

Le craquage avec Hashcat a 3 fois plus d’essais par seconde mais prend étrangement plus de temps :

# ~163k essais par seconde sur ma machine (Intel TigerLake-LP GT2 [Iris Xe Graphics]), crack de 20 sec pour le mot de passe morpheus
hashcat -m 13600 hash-hc.txt /usr/share/wordlists/passwords/rockyou.txt

Note : cette méthode peut également fonctionner pour les archives protégées par ZipCrypto. Comme indiqué précédemment, les attaques par liste de mots ou par force brute sont plus efficaces pour les mots de passe faibles, mais l’attaque à clair connu de Biham et Kocher pourrait être la seule option pour les mots de passe complexes.

7-zip

Tout d’abord, nous devons extraire un hash craquable de l’archive 7z. Pour ce faire, nous pouvons utiliser le script 7z2john fourni avec le paquet john mais il nécessite le module Perl Compress::Raw::Lzma pour fonctionner. Nous pouvons l’installer avec CPAN : cpan install Compress::Raw::Lzma.

Maintenant nous pouvons obtenir le hash :

$ 7z2john archive.7z
archive.7z:$7z$0$19$0$$16$fece1a2adfc036675b63b8d17fd3f23f$1908987488$128$122$525a8b050266d616bc88c39ef6184bfe642ed3b2efa7a97c1661fe46ffab4fada7501a39702397a38fae8b61289a22a3cdefd85812e637da96e723ded8b41f6def71aab1c5722413eaafba07fc6945cfe495650ef9f36ef5cb98f6f060994359717a3e4e5e3c1ee31139c0ab51140a79804064ad7fa870c5a1d0b97d98ce6934
$ 7z2john archive.7z > hash.txt

Note : l’archive 7z de test a été générée avec une compression LZMA2, un chiffrement AES256 et sans multi-volume.

Nous pouvons utiliser haiti pour déterminer le type de has (que nous connaissons déjà) et la référence correspondante pour Hashcat (HC) et John the Ripper (JtR) :

$ haiti $(cut -d ':' -f 2 hash.txt)
7-zip [HC: 11600] [JtR: 7z]

Maintenant nous pouvons essayer une attaque par force brute de liste de mots sur le hash avec JtR, c’est lent.

# 43 essais par seconde sur ma machine (Intel i5-1145G7 @ 2.6 GHz), 5 min de crack pour le mot de passe morpheus
john hash.txt -w=/usr/share/wordlists/passwords/rockyou.txt --format=7z

Si nous voulons essayer avec HC, nous devons retirer le nom du fichier du hash :

$ cut -d ':' -f 2 hash.txt > hash-hc.txt

Le craquage avec Hashcat a 3 fois plus d’essais par seconde mais est étrangement 2 fois plus long :

# 130 essais par seconde sur ma machine (Intel TigerLake-LP GT2 [Iris Xe Graphics]), 10 mins, 44 secs de craquage pour le mot de passe morpheus
hashcat -m 11600 hash-hc.txt /usr/share/wordlists/passwords/rockyou.txt

Remarque : les archives chiffrées 7z protègent également les noms de fichiers.

RAR

Tout d’abord, nous devons extraire un hash craquable de l’archive RAR. Pour ce faire, nous pouvons utiliser le script rar2john fourni avec le paquet john.

$ rar2john archive.rar
archive.rar:$rar5$16$0ee908df02e8f7e7697d862388d329eb$15$52eafa34fd7337161521ca986dcc9e8b$8$a887866220451ac5
$ rar2john archive.rar > hash.txt

Remarque : l’archive de test a été générée au format RAR 5.0 qui semble utiliser AES-256.

Nous pouvons utiliser haiti pour déterminer le type de hash (que nous connaissons déjà) et la référence correspondante pour Hashcat (HC) et John the Ripper (JtR) :

$ haiti $(cut -d ':' -f 2 hash.txt)
SAP CODVN B (BCODE) [HC: 7700] [JtR: sapb]
RAR5 [HC: 13000] [JtR: rar5]

Maintenant, nous pouvons essayer une attaque par force brute de liste de mots sur le hachage avec JtR.

# ~350 essais par seconde sur ma machine (Intel i5-1145G7 @ 2.6 GHz), crack de 35 sec pour le mot de passe morpheus
john hash.txt -w=/usr/share/wordlists/passwords/rockyou.txt --format=rar5

Si nous voulons essayer avec HC, nous devons retirer le nom du fichier du hash :

$ cut -d ':' -f 2 hash.txt > hash-hc.txt
# ~2000 essais par seconde sur ma machine (Intel TigerLake-LP GT2 [Iris Xe Graphics]), 40 secs de crack pour le mot de passe morpheus
hashcat -m 13000 hash-hc.txt /usr/share/wordlists/passwords/rockyou.txt

Note : la même méthode fonctionne pour les archives RAR3, seules les références HC et JtR seront différentes.

Conclusion

Peu importe le format d’archive, il est recommandé de vérifier la méthode de chiffrement utilisée et de choisir la plus robuste proposée dans les options du logiciel pour générer une archive chiffrée.

Pour le format ZIP en particulier, il est recommandé d’utiliser AES comme méthode de chiffrement. En effet, même avec un mot de passe fort, ZipCrypto est vulnérable par conception, il y a donc de grande chances qu’il soit possible de lire les documents que l’archive enferme sans en connaître le mot de passe.

Enfin, même si une méthode de chiffrement robuste est utilisée, l’utilisation d’un mot de pas faible peut compromettre la sécurité de l’archive. Il est donc recommandé d’utiliser un mot de passe fort pour protéger l’archive.

Exemple du choix de la méthode de chiffrement dans 7-zip :

7-zip

Exemple du choix de la méthode de chiffrement dans Ark :

ark

Exemple du choix de la méthode de chiffrement dans WinRAR (Cocher la case "Chiffrement ZIP" en français ou "ZIP legacy encryption" en anglais utilisera ZipCrypto, WinRAR utilisera AES si elle n’est pas cochée) :

winrar

A propos de l’auteur

Article écrit par Alexandre ZANNI alias noraj, Ingénieur en Test d’Intrusion chez ACCEIS.