PTHD_CHALLENGE.log _ □ X

FLAG: ARCHIVE MANQUANTE

> Initializing write-up sequence...

> Challenge Type: Stéganographie

> Difficulty: Easy

01_Description

Dans le cadre du CTF "Passe ton Hack d'Abord", j'ai dû faire face à un challenge qui mettait à l'épreuve mes connaissances en stéganographie.

02_Enoncé

Nous avons accès à deux images et on nous précise qu'elles n'ont pas la même signature. Cela implique que ces images ont été altérées pour accueillir des données supplémentaires.
On nous confie une paire d'images (archived-image et exfiltratred-image) pour analyse et on nous demande de comprendre et d'extraire la différence entre les deux images pour vérifier s'il y a un message caché.

archived-image et exfiltratred-image :

Exfiltrated Image Archived Image

03_Exploitation

L'énoncé précise que les deux images n'ont pas la même signature : cela oriente immédiatement vers une technique de stéganographie par LSB (Least Significant Bit). Le principe consiste à modifier le bit de poids faible de chaque pixel pour y dissimuler un message, une altération invisible à l'œil nu, mais détectable par analyse.

J'ai développé un script Python utilisant la bibliothèque Pillow pour extraire et reconstituer les bits de poids faible de chaque canal RGB de l'image exfiltrée, puis les assembler en caractères lisibles.

03a_Extrait_du_script

from PIL import Image

# Ouverture des deux images
img_archive    = Image.open("archived-image.png").convert("RGB")
img_exfiltered = Image.open("exfiltrated-image.png").convert("RGB")

bits = []
# Extraction du LSB canal par canal sur chaque pixel
for pixel_orig, pixel_exfil in zip(img_archive.getdata(), img_exfiltered.getdata()):
    for channel in range(3):
        bits.append(pixel_exfil[channel] & 1)

# Reconstitution des caractères (8 bits = 1 octet)
chars = [chr(int("".join(map(str, bits[i:i+8])), 2)) for i in range(0, len(bits), 8)]
message = "".join(chars).split("\x00")[0]
print(message)

03b_Résultat

L'exécution du script produit un output texte : les bits extraits de l'image exfiltrée, une fois réassemblés octet par octet, révèlent le flag dissimulé.

> python3 lsb_extract.py

> MESSAGE_EXTRACTED: FLAG{***}

> EXTRACTION_COMPLETE [✓]

La technique LSB est particulièrement efficace ici car la modification d'un seul bit par canal est imperceptible visuellement, mais constitue un canal de communication caché exploitable dès lors qu'on connaît la méthode d'encodage.

FLAG_STATUS: CAPTURED [✓]