Link: https://score.ctf.westerns.tokyo/problems/22 (only for logged in users)
This problem is not image based on steganography.
Take data from IDAT chunk, decompress it and grep for TWCTF.
The first step in every image based challenge is to look at its metadata:
$ identify -verbose ninth.png
Format: PNG (Portable Network Graphics)
identify: Extra compressed data. `ninth.png' @ warning/png.c/MagickPNGWarningHandler/1671.
identify: Extra compression data. `ninth.png' @ warning/png.c/MagickPNGWarningHandler/1671.
We can notice two important things while solving this task:
- image size is 1200x848px
- identify notices some Extra compressed/compression data – the flag?
To understand what it means, basic knowledge of PNG “backstage” is required.
PNG data is organized as chunks. A chunk is a set of bytes containing the following information:
- Length – 4 bytes
- Chunk type – 4 bytes
- Chunk data – Length bytes
- CRC – 4 bytes
One of chunks type is
IDAT. There can be many of them in one PNG file.
IDAT chunks contain compressed information about pixels in the image.
We can get this information with simple Python script:
img = png.Reader(filename)
for chunk in img.chunks():
if chunk == "IDAT":
This function returns 4071274 bytes. They are organized in scanlines which represent information about pixels in each line of an image (3 bytes per pixel) with one additional byte representing filter applied to this line. Knowing that, we can calculate how many bytes we should have and remove them (we are only interested in that “additional compressed data”).
data = get_decompressed_data("ninth.png")
image_width = 1200
image_height = 848
bytes_per_pixel = 3
bytes_per_filter = 1
data = data[(image_width * bytes_per_pixel + bytes_per_filter) * image_height:]
print ''.join([x for x in data if x in string.printable])
$ python solve.py