Challenge_reveillon de Zamer - Solution d'elooo

Valid XHTML 1.1! Valid CSS!

Télécharger la cible

NiveauOutilsAuteur
NewbieUn editeur hexadecimal quelconqueelooo

Sommaire

Introduction

Zamer est un tyran, et même durant les périodes de fête, il a décidé de nous faire bucher !!
Evidemment il faut jouer le jeu et faire ce challenge dans un état d'ebriété certain. Je vous propose donc d'aller chercher votre bouteille d'alcool préféré et de vous laisser aller à en boire quelques verres (pas trop non plus, 'faut que vous puissiez voir et lire les octets dans l'éditeur hexa quand même ensuite).

Première chose à faire : lire le Readme fourni dans l'archive.
Oui je sais c'est chi*nt, mais y'a quelques infos à en tirer :)
On y voit :

Vous devez trouver le moyen de lire l'image, pour trouver le mot de passe
à me donner pour confirmer le challenge.

C'est tres facile, y'a que 2 choses à faire, mais comme je pense que vous êtes
tous déjà bourrés, j'ai choisi de ne pas faire compliqué.

Bonne chance !

Pour ceux qui lisent un mot sur deux, il va falloir préciser les choses utiles dans ce court intitulé :

Zamer est un tyran, certes, mais peut-être pas au point d'avoir sorti de derrière les fagots un format d'image exotique, peu ou plus du tout utilisé (j'en connais un autre qui ne se serait pas géné, hein mimas ;))
On va donc faire une brève étude des formats de fichiers image les plus courants, histoire de comprendre un peu mieux leurs spécifications, et plus précisément leurs entêtes.

Retour au sommaire

Brefs résumés des entêtes de fichiers image

Le format GIF

Le format GIF de CompuServe semble être le plus complexe et, potentiellement, le plus interessant. Même si sa structure en général n'interesse que les programmeurs ;)
GIF est un acronyme de "Graphics Interchange Format" (format d'échange d'images).

Voilà à quoi correspond l'entête d'un fichier GIF :

typedef struct _gifheader
{
	unsigned char	gif_signature[3];	/* GIF */
	unsigned char	gif_version[3];		/* 87a ou 89a */
	unsigned char	gif_width_lo;		/* Largeur Low-Byte */
	unsigned char	gif_width_hi;		/*        High-Byte */
	unsigned char	gif_height_lo;		/* Hauteur Low-Byte */
	unsigned char	gif_height_hi;		/*        High-Byte */
} GIFHEADER;

Ou pour ceux qui préfèrent les schémas :

        +-----------------------+
        | +-------------------+ |
        | |   GIF Signature   | |
        | +-------------------+ |
        | +-------------------+ |
        | | Screen Descriptor | |
        | +-------------------+ |
        | +-------------------+ |
        | | Global Color Map  | |
        | +-------------------+ |
        . . .               . . .
        | +-------------------+ |    ---+   
        | |  Image Descriptor | |       |   
        | +-------------------+ |       |   
        | +-------------------+ |       |  
        | |  Local Color Map  | |       |-   Répété de 1 à n fois
        | +-------------------+ |       |   
        | +-------------------+ |       |   
        | |    Raster Data    | |       |   
        | +-------------------+ |    ---+   
        . . .               . . .   
        |-    GIF Terminator   -|   
        +-----------------------+

La signature permet seulement d'identifier de quel fichier il s'agit. Ici si on voit GIF87a ou GIF89a (ce qui donne en hexa "474946383761" ou "474946383961") en signature, on s'attendra ensuite à voir du data correspondant aux spécifications du format GIF.
Je vais pas détailler tout le reste, là on veut juste avoir suffisamment d'info pour pouvoir identifier l'extension qu'il faudra attribuer au fichier fourni par Zamer.

Par contre on peut parler aussi du GIF Terminator.
Un fichier GIF se terminera toujours par 0x3B (en ascii ça correspond à une virgule). C'est une convention, et c'est aussi ce qui marque les fins de blocs dans le fichier, mais il n'est pas utile ici, encore une fois, de rentrer dans les détails.

Le format PNG

Le format PNG (Portable Network Graphics) a été mis au point en 1995 afin de fournir une alternative libre au format GIF, format propriétaire dont les droits sont détenus par la société Unisys (propriétaire de l'algorithme de compression LZW utilisé dans le format GIF). D'ailleurs PNG est également un acronyme pour PNG's Not Gif ;)
De plus la compression proposée par le format PNG est une compression sans perte (lossless compression) 5 à 25% meilleure que la compression GIF, bref faites votre choix !!

Tout comme le GIF vu précédemment, le fichier PNG contient une signature, qui correspond en notation hexadécimale à 89504E470D0A1A0A et qui correspond aux 8 premiers octets du fichier.
S'en suivent une série d'éléments appelés chunks, chunks aux-mêmes composés de 4 parties : la taille du chunk, le type de chunk codé sur 4 octets, les données du chunk, et le CRC du chunk permettant de vérifier son intégrité.

Les chunks peuvent être agencés dans n'importe quel ordre, par contre il faut obligatoirement que le 1er chunk soit IHDR (Image Header, chunk d'entête) et que le dernier soit IEND (Image Trailer, chunk de fin).

Les principaux chunks (critical chuncks) sont :

Je ne parlerai pas des autres segments ici :)

Pour ceux qui souhaiteraient la structure du PNG Header :

typedef struct _pngheader
{
	unsigned char	png_res1[1];		/* 0x89 */
	unsigned char	png_signature[3];	/* PNG */
	unsigned char	png_res2[12];		/* Reservé */
	unsigned char	png_res3[2];		/* Reservé */
	unsigned char	png_width_hi;		/* Largeur Low-Byte */
	unsigned char	png_width_lo;		/*        High-Byte */
	unsigned char	png_res4[2];		/* Reservé */
	unsigned char	png_height_hi;		/* Hauteur Low-Byte */
	unsigned char	png_height_lo;		/*        High-Byte */
} PNGHEADER;

