2020网鼎杯 白虎组crypto:bs4
这道密码学题..我...脑洞不出来
下载得到“密文.txt”内容如下,根据提示bs4是base64加密
密文:uLdAuO8duojAFLEKjIgdpfGeZoELjJp9kSieuIsAjJ/LpSXDuCGduouz 泄露的密文:pTjMwJ9WiQHfvC+eFCFKTBpWQtmgjopgqtmPjfKfjSmdFLpeFf/Aj2ud3tN7u2+enC9+nLN8kgdWo29ZnCrOFCDdFCrOFoF= 泄露的明文:ashlkj!@sj1223%^&*Sd4564sd879s5d12f231a46qwjkd12J;DJjl;LjL;KJ8729128713
所以将泄露的明文进行base64加密得到正经密文:YXNobGtqIUBzajEyMjMlXiYqU2Q0NTY0c2Q4NzlzNWQxMmYyMzFhNDZxd2prZDEySjtESmpsO0xqTDtLSjg3MjkxMjg3MTM=
位数和泄露密文一样,想到了凯撒加密,但是凯撒不行,又想到了维基利亚加密,所以这里把泄露密文和正经密文进行比较得到一个字典
a='pTjMwJ9WiQHfvC+eFCFKTBpWQtmgjopgqtmPjfKfjSmdFLpeFf/Aj2ud3tN7u2+enC9+nLN8kgdWo29ZnCrOFCDdFCrOFoF' b='YXNobGtqIUBzajEyMjMlXiYqU2Q0NTY0c2Q4NzlzNWQxMmYyMzFhNDZxd2prZDEySjtESmpsO0xqTDtLSjg3MjkxMjg3MTM' s='' a_list =[] b_list= [] for i in a: a_list.append(i) for i in b: b_list.append(i) for i in range(0,len(a)): print(b_list[i],':',ord(b_list[i])-ord(a_list[i]),end='\t\t') #print('\'',a_list[i],'\'',':',ord(a_list[i])-ord(b_list[i]),end=',')
用这个字典去解泄密密文是可以解出泄露明文的,换成需要求的密文:uLdAuO8duojAFLEKjIgdpfGeZoELjJp9kSieuIsAjJ/LpSXDuCGduouzF
悲剧来了,有六个字母不在字典里,想来想去,也没找到规律可以推出这六个字母对应的值,所以暴力破解吧
import base64 d={'p':23,'T':-4,'j':28,'M':-34,'w':21,'J':3,'9':-59,'W':-26,'i':32,'Q':-4,'H':6,'f':-20,'v':21,'C':-39,'+':-26,'e':-20,'F':-7,'C':-39,'F':-7,'K':-33,'T':-4,'B':-39,'p':23,'W':-26,'Q':-4,'t':66,'m':28,'g':55,'j':28,'o':27,'p':23,'g':55,'q':14,'t':66,'m':28,'P':28,'j':28,'f':-20,'K':-33,'f':-20,'j':28,'S':-4,'m':28,'d':-20,'F':-7,'L':-33,'p':23,'e':-20,'F':-7,'f':-20,'/':-23,'A':-39,'j':28,'2':-18,'u':27,'d':-20,'3':-49,'t':66,'N':-34,'7':-59,'u':27,'2':-18,'+':-26,'e':-20,'n':27,'C':-39,'9':-59,'+':-26,'n':27,'L':-33,'N':-34,'8':-59,'k':28,'g':55,'d':-20,'W':-26,'o':27,'2':-18,'9':-59,'Z':14,'n':27,'C':-39,'r':11,'O':28,'F':-7,'C':-39,'D':-39,'d':-20,'F':-7,'C':-39,'r':11,'O':28,'F':-7,'o':27,'F':-7} miwen="uLdAuO8duojAFLEKjIgdpfGeZoELjJp9kSieuIsAjJ/LpSXDuCGduouzF" s='' i=0 for j in miwen: if j=='E' or j=='I' or j =='G' or j=='s' or j=='X' or j=='z': s += j else: tmp = ord(j) #print(d[j],end='\t') #print(chr(tmp-d[j]),end='') s += chr(tmp-d[j]) #print('ss',j) out=[] flag='flag' s_tmp = s for a in range(65,123): s_tmp.replace('E',chr(a)) out.append(s_tmp) s_tmp = s for b in range(65,123): s_tmp.replace('I',chr(b)) out.append(s_tmp) s_tmp = s for c in range(65,123): s_tmp.replace('G',chr(c)) out.append(s_tmp) s_tmp = s for d in range(65,123): s_tmp.replace('s',chr(d)) out.append(s_tmp) s_tmp = s for e in range(65,123): s_tmp.replace('X',chr(e)) out.append(s_tmp) s_tmp = s for f in range(65,123): s_tmp.replace('z',chr(f)) out.append(s_tmp) s_tmp = s for i in out: i +='=' try: code = base64.b64decode(i) if flag in coed: print(code) except: continue out[i]=s flag='flag' for i in out: if( flag in base64.b64decode(i)): print(i)
好的,没有flag因为内存错误啦~~数字太多超出内存,没办法,等writeup吧
wp出了,说是靠猜,不知道他们怎么猜的,我是这么猜的:
原密文经过字典翻译,有五个字母翻译不出来以?代替
ZmxhZ3sxZTNhMm?lN?0xYz?yLT?mNGYtOWIyZ??hNGFmYW?kZj?xZTZ?M
对flag字符串进行base64加密,发现和密文开头一样
尝试以?作为分隔符把每一段密文解出来
第一段:flag{1e3a2
第二段:\x96
第三段:\xd3\x163
第四段:\x98\xd1\x98\xb4\xe5\x88\xc9
第五段:\x84\xd1\x85\x99\x85
第六段:...
从第一段开始爆破下一个flag字符
s='flag{1e3a2' tmp=s for i in range(97,128): s += chr(i) out=base64.b64encode(s.encode('utf-8')) str1='' for j in range(0,len(out)-1): str1 += chr(out[j]) str1 += 'lN==' try: print(base64.b64decode(str1)) except: continue s=tmp
得到如下结果,当第一段后两个字符为de时,符合密文?之后是l
假设第一段后面是de,继续往后爆破,没有密文l之后是N的结果
s='flag{1e3a2de' tmp=s for i in range(97,128): s += chr(i) out=base64.b64encode(s.encode('utf-8')) print(out) str1='' for j in range(0,len(out)-1): str1 += chr(out[j]) str1 += '0xYz==' try: print(base64.b64decode(str1)) except: continue s=tmp
换爆破范围为数字,4,5,6,7符合l之后是N
因为flag的形式是uuid:8-4-4-12,数字之后就是短横线-,所以从第一个数字带入flag查看base64加密后的值和题中给的那个数字一样
s='flag{1e3a2de' tmp=s for i in range(52,56): s +=chr(i) s += '-' print(s) print(base64.b64encode(s.encode('utf-8'))) s=tmp
都是0,没有更往后的数字来判断
那只有在4,5,6,7的base64加密上接上题目中的密文
s='flag{1e3a2de' tmp=s for i in range(52,56): s += chr(i) s += '-' out=base64.b64encode(s.encode('utf-8')) print(out) str1='' for j in range(0,len(out)-1): str1 += chr(out[j]) str1 += 'xYz==' try: print(base64.b64decode(str1)) except: continue s=tmp
都能解出来,那么说明目前这四个数字都有可能,排除不了,继续往后猜,套路和前面一样
最后猜出来的结果是flag{1e3a2de5-1c02-4f4f-9b2e-a4afabdf01e6}