Story line

Croatia - Yacht

You arrive at the location through the coordinates that you got from the assassin, a luxurious yacht. A fat, bald man lies on a puma couch. He sips on a dry martini, smokes the biggest cigar you’ve ever seen and when he smiles, a golden tooth is revealed. You can’t help but smile back at him, although you think the place seems shady. “Welcome to my yacht, Johnson, finally you show us your face. Have you killed the AGENT now? Good! You’re here to collect your reward I presume? I’ll have my guy finalize the transaction but before you leave I need a small favour from you.” It seems that he is mistaking you for the assassin but you don’t mind.

Challenge: Hide and seek (misc)

The man hands you a pendrive which you reluctantly connect to your laptop. He says he got it from a partner, and the partner claims that he hid valuable information in that PNG there. The problem is, it looks empty. See if you can find anything.

After solving

I see you are a person of many qualities. I must say I am impressed. One last thing, I just have to ask, see you always struck me as a fan of sports, I don’t know why. What do you prefer? Basketball or Soccer?

Basketball (10)

“Well then, if you are hungry for more missions, I got a thing in NYC for you. The person who wanted the AGENT dead, also owns this office complex, and needs a guy to guard a certain event that will take place there tomorrow. I’m sorry that I can’t reveal more information than that, but at least it is well paid, and perhaps you can watch a game of basketball on your way home, deal?.”

Soccer? Do you mean football? (11)

“Well then, if you are hungry for more missions, I got a thing in London for you. The person who wanted the AGENT dead, also owns this warehouse near Heathrow, and needs a guy to guard a certain event that will take place there tomorrow. I’m sorry that I can’t reveal more information than that, but at least it is well paid, and perhaps you can watch a game of football on your way home, deal?.”

Attachment

attachment.zip

hideandseek.png

Note: The image is supposed to look like half is missing.

Recon

The attachment contains one file: hideandseek.png.

It is an image of 1000x1000 pixels with a size of 15KB.

Solving

Upon opening the image we don’t really see anything, depending on the image viewer we only get a black image. So first thing I thought of was regular stenography.

Basic stenography

After playing with the image a bit and using tools like zsteg and steghide, I found it to not be your standard stenograpy.

So I started looking a the hex representation of the image (using hexdump or hexyl), and found some PNG data chunks. I didn’t know anything about PNG files though.

PNG specification

When reading through the PNG specification, I found that it was actually pretty huge. We (probably) don’t need to know everything though, so let’s skip to the datastream specification. Here we find the following text:

There are 18 chunk types defined in this International Standard. Chunk types are four-byte sequences chosen so that they correspond to readable labels when interpreted in the ISO 646.IRV:1991 character set. The first four are termed critical chunks, which shall be understood and correctly interpreted according to the provisions of this International Standard. These are:

  • IHDR: image header, which is the first chunk in a PNG datastream.
  • PLTE: palette table associated with indexed PNG images.
  • IDAT: image data chunks.
  • IEND: image trailer, which is the last chunk in a PNG datastream.

The remaining 14 chunk types are termed ancillary chunk types, which encoders may generate and decoders may interpret.

When reading through the hex representation of the image, I could find the mandatory IHDR, IDAT and IEND chucks. However, I also found some eDIH chunks. When looking around on the internet I could not find anything about it, so it had to be something to do with the challenge.

Firstly, I had to find out how chunks actually work.

Chunk specification

When looking at the chunk layout documentation, it says a chunk consists of four field; LENGTH, CHUNK TYPE, CHUNK DATA and CRC.

So I grabbed one eDIH chunk and verified/decoded it.

00 00 00 01 65 44 49 48 31 95 B3 B3 32
Part HEX Decoded
Length 00 00 00 01 1
Type 65 44 49 48 eDIH
Data 31 1
CRC 95 B3 B3 32 ....

Now we have to get all the eDIH chunks.

eDIH chunks

The flag is probably stored in the data fields of the eDIH chunks, so I wrote a little script to get all these fields and decode them.

import re
import base64

with open("hideandseek.png", 'rb') as file:
    image_data = file.read()

occurrences = (location.end() for location in re.finditer(b"eDIH", image_data))

print("".join(chr(image_data[index]) for index in occurrences))

When running it, it returns the following:

Q1RGe0RpZFlvdUtub3dQTkdpc1Byb25vdW5jZWRQSU5HP30=

This looks like some base64, so I decoded it using the following command:

echo "Q1RGe0RpZFlvdUtub3dQTkdpc1Byb25vdW5jZWRQSU5HP30=" | base64 -d

Solution

After executing this command, we get the flag! It’s CTF{DidYouKnowPNGisPronouncedPING?}.