ASIS-CTF-Quals-2014-Winner/Random-Image-Writeup

Travia-20-Winner

搜索cheetah lane tangle winner找到了这个链接,往下翻看到了Winner.得到flag.
http://en.wikipedia.org/wiki/NIST_hash_function_competition


CRYPTO-150-random-Image

首先来看代码的加密部分
code_area.png
先载入了flag.png,初始化了一个介于1 ~ 2**256之间的一个随机数,再生成了一个和flag.png一样大小的图片。这是加密前的工作,需要注意的是这个随机数在后面是不会发生变化的。

接着在新建的空白图上染上色值小于250的点。这样第一步就完成了。
因为两张图是一样大小,然后的工作就是依据flag.png中每个坐标点的色值是否小于250,来对新建图中同样的坐标点进行get_color操作。
接着看get_color(x, ,y, r)函数。
get_color.png
取x3 + y3的值,然后和r异或,最后保留返回值的低八位。也就是说经过get_color操作的值介于0,256之间。
在基于flag.png中显示flag的色值小于250的猜想下,我们试着保留250~256之间的点,得到了这样的图片。
out_260~256.png
大致看出来了flag,但还是不对。
回顾上面的分析和猜想,我们发现在enc.png中的点,如果经过get_color函数,那么必定是flag上的点。但验证是否满足get_color需要三个值,x和y都有了,但是r没有。不过如果我们有一组满足get_color的点,那么就可以计算出r。很明显250-256之间的点是绝对满足这的。
接着我们挑出250~256的点,算出r,并且验证r是否唯一。接着根据算出的r。区分enc.png中所有满足get_color关系的点和其余的点,最后显示出来就得到了清楚的flag
out-final.png

#!/usr/bin/env python
import Image
import random

enc_img = Image.open("enc.png")
im = enc_img.load()

def get_color(x, y, r):
    n = (pow(x, 3) + pow(y, 3)) ^ r
    return (n ^ ((n >> 8) << 8 ))

def calcr(enc_img):
    lst = []
    for x in range(enc_img.size[0]):
        for y in range(enc_img.size[1]):
            if 250 < im[x,y] < 256 :
                s = im[x,y]
                r = ((int(x)**3 + int(y)**3) ^ int(s)) & 0xff
                lst.append(r)
    lst = list(set(lst))
    if len(lst) == 1:
        return lst[0]
    else:
        for val in lst:
            print "GET r's value:", val
        return 0

def displayflag(enc_img, r):
    for x in range(enc_img.size[0]):
        for y in range(enc_img.size[1]):
            # if 250 < im[x,y] < 256 :
            #   print x,y,im[x,y]
            if get_color(x, y, r) == im[x,y]:
                im[x,y] = 251
            else:
                im[x,y] = 0         
    enc_img.show()

r = calcr(enc_img)
displayflag(enc_img, r)

@DM_ Luo le4f ::TEAM L::

tagged by none  

Comment Closed.

© 2014 ::L Team::