7.9 KiB
+++ author = "Maik de Kruif" title = "Hide and seek" subtitle = "Beginners Quest 8 - Google CTF" date = 2021-09-28T23:21:00+01:00 description = "A writeup for challenge 8 of the beginners quests of the Google CTF." cover = "img/writeups/google-ctf/2021/beginners-quest/8/cover.png" tags = [ "Google CTF", "Beginners Quest", "ctf", "hacking", "writeup", "misc", ] categories = [ "ctf", "writeups", "hacking", "misc", ] +++
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
{{< figure class="small" src="/img/writeups/google-ctf/2021/beginners-quest/8/hideandseek.png" title="hideandseek.png" raw=true >}}
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.
- Transparency information: tRNS (see 11.3.2: Transparency information).
- Colour space information: cHRM, gAMA, iCCP, sBIT, sRGB (see 11.3.3: Colour space information).
- Textual information: iTXt, tEXt, zTXt (see 11.3.4: Textual information).
- Miscellaneous information: bKGD, hIST, pHYs, sPLT (see 11.3.5: Miscellaneous information).
- Time information: tIME (see 11.3.6: Time stamp information).
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?}
.