Petit challenge de crypto pour se dégourdir les jambes. Le code suivant nous est fourni :
import os
flag = b"BZHCTF{???????}"
assert len(flag) == 15
key = os.urandom(7)
flag = bytes([f^k for f,k in zip(flag,key)]) + bytes([f^k for f,k in zip(flag[7:],key)])
flag = flag[:7] + bytes([f^k for f,k in zip(flag[:7],flag[7:])])
print("Voici le premier flag d'une longue série :",flag.hex())
Ici ce n’est qu’une opération de XOR
qui est réalisée sur le flag. Prenons ^
l’opération de XOR, ||
l’opération de concaténation, x1
et x2
les 7 premiers et derniers octets du flag et key
la clef. On peut donc écrire le chiffrement comme suit :
cipher = x1 ^ key || (x1 ^ key) ^ (x2 ^ key)
Pour récupérer la clef, rien de plus simple comme le XOR
est:
- associatif
- commutatif
- et que
X ^ X = 0
Alors on peut facilement récupérer la clef en xorant le chiffré et le clair connu.
cipher = plain ^ key <=> key = cipher ^ plain
Il ne reste plus qu’a écrire le script permettant le déchiffrement:
knownPlain = b"BZHCTF{"
cipher = b"\x85\xde\x6a\xff\xbe\x5e\x2f\x20\x28\x2d\x37\x3b\x28\x08"
# Recover de la clef
key = bytes([f^k for f,k in zip(knownPlain,cipher)])
# Calcul de la première partie
part1 = bytes([f^k for f,k in zip(cipher,key)])
# Calcul de la fin
part2 = bytes([f^k for f,k in zip(cipher[7:],key)])
part2 = bytes([f^k for f,k in zip(part1,cipher[7:])])
print(part1 + part2 + b'}')
Plus qu’à lancer le script et TADAA !!
Le flag se révèle BZHCTF{bretons}
Note : La solution de l’auteur est disponible ici.
À propos de l’auteur
Article écrit par Maël FRAZAO alias Morncraban, Expert cybersécurité chez ACCEIS.