護網杯一道crypto

 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 f(x,k):
 9     return xor(xor(x,k),7)
10 def round(M,K):
11     L=M[0:27]
12     R=M[27:54]
13     new_l=R
14     new_r=xor(xor(R,L),K)#先將前27和後的27異或 而後將獲得的27 位再跟k異或
15     return new_l+new_r#將new_r和new_l拼接起來
16 def fez(m,K):
17     for i in K:
18         m=round(m,i) #一輪輪下去
19     return m
20 
21 K=[]
22 for i in range(7):
23     K.append(os.urandom(27))
24 m=open("flag","rb").read()
25 assert len(m)<54
26 m+=os.urandom(54-len(m)) #不夠還得補
27 
28 test=os.urandom(54)
29 print test.encode("hex")
30 print fez(test,K).encode("hex")
31 print fez(m,K).encode("hex")

剛剛開始想了很久都沒想出k是怎麼求出來的,最後看了大佬的wp,豁然大悟,原來是消去k。git

不過。。。就算這樣也搞不出來,看了很久wp才弄明白。github

首先,我把一個的過程給寫了下來,進行猜測:app

 1 fR7=xor(xor(fL6,fR6),k)
 2 fL7=fR6
 3 fR7=xor(xor(fL5,fR5),k)
 4 fL6=fR5
 5 fR5=xor(xor(fL4,fR4),k)
 6 fL5=fR4
 7 fR4=xor(xor(fL3,fR3),k)
 8 fL4=fR3
 9 fR3=xor(xor(fL2,fR2),k)
10 fL3=fR2
11 fR2=xor(xor(fL1,fR1),k)
12 fL2=fR1
13 fR1=xor(xor(fL0,fR0),k)
14 fL1=fR0

另外一邊也同樣的,當到最後的時候tL0和tR0是已知,但要記住,從下往下回歸的時候,左右會交換了。dom

最後發現:spa

tL7^fL7=tL0^fL0

因此能夠將code

fL0=tL7^fL7^test[27:54]

這樣就能求出另外一邊了。另外一邊,也差很少,想方法求得帶有fR0^tR0的項,再異或blog

test[0:27]

就出來了。博客

下面還有一種大佬的方法:it

(tR7^R7)^(tL7^L7)=fL6^tL6
(tR6^R6)^(tL6^L6)=fL5^tL5
(tR5^R5)^(tL5^L5)=fL4^tL4
(tR4^R4)^(tL4^L4)=fL3^tL3
(tR3^R3)^(tL3^L3)=fL2^tL2
(tR2^R2)^(tL2^L2)=fL1^tL1
(tR1^R1)^(tL1^L1)=fL0^tL0

 

再有:io

fR7=fR6
tR7=tR6

就能湊出

(tR6^R6)^(tL6^L6)

以後就能一步一步往下走:就能求出 tL0^fL0 和fL0^tL0

最後給出大佬的博客,大佬真的是厲害。

https://qingchenldl.github.io/2018/10/13/%E6%8A%A4%E7%BD%91%E6%9D%AFWP-BitPwn/

 

此次比賽真的讓我自閉了。

相關文章
相關標籤/搜索