Hamac

Hello world !

Pour ce chall crypto d'intro, nous allons tenter de retrouver le message original à partir du message chiffré contenu dans le fichier output.txt à partir du script hamac.py via AES

Decryptage

Regardons le contenu du fichier output.txt

{"iv": "ea425b2ea4bb67445abe967e3bd1b583", "c": "69771c85e2362a35eb0157497e9e2d17858bf11492e003c4aa8ce1b76d8d3a31ccc3412ec6e619e7996190d8693299fc3873e1e6a96bcc1fe67abdf5175c753c09128fd1eb2f2f15bd07b12c5bfc2933", "h": "951bd9d2caae0d9e9a5665b4fc112809aac9f5f9ecbcfc5ad8e23cb1d020201d"}

Nous avons :

Regardons le script de chiffrement :

# python3 -m pip install pycryptodome
import json
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Hash import HMAC, SHA256
from Crypto.Random import get_random_bytes

print("Enter your password")
password = input(">>> ").encode()
h = HMAC.new(password, digestmod = SHA256)
h.update(b"FCSC2022")

iv = get_random_bytes(16)
k  = SHA256.new(password).digest()
c  = AES.new(k, AES.MODE_CBC, iv = iv).encrypt(pad(open("flag.txt", "rb").read(), 16))
r = {
	"iv": iv.hex(),
	"c": c.hex(),
	"h": h.hexdigest(),
}
open("output.txt", "w").write(json.dumps(r))

Les 6 premières lignes du script importent les librairies necessaires.

Ligne 9, on récupère le message à chiffrer. Ensuite ligne 10,11, on initialise le HMAC h.

Ligne 13, on génère un nombre aléatoire de 16 octets (iv).

Ligne 14, on génère la clé de chiffrement

Ligne 15 on chiffre le message avec la clé et le vecteur d'initialisation (la valeur aléatoire)

Ensuite, on stocke le vecteur d'initialisation, le message chiffré et le HMAC dans un JSON

Puis dernière ligne on écrit r dans un fichier

Déchiffrons tout ça

On va écrire un script qui va bruteforcer la clé de chiffrement (le mot de passe utilisé dans le script précédent) pour déchiffrer le message contenu dans output.txt.

Dans l'énoncé, il est écrit : Connaissez-vous l'existance de rockyou ?

Rockyou est un dictionnaire de mot de passe bien connu des pentesteurs et autres Hackers.

C'est parti !

from Crypto.Cipher import AES
from Crypto.Hash import HMAC, SHA256

c = "69771c85e2362a35eb0157497e9e2d17858bf11492e003c4aa8ce1b76d8d3a31ccc3412ec6e619e7996190d8693299fc3873e1e6a96bcc1fe67abdf5175c753c09128fd1eb2f2f15bd07b12c5bfc2933"
iv = "ea425b2ea4bb67445abe967e3bd1b583"
h = "951bd9d2caae0d9e9a5665b4fc112809aac9f5f9ecbcfc5ad8e23cb1d020201d"

file1 = open('rockyou.txt', 'rb')
for line in file1.readlines():
    word = line.strip()
    h2 = HMAC.new(word, digestmod=SHA256)
    h2.update(b"FCSC2022")
    if h == h2.hexdigest():
        k = SHA256.new(word).digest()
        c2 = AES.new(k, AES.MODE_CBC, iv = bytes.fromhex(iv)).decrypt(bytes.fromhex(c))
        print(word.decode())
        print(bytes.fromhex(c2.hex()))
        break

Explications

from Crypto.Cipher import AES
from Crypto.Hash import HMAC, SHA256

On importe les librairies AES que nous avons besoin

c = "69771c85e2362a35eb0157497e9e2d17858bf11492e003c4aa8ce1b76d8d3a31ccc3412ec6e619e7996190d8693299fc3873e1e6a96bcc1fe67abdf5175c753c09128fd1eb2f2f15bd07b12c5bfc2933"
iv = "ea425b2ea4bb67445abe967e3bd1b583"
h = "951bd9d2caae0d9e9a5665b4fc112809aac9f5f9ecbcfc5ad8e23cb1d020201d"

Ici, nous initialisons nos variables avec les valeurs contenues dans output.

file1 = open('rockyou.txt', 'rb')
for line in file1.readlines():
    word = line.strip()
    h2 = HMAC.new(word, digestmod=SHA256)
    h2.update(b"FCSC2022")
    if h == h2.hexdigest():
        k = SHA256.new(word).digest()
        c2 = AES.new(k, AES.MODE_CBC, iv = bytes.fromhex(iv)).decrypt(bytes.fromhex(c))
        print(word.decode())
        print(bytes.fromhex(c2.hex()))
        break

On ouvre le fichier rockyou.txt (le dictionnaire de mots de passe)

On boucle sur chaque lignes du fichier.

On enlève les caractères spéciaux de type retour chariot.

On crée le HMAC depuis le mot courant

Si le HMAC du mot courant est le même que celui qui est dans la variable h:

  • On créé la clé avec ce mot
  • On déchiffre le message avec la clé fraîchement générée et le vecteur d'initialisation ìv

On décode le résultat pour récupérer la chaîne de caractère du mot de passe et on l'affiche

Et enfin, on écrit le message original

On execute tout ça, et avec un peu de patience :

┌──(kali㉿tyrell)-[~/FCSC/FCSC2022/Challenges/intro/hamac]
└─$ python3 decrypt.py
omgh4xx0r
b'FCSC{5bb0780f8af31f69b4eccf18870f493628f135045add3036f35a4e3a423976d6}\n\n\n\n\n\n\n\n\n\n'

On obtient le mot de passe qui a servi à chiffrer le message :

omgh4xx0r

On obtient le flag

FCSC{5bb0780f8af31f69b4eccf18870f493628f135045add3036f35a4e3a423976d6}