CSCAMP CTF 2012 - Web300

1 minute read

In this challenge, an image divided into blocks has its blocks scrambled not unlike a sliding block puzzle ( The objective is to rearrange the blocks to form the correct image and submit the correct order to the server.

Our first task is to obtain the constituent parts of the image, sort them and then compare the differences between our sorted blocks and the ones received.

Here is the exploit (

from PIL import Image
import ImageChops
import math, operator
import requests

def main():
# new image
url = ""
r = requests.get(url)
cookie = r.cookies['x0x']
file("image.jpg", 'w').write(r.content) # we are lazy

# obtain winning combinations
im ="image.jpg")
im_list = []
for i in range(3):
    for j in range(4):
        im_list.append(im.crop((j*100, i*100, j*100+100, i*100+100)))

        im_real_list = []
        for i in range(12):
            im_real_list.append("parts/%s.png" % i)) # you require
            some work

            l_order = {}
            for i in range(len(im_list)):
                for j in range(len(im_real_list)):
                    if rmsdiff_2011(im_list[i], im_real_list[j]) < 600:
                        l_order[grab_fn(im_real_list[j])] = i

solution = ":".join(str(l_order[str(i)]) for i in range(12))

# send solution
url_s = ""
payload = {"order": solution}
cookies = {'x0x': cookie}
r_s = requests.get(url_s, params=payload, cookies=cookies)
print r_s.text

def rmsdiff_2011(im1, im2):
    # Shamefully stolen from
    # Thanks guy who posted cool code

    "Calculate the root-mean-square difference between two images"
    diff = ImageChops.difference(im1, im2)
    h = diff.histogram()
    sq = (value*(idx**2) for idx, value in enumerate(h))
    sum_of_squares = sum(sq)
    rms = math.sqrt(sum_of_squares/float(im1.size[0] * im1.size[1]))
    return rms

def grab_fn(name):
    return name.filename.replace("parts/", "").replace(".png", "")

if __name__ == "__main__":

Leave a Comment