记一道CTF密码题

@Time:2018/10/16

前两天的护网杯,ummmm本菜鸡只写出来了几道基础题,觉得那道比较简单的crypto很有意思,写出来记录一下~

题目给了一段加密代码,还有三个输出的数值

import os
def xor(a,b):
    assert len(a)==len(b)
    c=""
    for i in range(len(a)):
        c+=chr(ord(a[i])^ord(b[i]))
    return c
def f(x,k):
    return xor(xor(x,k),7)
def round(M,K):
    L=M[0:27]
    R=M[27:54]
    new_l=R
    new_r=xor(xor(R,L),K)
    return new_l+new_r
def fez(m,K):
    for i in K:
        m=round(m,i)
    return m

K=[]
for i in range(7):
    K.append(os.urandom(27))
m=open("flag","rb").read()
assert len(m)<54
m+=os.urandom(54-len(m))

test=os.urandom(54)
print test.encode("hex")
print fez(test,K).encode("hex")
print fez(m,K).encode("hex")
0b7361c8143e5935f9f5be3949cc07ed7a5ba6f258ebd91f29c5a7d16976f8dfb7fa422a6167281e573d015cc6d995841d5cab07923c
f46d9ffa6a28a3fc2aa17c244ec29fc6a7bf5cac0da4489ad53782f1ef66597dc2928517b56693347ad468154e6f0f1ff8501fa6a1b1
44668860d4e23030bd4a0981530bc1d6da1a20f821aa51941258862cfb716cac503d0f0dcec150171aecfe4d86839f346ff26f2a6a70

刚一开始的时候,会觉得要看代码自己解密,肯定很难,输出又那么长,真心想要放弃他,看着队里那么点分,硬着头皮写了下来,开始分析,发现这里最主要的就是异或,取出把字符串分成前后27个字符,右边与左边异或,再与K中的元素异或

记一道CTF密码题_第1张图片

K是什么呢?K是一个随机生成的列表,内有7个元素,每个元素是27个字符,相当于一个S盒,一开始认为,可能要解出整个K,但是,这似乎是不可能的。

再来看看已知量,已知原本的字符test,已知test加密后的量,又已知flag加密后的量,于是要思考,能不能将K作为一个中间变量,就像 (x1/y1)*K = (x2/y2)*K  一样,已知三个量,将K当做中间变量,就可以求出第四个量了,说干就干~

根据表中的

new_l=R
new_r=xor(xor(R,L),K)

倒推回去:

last_r = l
r = xor(xor(last_r,last_l),k7)

代入就可以得到last_l

last_l = r^l^k7

重复上述步骤

last_last_r = last_l
last_last_l = last_r ^ last_l ^ k6

倒推得到

last_last_r = r ^ l ^ k7
last_last_l = l ^ r ^ l ^ k7 ^ k6

倒推7次,最后可以得到,

7_last_l = l ^ r ^ k7 ^ k5 ^ k4 ^ k2 ^ k1
7_last_r = l ^ k6 ^ k5 ^ k3 ^ k2

因为test与flag都是经过7轮变换得到的最后的答案,所以,他们异或的k是相同的,这样,就完美的避开了k

我把前面那堆K整合成K1,后面的整合成K2,于是,就会有

test_l = test_final_l ^ test_final_r ^ K1
test_r = test_final_r ^ K2
flag_l = flag_final_l ^ flag_final_r ^ K1
flag_r = flag_final_r ^ K2

整合一下就可以得到

flag_l = test_l ^ test_final_l ^ test_final_r ^ flag_final_l ^ flag_final_r
flag_r = test_r ^ test_final_l ^ flag_final_l

写个小脚本,代码挺丑,见谅~

from base64 import b64decode
a_l = "0b7361c8143e5935f9f5be3949cc07ed7a5ba6f258ebd91f29c5a7".decode('hex')
a_r = "d16976f8dfb7fa422a6167281e573d015cc6d995841d5cab07923c".decode('hex')
b_l = "f46d9ffa6a28a3fc2aa17c244ec29fc6a7bf5cac0da4489ad53782".decode('hex')
b_r = "f1ef66597dc2928517b56693347ad468154e6f0f1ff8501fa6a1b1".decode('hex')
c_l = "44668860d4e23030bd4a0981530bc1d6da1a20f821aa5194125886".decode('hex')
c_r = "2cfb716cac503d0f0dcec150171aecfe4d86839f346ff26f2a6a70".decode('hex')


flag_l = ""
for i in range(27):
    flag_l += chr(ord(a_l[i])^ord(b_l[i])^ord(b_r[i])^ord(c_l[i])^ord(c_r[i]))

print(flag_l)

flag_r = ""
for i in range(27):
    flag_r += chr(ord(a_r[i])^ord(b_l[i])^ord(c_l[i]))

print(flag_r)

脚本我是真的菜,,,,,XD

END

 

你可能感兴趣的:(CTF-wp,密码学)