JarvisOJ-[xman2019]xfz

下载附件后,得到了一个py脚本与一个.log的文本,如下:

fez.py:

 1 import os
 2 def xor(a,b):
 3     assert len(a)==len(b)
 4     c=""
 5     for i in range(len(a)):
 6         c+=chr(ord(a[i])^ord(b[i]))
 7     return c
 8 def round(M,K):
 9     L=M[0:27]
10     R=M[27:54]
11     new_l=R
12     new_r=xor(xor(R,L),K)
13     return new_l+new_r
14 def fez(m,K):
15     for i in K:
16         m=round(m,i)
17     return m
18 
19 K=[]
20 for i in range(7):
21     K.append(os.urandom(27))
22 m=open("flag","rb").read()
23 assert len(m)<54
24 m+=os.urandom(54-len(m))
25 
26 test=os.urandom(54)
27 print(test.encode("hex"))
28 print(fez(test,K).encode("hex"))
29 print(fez(m,K).encode("hex"))

fez.log:

50543fc0bca1bb4f21300f0074990f846a8009febded0b2198324c1b31d2e2563c908dcabbc461f194e70527e03a807e9a478f9a56f7
66bbd551d9847c1a10755987b43f8b214ee9c6ec2949eef01321b0bc42cffce6bdbd604924e5cbd99b7c56cf461561186921087fa1e9
44fc6f82bdd0dff9aca3e0e82cbb9d6683516524c245494b89c272a83d2b88452ec0bfa0a73ffb42e304fe3748896111b9bdf4171903

简单的观察可以知道要通过已给出的三个输出,计算出原本的m(也就是flag)。这里要注意的是异或运算本身的特殊性-可逆,因此通过后面两个式子,fez(test,K),fez(m,K)计算出test与m原始数的[0:27]与[27:54],通过两者之间相互异或,两两抵消,再与给出的test的值异或,即可得到最初的m。这其中最重要的就是抵消掉k的值。

推算结果如下:

已知 entest enm test
设entest的[0:27]为L,[27:54]为R
设enm的[0:27]为ML,[27:54]为MR
设k[]的每个值为k0,k1...k6
则根据算法可知:(通过L和R来推)
原始的test:(逆推)
                 L                                          R     
①     R^k6^L                                                L
②     L^k5^(R^k6^L)                                      (R^k6^L)
③    (R^k6^L)^k4^( L^k5^(R^k6^L) )                       L^k5^(R^k6^L) 
简     L^k4^k5                                            R^k5^k6
④     L^R^k3^k4^k6                                       L^k4^k5
⑤     R^k2^k3^k5^k6                                      L^R^k3^k4^k6
⑥     L^k1^k2^k4^k5                                      R^k2^k3^k5^k6
⑦     L^R^k0^k1^k3^k4^k6                                 L^k1^k2^k4^k5
原始的enm与test逆推过程一样:
可得:
                 L                                           R     
       ML^MR^k0^k1^k3^k4^k6                            ML^k1^k2^k4^k5
因此,根据异或运算的可逆性,可得:
test[0:27]^m[0:27]==(L^R^k0^k1^k3^k4^k6 )^(ML^MR^k0^k1^k3^k4^k6)==L^R^ML^MR
test[27:54]^m[27:54]==(L^k1^k2^k4^k5)^(ML^k1^k2^k4^k5)==L^ML

写脚本得出flag:

from libnum import n2s
from binascii import a2b_hex
test='50543fc0bca1bb4f21300f0074990f846a8009febded0b2198324c1b31d2e2563c908dcabbc461f194e70527e03a807e9a478f9a56f7'
entest='66bbd551d9847c1a10755987b43f8b214ee9c6ec2949eef01321b0bc42cffce6bdbd604924e5cbd99b7c56cf461561186921087fa1e9'
enm='44fc6f82bdd0dff9aca3e0e82cbb9d6683516524c245494b89c272a83d2b88452ec0bfa0a73ffb42e304fe3748896111b9bdf4171903'

test=a2b_hex(test)
entest=a2b_hex(entest)
enm=a2b_hex(enm)
R=entest[27:54]
L=entest[0:27]
MR=enm[27:54]
ML=enm[0:27]
#print(test,"\n",entest,"\n",enm)
ml=''
mr=''
for i in range(27):
    templ=chr((R[i]^MR[i]^L[i]^ML[i]^test[i]))
    tempr=chr((L[i]^ML[i]^test[27+i]))
    ml+=templ
    mr+=tempr

print(ml+mr)

运算结果:

JarvisOJ-[xman2019]xfz_第1张图片

 

你可能感兴趣的:(JarvisOJ-[xman2019]xfz)