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.