@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中的元素异或
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