Le format JPEG

Le format JPEG JFIF est communément référé au format JPEG.
Voici la structure du JFIF Header :

typedef struct _JFIFHeader
{
BYTE SOI[2]; /* 00h Start of Image Marker */
BYTE APP0[2]; /* 02h Application Use Marker */
BYTE Length[2]; /* 04h Length of APP0 Field */
BYTE Identifier[5]; /* 06h "JFIF" (zero terminated) Id String */
BYTE Version[2]; /* 0Bh JFIF Format Revision */
BYTE Units; /* 0Dh Units used for Resolution */
BYTE Xdensity[2]; /* 0Eh Horizontal Resolution */
BYTE Ydensity[2]; /* 10h Vertical Resolution */
BYTE XThumbnail; /* 12h Horizontal Pixel Count */
BYTE YThumbnail; /* 13h Vertical Pixel Count */
} JFIFHEAD; 

En fait l'entête débute avec FFD8FFE0 (FFD8 étant les 2 octets du SOI, etFFE0 les 2 octets de APP0), puis on a la longueur du segment JFIF sur 2 octets, la string "JFIF" terminé par un 0 (ça correspond à la signature du fichier JPEG JFIF. Notation hexadécimale : 4A46494600) sur 5 octets, La version sur 2 octets, puis les champs relatifs à la résolution de l'image.

Les données d'un fichier JPEG sont stockées sous forme de blocs et chaque bloc est identifié par un marqueur.

Le format TIFF

Le format TIFF (Tagged image file format) a été créé par Aldus (appartient à Adobe) et Microsoft.
Il a été conçu pour l'acquisition et la création d'images en vue de l'impression et peut être compressé ou non compressé.

La structure de l'entête d'un fichier TIFF :

typedef struct _TiffHeader
{
    WORD  Identifier;  /* Byte-order Identifier */
    WORD  Version;     /* TIFF version number (always 2Ah) */
    DWORD IFDOffset;   /* Offset of the first Image File Directory*/
} TIFHEAD;

L'Identifier contient toujours soit 4949 (II) soit 4D4D (MM) et signifie simplement que les données sont agencées en little-endian (format Intel) ou en big-endian (format motorola).
La signature d'un fichier TIFF se trouve toujours auniveau du 4eme byte du fichier, ce qui correspond à la version, et sera toujours 42 (soit 0x2A). En fait il s'agit de la version et non de la signature à la base, mais le format TIFF n'ayant pas été revu, on y retrouvera toujours cette même valeur, qu'on peut par conséquent considéré comme une "signature".
En fonction de l'Identifier précisé on aura donc pour les 4 premiers bytes, soit 49492A00, soit 4D4D002A.

Le principe du format TIFF consiste à définir des balises (tags, d'où le "Tagged Image File Format") décrivant les caractéristiques de l'image, aussi bien les dimensions de l'image que le nombre de couleurs, le type de compression, etc.

Le format BMP

Un fichier BMP se compose de plusieurs parties :

Comme pour les précédents, voici la structure de l'entête d'un fichier BMP :

typedef struct _BmpInfo     /* Offset   Description                      */
{
    WORD   Type;            /*  00h     File Type Identifier (4D42h)     */
    DWORD  FileSize;        /*  02h     Size of File                     */
    WORD   Reserved1;       /*  06h     Reserved (should be 0)           */
    WORD   Reserved2;       /*  08h     Reserved (should be 0)           */
    DWORD  Offset;          /*  0Ah     Offset to bitmap data            */
} BMPINFO;	

Dans les 2 premiers octets du fichiers, on y trouve la signature, qui peut être :

Ensuite on a la taille du fichier sur 4 octets, un champs réservé de 4 octets, puis l'offset dans le fichier vers les données data du bitmap.

Retour au sommaire

Corrections à apporter sur le fichier

Commencons par ouvrir le fichier cible (roelofs) dans l'éditeur hexadécimal :

Image 1

Deux choses me sautent aux yeux, après avoir lu les différentes infos citées ci-dessus sur les formats de fichiers image : le IEND et le IDAT.
Il semblerait que ce soit des chunks d'un fichier PNG !
Par contre la signature (les 8 premiers octets du fichier) ne correspond pas du tout à la signature d'un fichier PNG...

Si on descend tout à la fin du fichier dans l'éditeur hexa, on y voit également :

Image 1

On remarquera assez rapidement la présence d'un chunk IHDR.

Bref nul doûte qu'on se trouve en face d'un fichier PNG, il va donc falloir le remettre en forme afin qu'il s'affiche correctement. Ainsi on sera en mesure de récupérer le fameux pass que Zamer nous demande.

On a lu au-dessus que dans un fichier PNG les chunks pouvaient se trouver dans n'importe quel ordre, par contre il y avait quand même deux invariants à conserver : le chunk IEND comme dernier chunk et le chunk IHDR comme premier chunk.
On va donc commencer par remettre ça en ordre :

Image 1

Image 1

Puis on passe à la signature, qu'on va également rétablir :

Image 1

On met une extension .png à notre nouveau fichier qu'on a sauvegardé, et on double-clique dessus :

Image 1

Waouh du grand art, Zamer est un graphiste né :>
Bon ben je crois qu'on a fini le boulot là :) Vous pouvez vider votre cave maintenant, vous l'avez mérité !! (Je peux venir ? :p)

Retour au sommaire

Remerciements

Qui veut :)

Cordialement,
elooo.

Retour au sommaire