题目描述:
下载得到enc.py和out.txt,分别是加密算法和结果。先看enc.py:
import codecs
def enc(s, t):if t:l = list(map(ord, s))return enc(''.join(list(map(chr, [l[i]^l[i+1] for i in range(len(l)-1)]))), t-1)else:return swith open('in.txt') as f:s = enc(f.read(), 5)
with open('out.txt', 'w') as f:f.write(s)
基本上就是读取in.txt,然后将其中的每一位字符都与其后一位字符异或,如此循环5次,再写入out.txt。
如果flag在in中,那么flag格式开头必定为RCTF{,假定out中某一位是{后第一位异或5次的结果,则可以从这一位开始计算原始明文,并依次计算后续字符直到出现}为止。若过程中出现了\n或不可打印字符,说明开始位置假定有误。
然后还原计算方法,假定有一段6位长度的字符串,其前5位已知,经过5轮异或后:
0:A B C D E X
1:A^B B^C C^D D^E E^X
2:A^C B^D C^E D^X
3:A^B^C^D B^C^D^E C^D^E^X
4:A^E B^X
5:A^B^E^X
可见如果前5位已知,那么用密文中对应位置字符异或第1、2、5位即可得到明文。
接下来的步骤是,对out中的任意一位,假定其前5位是RCTF{,计算这一位的明文,然后加上这一位的明文,计算下一位的明文。若出现},停止并输出;若出\n和不可打印字符,停止,并回到最初的循环,对下一位进行假定。
写出Python代码:
out = open('C:/Users/Administrator/Desktop/babyenc/out.txt', 'r').read()
test = list(map(ord, out))
for i in range(len(test)):lis = list(map(ord, 'RCTF{'))tmpi = ifor j in range(len(test) - i):tmp = lis[j] ^ lis[j + 1] ^ lis[j + 4] ^ test[tmpi]tmpi += 1if chr(tmp) == '}':lis.append(tmp)print(str(i) + ' results:' + ''.join(map(chr, lis)))breakelif chr(tmp) == '\n':breakelif tmp < 43:breakelse:lis.append(tmp)
运行结果中找到:
639 results:RCTF{te1l_mE_tHe_wAy_you_so1ve_thIs}
得到flag:RCTF{te1l_mE_tHe_wAy_you_so1ve_thIs}