CTFshow 月饼杯crypto1_中秋月wp

下载附件得到内容

fsskryenvkm~jl{ejs}jwflzsnpgmifq{{j{|suhzrjppnx|qvixt~whu

自动钥匙⊕
明文全大写,得到后转小写,并以_连接单词。
题目hint:

某古典密码
经此古典密码加密后,密文还是大写
该古典密码的密钥形式:keyword+plaintext (+plaintext...+plaintext)

一开始我就找到了是Autokey密码,但是解不出来
看来了大佬的wp后发现这里有异或⊕

然后就自己尝试异或一下,脚本:

s='fsskryenvkm~jl{ejs}jwflzsnpgmifq{{j{|suhzrjppnx|qvixt~whu'
for i in range(255):
	res=''
	for j in range(0,len(s)):
		temp = ord(s[j])^i
		if 65<=temp<=90 or 97<=temp<=122:	#由大小写字母构成
			res += (chr(temp))
	if len(res)==len(s):
		print(res)

得到

ylltmfzqitrausdzulbuhyselqoxrvynddudcljwemuooqgcnivgkahwj
YLLTMFZQITRAUSDZULBUHYSELQOXRVYNDDUDCLJWEMUOOQGCNIVGKAHWJ

然后再次尝试使用break_autokey.py:

from ngram_score import ngram_score
from pycipher import Autokey
import re
from itertools import permutations

qgram = ngram_score('quadgrams.txt')
trigram = ngram_score('trigrams.txt')
ctext = 'YLLTMFZQITRAUSDZULBUHYSELQOXRVYNDDUDCLJWEMUOOQGCNIVGKAHWJ'
ctext = re.sub(r'[^A-Z]','',ctext.upper())

keep a list of the N best things we have seen, discard anything else

class nbest(object):
    def __init__(self,N=1000):
        self.store = []
        self.N = N
        

def add(self,item):
    self.store.append(item)
    self.store.sort(reverse=True)
    self.store = self.store[:self.N]

def __getitem__(self,k):
    return self.store[k]

def __len__(self):
    return len(self.store)

#init
N=100
for KLEN in range(8,20):
    rec = nbest(N)

for i in permutations('ABCDEFGHIJKLMNOPQRSTUVWXYZ',3):
    key = ''.join(i) + 'A'*(KLEN-len(i))
    pt = Autokey(key).decipher(ctext)
    score = 0
    for j in range(0,len(ctext),KLEN):
        score += trigram.score(pt[j:j+3])
    rec.add((score,''.join(i),pt[:30]))

next_rec = nbest(N)
for i in range(0,KLEN-3):
    for k in range(N):
        for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
            key = rec[k][1] + c
            fullkey = key + 'A'*(KLEN-len(key))
            pt = Autokey(fullkey).decipher(ctext)
            score = 0
            for j in range(0,len(ctext),KLEN):
                score += qgram.score(pt[j:j+len(key)])
            next_rec.add((score,key,pt[:30]))
    rec = next_rec
    next_rec = nbest(N)
bestkey = rec[0][1]
pt = Autokey(bestkey).decipher(ctext)
bestscore = qgram.score(pt)
for i in range(N):
    pt = Autokey(rec[i][1]).decipher(ctext)
    score = qgram.score(pt)
    if score > bestscore:
        bestkey = rec[i][1]
        bestscore = score       
print(bestscore,'autokey,klen',KLEN,':"'+bestkey+'",',Autokey(bestkey).decipher(ctext).lower())

得到

-306.4154316738783 autokey, klen 8 :"KYIFZYWC", ondonhdougomhlalafnianstllbprigusstolddcmubadndaboughnewi
-290.9667615558167 autokey, klen 9 :"NHSZZCZEI", letundamainhafazilthaynemidekvaazrmaybowendcosforeidimprv
-252.5124922641369 autokey, klen 10 :"KEYFORFLAG", ohnoyoufindtheflagtheflagforyouisdoyoulikeclassicalcipher
-272.6830354332479 autokey, klen 11 :"QJTTBDRTGFE", icsalcixconssadosdestlamlnaforgusdispleingawlioncenteallb
-284.1217857757366 autokey, klen 12 :"ELAJWLRDEVRL", ualkquineyapassperthdasplywinefgadcornnoripioneowvistssov
-281.0496306112152 autokey, klen 13 :"UIZCVRFYKENJJ", edmrrousyperloandunapadaufaxeseadouacrewhickonsingecotzuz
-261.79764432480465 autokey, klen 14 :"VXBIMDSUECYSHZ", doklachwertintalkabsaconsiberkoncluboyrodideaderthhitmeog
-267.71934867785404 autokey, klen 15 :"FLDGXNBQVQOAROL", tainpsyanddadesgudofpasrinoundstappoctsoryablyncytheritfl
-261.83884091332243 autokey, klen 16 :"HAXCFFMAOPRNRKLG", rlorhanqueandistdandayformokonguadhacneinageadainfogindow
-241.55027012885887 autokey, klen 17 :"UKXQTYVZFFMHNOQLF", ebodtherdofthenophageflaunasyouapondwheleshowssinththeasy
-246.7536189844891 autokey, klen 18 :"QYIMYUWMIBYTQFRZHI", indholdeasthenmandtheretimofyouardhajeffatmcaliotieddayse
-242.68397600907335 autokey, klen 19 :"GSZFZUBKEAYCYSSNUNJ", stmonlygettywalmayscomerasitycardsidethisidowineliedssesq

当klen为10时,ohnoyoufindtheflagtheflagforyouisdoyoulikeclassicalcipher。
结合提示flag为:flag{do_you_like_classical_cipher}。

python3下breakautokey适用脚本及依赖库下载

posted @ 2021-10-18 18:41  404p3rs0n  阅读(161)  评论(0编辑  收藏  举报