HITCON CTF 2014: Puzzle

August 18, 2014

This is the picture we got:


After downloading, I opened the picture with an image viewer and saved it again, only to compare the file sizes. As expected the original is much larger than the just saved one. Then I opened it in stegesolve to make sure I don’t miss anything. By looking at the image with an hex editor I noticed a lot of JFXX Strings. So I let the program search for the jpg header FFD8, which gave me 102 results. In order to extract those images I wrote a small program:

f = open('puzzle.jpg','r')
d = f.read()

o = ""
j = 0
for i in range(len(d)):
   if d[i] == '\xff' and d[i+1] == '\xd8':
      o = d[i:]
      f = open(str(j)+'.jpg','w')
      j += 1

So that’s the puzzle (combined picture):


But I didn’t want to solve the puzzle in Paint by hand, so I let python do this work for me and search the matching neighbour to a given image and side.

values = {}
ima = Image.open(sys.argv[1]+'.jpg')
da = ima.load()
sa = ima.size
for i in range(2,101):
    imb = Image.open(str(i)+'.jpg')
    sb = imb.size
    db = imb.load()
    z = 0
    for x in range(sa[1]):
        if sys.argv[2] == "l":
            a = da[0,x]
            b = db[sa[0]-1,x]
        elif sys.argv[2] == "t":
            a = da[x,0]
            b = db[x,sa[1]-1]
        elif sys.argv[2] == "r":
            a = da[sa[0]-1,x]
            b = db[0,x]
        else: #bottom
            a = da[x,sa[1]-1]
            b = db[x,0]

        y = abs(a[0]-b[0])+abs(a[2]-b[2])+abs(a[2]-b[2])
        z += y
    values[str(i)+'.jpg'] = z
sorted_values = sorted(values.iteritems(), key=operator.itemgetter(1))
print sorted_values[0]


A team member mentioned that the key is propably in the sky as something can be seen there in the puzzle pictures.
After some time putting the images together I got this:


Here we can read “HITCON” and “ounT”. Another team member found the original image, so we could use the image combiner in stegsolve which gave us finally this:


Flag: HITCON{mounTAIn_jEPg_I01}

Leave a Reply