Lapin ture à l'huile
Une solution alternative à un challenge d'hackropole
La solution qui suit est une variante de celle de Themask149 en utilisant l'information apportée par le tag.
La partie pertinente de lapin.py
qui nous intéresse est
k = scrypt(long_to_bytes(pin), b"FCSC", 32, N = 2 ** 10, r = 8, p = 1)
aes = AES.new(k, AES.MODE_GCM)
c, tag = aes.encrypt_and_digest(flag)
enc = aes.nonce + c + tag
La valeur de enc
s'obtient par concaténation du nonce, du chiffré et
du tag, le digest calculé par aes.encrypt_and_digest
(c'est dans la
version Cryptodom
de la bibliothèque Crypto
).
Comme on bruteforce le pin, on doit avoir un test de correction du message déchiffré. Dans la version de Themask149, on utilise le fait que FCSC doit faire partie du message déchiffré. De façon plus générale, si le message a été correctement déchiffré, alors le tag doit être correct et cela ne doit arriver qu'une seule fois lors de la boucle (ou alors le tag n'est pas de bonne qualité...).
Cela conduit à modifier le programme de Themask149 de la façon suivante :
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import scrypt
from Crypto.Util.number import long_to_bytes
with open("output.txt", "rb") as f:
hex_output= bytes.fromhex(f.readline().decode("utf-8")) #Attention à bien c\
onvertir notre output en bytes !
nonce = hex_output[:16] # 16 bytes de nonce
c= hex_output[16:-16]
tag = hex_output[-16:] # 16 bytes de tag
for i in range(1,10000):
print("Pin: ",i)
pin = i
k = scrypt(long_to_bytes(pin), b"FCSC", 32, N = 2 ** 10, r = 8, p = 1)
aes = AES.new(k, AES.MODE_GCM, nonce=nonce) # N'oublions pas le nonce i\
ci !
## les modifications commencent ici
try:
flag = aes.decrypt_and_verify(c, tag)
print(flag)
break
except ValueError:
pass
Notons que aes.decrypt_and_verify
lève une exception quand le tag
n'est pas valide, d'où l'utilisation de try
.