--- title: peaCTF 2019 (Round2) - [Forensic] Guillotine (1200pts) author: Maltemo tags: CTF, peaCTF, Forensic, PNG --- peaCTF 2019 (Round2) - [Forensic] Guillotine (1200pts) === Written by [Maltemo](https://twitter.com/Maltemo), member of team [SinHack](https://sinhack.blog/). [TOC] ## Statement of the challenge ### Description This unknown file, hail-hydra, seems to have **lost part of its head**! Would you be able to Frankenstein the file back together for me? I do remember some specific information about the file. It is **2679x1724 pixels**, and has an **AlphaTrueColor color space**. ### File ``` hail_hydra ``` ## Analyzing the file Let's begin ! We already know that the file is corrupted, so we can assume that a `file` bash command won't give us further information. Now we open the file with an hexadecimal editor : We can already spot a critical chunk name of a PNG file : **IDAT** :::info **Little reminder :** A PNG file is composed of different chunks of data, some must exist and other are optional. The **critical chunks** are (in order): * `IHDR` (**I**mage **H**ea**D**e**R**) : General informations about the image (length, width, color type) * `PLTE` (**P**a**L**e**T**t**E**) : Palettes of colors of the image (not always needed) * `IDAT` (**I**mage **DAT**a) Beginning of image data * `IEND` (**I**mage **END**) End of image data A **chunk of data** is always composed of : |Length of the data chunk | Chunk type | Chunk data | CRC | |-|-|-|-| |4 bytes | 4 bytes | Length bytes | 4 bytes | ::: Thanks to this reminder, we can now guess that we will have to add : * The standard chunk that helps to recognize a PNG file * A IHDR chunk * Potentially a PLTE chunk * And after the IDAT chunk of data, the IEND chunk to finish the file. Those are the main documentations/sources I used to learn all this stuff : * https://www.w3.org/TR/PNG/ * https://en.wikipedia.org/wiki/Portable_Network_Graphics * https://fr.wikipedia.org/wiki/Portable_Network_Graphics * http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html ## Fixing the file Let's start by creating the header chunk. ### Header chunk From the wikipedia [PNG format page](https://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header), everything is explained, so here is the **header chunk** : `89 50 4E 47 0D OA 1A 0A` Explanation copy pasted from wikipedia : |**Values (hex)** | **Purpose**| |-|-| |`89` | Has the high bit set to detect transmission systems that do not support 8-bit data and to reduce the chance that a text file is mistakenly interpreted as a PNG, or vice versa.| |`50 4E 47`| In ASCII, the letters PNG, allowing a person to identify the format easily if it is viewed in a text editor.| |`0D 0A`| A DOS-style line ending (CRLF) to detect DOS-Unix line ending conversion of the data.| |`1A`| A byte that stops display of the file under DOS when the command type has been used—the end-of-file character.| |`0A`| A Unix-style line ending (LF) to detect Unix-DOS line ending conversion. | ### IHDR chunk |length IHDR | IHDR |IHDR data chunk| CRC| |-|-|-|-| | 00 00 00 0D | 49 48 44 52 | ??| ?? | **IHDR** data chunck : |Purpose| Value| |-|-| | Width | `00 00 0A 77` => 2679 | | Height | `00 00 06 BC` => 1724 | | Size of color bytes | `08` or `10` | | Color type | `06` => AlphaTrueColor color space | | Compression method | `00` | | Filter method | `00` | | Enlacement method | `00` | [Table's source (wikipedia)](https://fr.wikipedia.org/wiki/Portable_Network_Graphics#Exemple_d'un_chunk_(pour_une_image_de_800x600)) then adapted to our case. From the [color type](http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html), we already know that we won't have to use a PLTE chunk (PLTE must be created with color type 3, see the link before). We will use `pngcheck` at the end with option v (verbose) to get the correct CRC. ```= pngcheck -v hail_hydra_modified.png File: hail_hydra_modified.png (58575 bytes) chunk IHDR at offset 0x0000c, length 13 2679 x 1724 image, 32-bit RGB+alpha, non-interlaced CRC error in chunk IHDR (computed c3695c43, expected 0000e49a) ERRORS DETECTED in hail_hydra_modified.png ``` And there it is, the last part missing, the CRC : `c3695c43` :::info I won't explain entirely what is CRC, but briefly, it checks if there were any modifications or corruption in the data. It is calculated from the data. This is why we need to compute it, it's unique. ::: #### Final IHDR chunk |length IHDR | IHDR |IHDR data chunk| CRC| |-|-|-|-| | 00 00 00 0D | 49 48 44 52 |00 00 0A 77 00 00 06 BC 08 06 00 00 00 | C3 69 5C 43 | ### IEND chunk The IEND chunk is always the same because it doesn't contain any data, so the length stays the same, the chunk type too and the CRC isn't affected. |LENGTH|NAME DATA CHUNCK|CRC| |-|-|-| |`00 00 00 00` | `49 45 4E 44` | `AE 42 60 82` | ### Modifying the hexadecimal of the file The last step will be to edit the incomplete image from an hexa editor tool. I personaly use `bless`, but there are other like `hexeditor`, `emacs` in hex editor mode, etc. Let's add the header chunk with the IHDR at the beginning of the file : ![](https://i.imgur.com/rPBRRBv.png) Then at the end of the file, we add the IEND chunk : ![](https://i.imgur.com/yDHlnc2.png) And we obtain this picture, giving us the flag (at first not, because the creator of the challenge forgot some upper case letters :cry:). ![](https://i.imgur.com/NuI0nF5.png) ## TL;DR We need to repair a PNG file where the header, the IHDR and the IEND chunk are missing. ## Flag The flag is **peaCTF{Just_A_Flesh_Wound}** ___ <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License</a>.