SUCTF-Crypto-Magic

题目在官方网站还可以下载得到,这里比赛后总结一下WP(虽然比赛的时候并没有做上)

题目源码:

from flag import flag

def getMagic():
    magic = []
    with open("magic.txt") as f:
        while True:
            line = f.readline()
            if (line):
                line = int(line, 16)
                magic.append(line)
                # print bin(line)[2:]
            else:
                break
    return magic

def playMagic(magic, key):
    cipher = 0
    for i in range(len(magic)):
        cipher = cipher << 1
        t = magic[i] & key
        c = 0
        while t:
            c = (t & 1) ^ c
            t = t >> 1
        cipher = cipher ^ c
    return cipher

def main():
    key = flag[5:-1]
    assert len(key) == 32
    key = key.encode("hex")
    key = int(key, 16)
    magic = getMagic()
    cipher = playMagic(magic, key)
    cipher = hex(cipher)[2:-1]
    with open("cipher.txt", "w") as f:
        f.write(cipher + "\n")

if __name__ == "__main__":
    main()

magic文件预览:

SUCTF-Crypto-Magic_第1张图片

cipher:

ae9d5ce2d396bdd5b30a20fa252e3dc53549f4499d5066ef2d005ce5696f976e


题目分析:

magic可以看做是一个256个由256个0/1组成的二进制数字串(magic文件里是长度64位的16进制数字串)

key也是一串32长度的字符串,本质上就是32*8 bits的0/1数字串

题目的意思就是:magic每次取一行,选取key为1位置的对应位置,这些位共同进行异或的结果放在cipher的第一位(本质上相当于求1的个数然后mod 2),然后cipher每次都左移一次,共进行了256次,所以magic是256行,cipher是256bits


解题思路:

把magic看成是256*256的0/1组成的矩阵;我们的key是256行1列的0/1矩阵;而最后的cipher同样是一个256行1列的0/1矩阵

所以就有矩阵运算: magic*key (mod 2)= cipher

求出magic的逆矩阵magic^-1即可通过key = cipher*(magic^-1) (mod2) 求解


解题脚本:

解题脚本使用sage写的,因为python里面的numpy求逆矩阵的时候始终得不到精确结果(可能有但我不会用),直接在sage里运行就成了:

def getMagic():
    magic = []
    with open("E:\CTF-Quals\SUCTF\magic\magic.txt","r") as f:
        while True:
            line = f.readline()
            if (line):
                line = int(line, 16)
                magic.append(line)
            else:
                break
        return magic

magic = getMagic()
magicbin = []
for i in magic:
    magicbin.append(bin(i)[2:].zfill(256))

tmp1 = []
magicarray = []
for i in magicbin:
    for cnt in i:
        tmp1.append(int(cnt))
    magicarray.append(tmp1)
    tmp1 = []
magic = matrix(magicarray)

I = magic.inverse()
#print I

cipher = int("ae9d5ce2d396bdd5b30a20fa252e3dc53549f4499d5066ef2d005ce5696f976e",16)
cipherVector = ""

cipherVector = bin(cipher)[2:].zfill(256)
	
cipherMatrix = []
for i in cipherVector:
	tmp = []
	tmp.append(int(i))
	cipherMatrix.append(tmp)
	
#print cipherMatrix
cipherMatrix = matrix(cipherMatrix)
flagMatrix = (I*cipherMatrix)%2
#print flagMatrix

flagbin = ""
for i in flagMatrix:
	flagbin+=str(i[0])

flag = ""
for i in range(0,len(flagbin),8):
	flag += chr(int(flagbin[i:i+8],2))
	
flag = "SUCTF{" + flag + "}"
print flag	


结果如下:

SUCTF-Crypto-Magic_第2张图片

其实通过这道题基本上就只到Hill Cipher到底是个什么东西了。-!-

(懒狗一只,继续努力!)


你可能感兴趣的:(Crypto)