Wargame NDH XV - Write-Up Radio Three
Lundi 26 Juin 2017 à 18:45

Lors de la Nuit du Hack XV, j’ai donc participé au wargame public sous le nom de l’équipe The Magic Modbus. Les write-ups d’autres challenges des membres de mon équipe se trouvent ici:

Je me suis essayé aux trois challenges radio présents, cependant les deux premiers étaient hors de portée de mes maigres compétences de traitement du signal. Cependant, le troisième était largement faisable, juste un tool à dev.

Le challenge consiste en un fichier binaire, celui-ci. L’énoncé nous indique que ce signal est passé par un bloc d’entrelacement matriciel de 12 par 17. Il nous indique aussi que l’on attend de l’ascii en sortie, donc on a un rapide moyen de vérifier si l’on s’est trompé ou non. L’énoncé nous dit aussi que quelques erreurs sont présentes dans le flux, donc possiblement quelques infos à reconstruire.

L’entrelacement matriciel

L’entrelacement matriciel (matrix interleaver dans la langue de Shakespeare) est une transformation utilisée pour réduire les erreurs de transmission de l’information. Associé à des codes correcteurs d’erreurs, cela permet de corriger de petites erreurs de transmission, en les répartissant sur plusieurs octets.

Si l’on imagine un signal binaire comme une ligne de données, l’entrelacement matriciel va les traiter en blocs de N lignes par M colonnes. On remplit le bloc ligne par ligne, puis on le lit colonne par colonne pour récupérer le signal de sortie. Un exemple avec un entrelacement matriciel de 3 par 5, en imaginant que l’on travaille sur des octets directement (plus lisible).

Flux d'entrée :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Bloc résultant :
1  2  3  4  5
6  7  8  9  10
11 12 13 14 15

Flux de sortie :
1 6 11 2 7 12 3 8 13 4 9 14 5 10 15

C’est le flux de sortie qui est ensuite transmis. L’opération inverse s’effectue simplement en utilisant une matrice de 5 par 3, et on retrouve le signal de départ:

Flux d'entrée :
1 6 11 2 7 12 3 8 13 4 9 14 5 10 15

Bloc résultant :
1  6 11
2  7 12
3  8 13
4  9 14
5 10 15

Flux de sortie :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Résolution du challenge

A partir de là, c’est assez facile de résoudre le challenge, il suffit de transformer notre fichier binaire en chaîne de bits, puis de les décoder blocs par blocs.

#!/bin/python3

with open("tbintrlvrmatriciel.bin", "rb") as fp:
    content = fp.read()

bin_str = "{0:b}".format(int.from_bytes(content, byteorder='big'))

# Pad with leading zeros if necessary
pad = len(bin_str) % 8
if pad:
    bin_str = "0" * (8 - pad) + bin_str

out_file = open("tbintrlvrmatriciel.ascii", "w")

# Process the file chunk by chunk
for i in range(int(len(bin_str) / 204)):

    buf = bin_str[i * 204:(i + 1) * 204]

    transposed = ""

    for col in range(12):
        for row in range(17):
            transposed += buf[row * 12 + col]

    out_file.write(("{:x}".format(int(transposed, 2))))

print("done")

On écrit chaque bloc l’un à la suite de l’autre, et on s’aperçoit que le contenu est en fait le flag répété sur toutes la durée du signal. Quelques nibbles sont partis par ci par là, mais le flag reste encore très lisible :

Hexa : 6e6468326b31375f6264353461393062396264653634393631623764306433393161643532346165
Ascii : ndh2k17_bd54a90b9bde64961b7d0d391ad524ae

Back to posts