Aperi’CTF 2019 - Sounds weird
Détails du challenge
| Event | Challenge | Category | Points | Solves |
|---|---|---|---|---|
| Aperi’CTF 2019 | Sounds weird | Cryptographie | 100 | 10 |
Afin de protéger les fichiers de l’entreprise, un développeur a proposé une solution de chiffrement à sa DSI. Votre DSI vous a par conséquent demandé de tester la résistance de cette solution en vous fournissant un fichier chiffré.
Challenge: flag.ogg.crypt - md5sum: 0dbd09dc7546998c7d3fe230486be377
TL;DR
Il s’agissait d’un fichier ogg xoré. Nous avons appliqué la technique du xor « Known plaintext » en observant le magic number ogg.
Header du fichier
En regardant le nom du fichier, on voit qu’on a affaire à un fichier chiffré « ogg ». OGG est un format de fichier audio.
Si on regarde le header de notre fichier chiffré, on obtient :
xxd flag.ogg.crypt | head
00000000: 0e17 5421 3169 7562 6566 6c34 6721 5ec8 ..T!1iubefl4g!^.
00000010: b413 316b 7562 6237 8283 663f 4006 5c00 ..1kubb7..f?@.\.
00000020: 5302 0662 6566 6c35 4577 4170 3372 316b S..befl5EwAp3r1k
00000030: f23d 6466 6c34 6721 e871 7c15 5638 7562 .=dfl4g!.q|.V8ub
00000040: 6566 6c34 6721 4170 2cca b60a 7462 6566 efl4g!Ap,...tbef
00000050: 1556 e9cc 4e1f cc8d ce94 8a9d 9a99 93cb .V..N...........
00000060: 98de be90 3004 5e19 170b 164a 6c34 6779 ....0.^....Jl4gy
00000070: 2800 5b5c 7e19 1242 090f 0e62 0853 2319 (.[\~..B...b.S#.
00000080: 4052 784b 4752 5453 5c05 5714 6158 d1e9 @RxKGRTS\.W.aX..
00000090: b589 eee6 87fd e8d6 fca5 6873 3372 3162 ..........hs3r1b
On peut clairement identifier « fl4g! » et « Ap3r1k ». On peut même deviner la clé entière : « Ap3r1kubefl4g! ».
Cela est dû à un chiffrement xor ou Vigenère. Si on regarde le magic number OGG sur internet, on voit qu’il y a beaucoup d’octets nuls dans le magic number : 4F 67 67 53 00 02 00 00 00 00 00 00 00 00. À noter, ce magic number peut aussi être récupéré en regardant un fichier ogg normal.
XOR
Si on xore les 14 premiers octets de notre fichier chiffré avec les 14 octets de la signature OGG, on obtient ce qui suit :
b = "\x4F\x67\x67\x53\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00" # Default file
a = "\x0e\x17\x54\x21\x31\x69\x75\x62\x65\x66\x6c\x34\x67\x21" # Cipher
key = ""
for x in zip(a,b):
key += chr(ord(x[0])^ord(x[1]))
print(key)
Ap3r1kubefl4g!
On a obtenu la clé xor ! Maintenant, xorons tout le fichier chiffré avec notre clé pour récupérer le fichier original :
#### Decrypt
b = "\x4F\x67\x67\x53\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00" # Default file
a = "\x0e\x17\x54\x21\x31\x69\x75\x62\x65\x66\x6c\x34\x67\x21" # Cipher
key = ""
for x in zip(a,b):
key += chr(ord(x[0])^ord(x[1])) # Key Ap3r1kubefl4g!
with open("flag.ogg.crypt", 'rb') as f:
file1 = f.read()
file2 = bytearray(len(file1))
for i in range(len(file1)):
file2[i] = ord(file1[i]) ^ ord(key[i%len(key)])
# Write the XORd bytes to the output file
with open("flag_decrypt.ogg", 'wb') as f:
f.write(file2)
Maintenant on peut écouter flag_decrypt.ogg :
Bravo le flag est: APRK{51MPL3_X0R_C0MMUNICATI0N}, le tout en majuscule.
Flag
APRK{51MPL3_X0R_C0MMUNICATI0N}