DEFKTHON CTF 2014: Misc 200 writeup

This challenge was the second challenge in the category Misc, which is a category mostly about trivia questions or programming skills.

We were provided with an URL named “Flag is Here!” which pointed to a text file.

The text file (~700 KB) consists of thousands of triplets of values between 0 and 255. By knowing this, we immediality though that these values were describing an image in sort of way, which could contains the flag. Each line of the file had only one triplet. If the text file was describing an image, we had no information about the width and the height of the resulting image. This is where the challenge was.

While we didn’t know the width and the height, we knew the total number of pixels which is the number of lines in the text file, 61368. Therefore, for each width there is only one possible height.

I created a simple script to solve this challenge. It consist of an iteration loop over the width of image to create. If the dimensions are reasonable (let’s say no less than 100 pixels for width and height), the images created are saved and run through the OCR engine Tesseract.

This script was done in Python with the library PIL for image processing and with the library PyTesser for OCR. By running it, it generates about 500 images and with the OCR log, you can see if they contains words.

Finally, the image with the dimensions 504×122 was the one and gave me the flag!

504x122

Here’s my python script to generate the images.

#!/usr/bin/env python
from PIL import Image
from math import ceil
from pytesser import *

file_in = open("flag.txt", "r")
lines = file_in.readlines()
nb_pixels = len(lines)

file_out = open("output.txt", "w")

for i in xrange(nb_pixels - 1):
    width = i + 1
    height = int(ceil(float(nb_pixels) / float(width)))

    # Reasonable dimensions
    if width >= 100 and height >= 100:
        img = Image.new("RGB", (width, height), "white")
        pixels = img.load()

        index = 0
        for line in lines:
            r, g, b = map(int, line.strip().split(","))
            pixels[index / height, index % height] = r, g, b
            index += 1

        file_name = str(width) + "x" + str(height) + ".png"
        img.save(file_name)
        output = image_to_string(img)
        file_out.write(file_name + ": " + output + "\n")

file_out.close()
Posted in