题目:
Encrytp.py文件
import sys
from binascii import unhexlify
if(len(sys.argv)<4):
print("Usage: python Encrypt.py keyfile plaintext ciphername")
exit(1)
def lfsr(R, mask):
output = (R << 1) & 0xffffffffffffffff
i=(R&mask)&0xffffffffffffffff
lastbit=0
while i!=0:
lastbit^=(i&1)
i=i>>1
output^=lastbit
return (output,lastbit)
R = 0
key = ""
with open(sys.argv[1],"r") as f:
key = f.read()
R = int(key,16)
f.close
mask = 0b1101100000000000000000000000000000000000000000000000000000000000
a = ''.join([chr(int(b, 16)) for b in [key[i:i+2] for i in range(0, len(key), 2)]])
f=open(sys.argv[2],"r")
ff = open(sys.argv[3],"wb")
s = f.read()
f.close()
lent = len(s)
for i in range(0, len(a)):
ff.write((ord(s[i])^ord(a[i])).to_bytes(1, byteorder='big'))
for i in range(len(a), lent):
tmp=0
for j in range(8):
(R,out)=lfsr(R,mask)
tmp=(tmp << 1)^out
ff.write((tmp^ord(s[i])).to_bytes(1, byteorder='big'))
ff.close()
flag_encode.txt 文件
HMe嫫綒l"軏a>啒S ?HC隕^JaAXDN婬埓騕f擆AT??l??鼁?氺6!F€娦栮辬
羘豭峯旈L.PSu1珙a顄r[j没饬坘嫑o齑FOx?)扥菊焚鍋暭uVK@?舽?-qc齛?豤G齍?箶亷a?E鸜摇c1`o鴄魛?琲敶牉)?捏ЯY嘉驌SM>舄湼~^7?/?倕湏?潳 ?詛蛝銥?荨t樀飤鞵燿颔嬠i外卂uu$`?F醧bt?*s1抸蝱;<豭掉??;Z卺?瓷|~吢CcC偠芵f饸X麿8禫枘#3??殍歼齵拆/惉莘m蜚閱@R
?p▽傺??g-BJ彸?馐?雯鴔?牶櫉FY?E鹍?a
?耸瓉ゝ頉?
+魤傌+哙桒?$鰇>]燤?榎鮭脎畅烄_?)?绪顸_ 蘸??8綗Q_qB奎?@G?飈t肣枉?E~h*?裸軞仂E野ez窘頷鲸4S术?櫅?i?C?唆3?P祆)嘕怑%讠?{疷q踾楑瓮/n飐j栰?i??燉楁C躚縏?>澘p?g刜Q??搡i藴?€>ya硅鹭淿i俰矊2X廭)藆?Z沅Ⅴ湉1JA?l卵`:绺f%忢7@肴0R?蠡夋M4$乥?埈s€慐蒟攧+奊€e漐1?k芡忠?:悾偡韭趄辶、?E酄虬懨}Xi痃H<uu?Ua殖&纣KY?#M6?
`峴?璤靷6K淎 QtD?Z?荠?t纄g)e樖k遮骔襞?孶\M鐤1_沟拍=怖湓?[&贓鈳Uu瘩dE|z灀葲L}郏}娺鉈蝒??鵷倹嵂梁廑d訍踋磺e衭'槼鲌②0坍抑e?荵:湘[殬麨l.i!烽]itD3氍⒗+瓤<濈躘?肞M%騾?褄
穠晪? 躈枉AY懔?竈觗8!?yま糒吷€;}m?蓜t?細"
<D?嵠R 桙O?鎊核 镧?@??謹寔唀趠]S椧~Q添€嘧R糇?荆)耳胙?諩j@峖b?
7\ξ_y濋羨€黚+? 傄=茀{y?徖<贮.撬懾?z簡躔*?(υ禃??荖絅铉輑湜榍 樵'~鞳GJ!訙sE?
.bash_history.txt 文件
python Encrypt.py key.txt Plain.txt cipher.txt
python Encrypt.py key.txt flag.txt flag_encode.txt
rm flag.txt
rm key.txt
cipher.txt 文件
rG"憷瑖z'羾)t熩\?P
隑\[jSWKJ P匜 J悽馮w€鼲?儳"??緉?効 #Y彼屹脮榍mB遝膒?掓_fPO0%钓`鐁 j,?
Plain.txt 文件
sdgfjkahblskdjxbvfskljdfbguisldfbvghkljsdfbghsjkldhbgjklsdbgvlkjsdgbkljb sdkljfhwelo;sdfghioeurthgbnjl k
这个题的给了两份加密文件:
python Encrypt.py key.txt Plain.txt cipher.txt
python Encrypt.py key.txt flag.txt flag_encode.txt
由题目可知,Plain.txt 通过加密后得到了 cipher.txt
两份文件使用相同的初始密钥 key,所以求出 key 是解题的关键。
由这段代码可知:
cipher.txt 文件的前一部分是由 key和plain.txt的前一部分进行异或构成的,后一部分是由 lfsr产生的密钥流与plain.txt 的后一部分进行异或构成的。
所以要想求得 key值,只需要将,plain.txt 与 cipher.txt 进行异或即可得到。
import re
from Crypto.Util.number import*
#指定文件在相对路径
import os, sys
os.chdir(sys.path[0])
cip = open('cipher.txt', 'rb').read()
plain = open('Plain.txt', 'rb').read()
cip = bytes_to_long(cip)
plain = bytes_to_long(plain)
key = hex(cip^plain)[2:]
print(key)
s = re.findall(r'.{16}',key[::-1])
print(s)
从输出数据可以发现,前16位缺一位数据,应该补0,即密钥应该为key:0123456789abcdef(为什么前面加个0,这里具体原因还没想明白,还有点没真正搞清楚)
由mask可知,密钥应该为16位16进制数据,即64bit,与mask长度一致。
由于对,flag的加密仅仅只是 异或,并未进行其他的加密,所以我们有了密钥key 后,只需要将其与 密文再次进行异或 就能得到 flag 了。
而对于 lfsr 产生密钥流的中间过程,我们将其看作“黑匣子”,只关注它的功能,不在意他的内部结构,更有利于解题。有了key 后产生的密钥流是一样的,所以将密钥流与密文 异或就行了。
import os,sys
os.chdir(sys.path[0])
key = '0123456789abcdef'
R = int(key,16)
mask = 0b1101100000000000000000000000000000000000000000000000000000000000
def lfsr(R, mask):
output = (R << 1) & 0xffffffffffffffff
i=(R&mask)&0xffffffffffffffff
lastbit=0
while i!=0:
lastbit^=(i&1)
i=i>>1
output^=lastbit
return (output,lastbit)
cipher = open('flag_encode.txt','rb').read()
a = ''.join([chr(int(b, 16)) for b in [key[i:i+2] for i in range(0, len(key), 2)]])
ans = []
lent = len(cipher)
for i in range(0, len(a)):
ans.append(chr(cipher[i]^ord(a[i])))
for i in range(len(a), lent):
tmp = 0
for j in range(8):
(R,out)=lfsr(R,mask)
tmp=(tmp << 1)^out
ans.append(chr(tmp ^ cipher[i]))
flag = ''.join(ans)
print(flag)