CTF中Crypto题目分析(1)

425 阅读10分钟

我正在参与掘金创作者训练营第6期,点击了解活动详情

[WUSTCTF2020]dp_leaking_1s_very_d@angerous

先看题目,一猜就是dp泄露,之前做过类似的题目。

e = 65537
n = 156808343598578774957375696815188980682166740609302831099696492068246337198792510898818496239166339015207305102101431634283168544492984586566799996471150252382144148257236707247267506165670877506370253127695314163987084076462560095456635833650720606337852199362362120808707925913897956527780930423574343287847
c = 108542078809057774666748066235473292495343753790443966020636060807418393737258696352569345621488958094856305865603100885838672591764072157183336139243588435583104423268921439473113244493821692560960443688048994557463526099985303667243623711454841573922233051289561865599722004107134302070301237345400354257869
dp = 734763139918837027274765680404546851353356952885439663987181004382601658386317353877499122276686150509151221546249750373865024485652349719427182780275825

我们先看看dp怎么求:dp=d%(p−1)。

根据公式推导可以写出代码:

import gmpy2
import binascii


def getd(n,e,dp):
    for i in range(1,e):
        if (dp*e-1)%i == 0:
            if n%(((dp*e-1)/i)+1)==0:
                p=((dp*e-1)/i)+1
                q=n/(((dp*e-1)/i)+1)
                phi = (p-1)*(q-1)
                d = gmpy2.invert(e,phi)%phi
                return d


e = 65537
n = 156808343598578774957375696815188980682166740609302831099696492068246337198792510898818496239166339015207305102101431634283168544492984586566799996471150252382144148257236707247267506165670877506370253127695314163987084076462560095456635833650720606337852199362362120808707925913897956527780930423574343287847
c = 108542078809057774666748066235473292495343753790443966020636060807418393737258696352569345621488958094856305865603100885838672591764072157183336139243588435583104423268921439473113244493821692560960443688048994557463526099985303667243623711454841573922233051289561865599722004107134302070301237345400354257869
dp = 734763139918837027274765680404546851353356952885439663987181004382601658386317353877499122276686150509151221546249750373865024485652349719427182780275825


d=getd(n,e,dp)
m=pow(c,d,n)
print binascii.unhexlify(hex(m)[2:])

还是那个简单的流程:

flag{dp_leaking_1s_very_d@angerous}

[BJDCTF2020]编码与调制

下载附件,先看txt文件:

密文:2559659965656A9A65656996696965A6695669A9695A699569666A5A6A6569666A59695A69AA696569666AA6

猜不出来是什么加密,我们再看看hint图片:

hint.PNG 可以推断出是曼彻斯特编码,我们找个解码器或者解码网站进行解码:

024A447B4469664D616E63686573746572636F64657D

不难看出是16进制编码,我们转一下字符串:

flag{DifManchestercode}

[BJDCTF2020]Polybius

下载附件:

密文:ouauuuoooeeaaiaeauieuooeeiea
hint:VGhlIGxlbmd0aCBvZiB0aGlzIHBsYWludGV4dDogMTQ=
flag:解出明文后,请加上BJD{}

hint是base编码,我们先看一下:

The length of this plaintext: 14
明文的长度:14

提示我们明文长度为14,不了解是什么意思,继续看,发现题目名称是一种编码方式Polybius(波利比奥斯方阵密码), 也叫棋盘密码,我们了解一下如何解密:

Polybius校验表由一个5行5列的网格组成,网格中包含26个英文字母,其中I和J在同一格中。相应字母用数对表示。

似乎(2,4)对应了多个解,即i/j,所以解出来可能不太一样,我们回到题目。会发现我们不清楚字符的先后顺序,需要我们遍历所有的可能,还有i/j的不同结果,我们找个脚本:

import itertools
s="aeoiu"
ciper="ouauuuoooeeaaiaeauieuooeeiea"
sumresult=[]
numsumresult=[]
for i in itertools.permutations(s,5):#找出所有全排列
    sumresult.append("".join(i))
for i in sumresult:
    temp=""
    for j in ciper:
        temp+=str(i.index(j)+1)
    numsumresult.append(temp)
for i in numsumresult:
    flag=""
    for j in range(0, len(i),2):
        xx=(int(i[j])-1)*5+int(i[j+1])+96
        if xx>ord('i'):
            xx+=1
        flag+=chr(xx)
    print(flag)

会发现flag就在其中一个结果中:

flag{flagispolybius}

yxx

下载附件,我们看一下明文:

lovelovelovelovelovelovelovelove

密文打开似乎是一堆乱码,根据给了我们两段文字,怀疑是需要我们进行异或,所以我们用他们的二进制格式进行异或:

import base64


m = '0110110001101111011101100110010101101100011011110111011001100101011011000110111101110110011001010110110001101111011101100110010101101100011011110111011001100101011011000110111101110110011001010110110001101111011101100110010101101100011011110111011001100101'
c = '0000101000000011000101110000001001010110000000010001010100010001000010100001010000001110000010100001111000110000000011100000101000011110001100000000111000001010000111100011000000010100000011000001100100001101000111110001000000001110000001100000001100011000'
res = ''


for i in range(len(m)):
    if(m[i]!=c[i]):
        res += "1"
    else:
        res += "0"


print(base64.b16decode(hex(int(res,2))[2:].upper()))

得到flag:

flag{xor_xor_xor_biubiubiu} 

浪里淘沙

下载附件发现文档里全是一些单词拼接起来了,根据题目描述:

我有密集恐惧症,所以大家自求多福吧,把获得的单词连在一起提交即可。(我这里有一串数字:4,8,11,15,16) 注意:得到的 flag 请包上 flag{} 提交

怀疑需要我们进行词频统计,然后按顺序进行拼接,可能就是flag.

这里可以用两种方法去做:

1.使用word文档自带的查找与替换去匹配单词出现次数,可能会比较麻烦。

2.写个脚本导入单词去统计:

f=open("C:/Users/XINO/Desktop/浪里淘沙.txt",'r')
data=f.read()
statistics={}
frequency=[]
num=[4,8,11,15,16]
def zipin(lsit):
    for i in lsit:
        statistics.setdefault(data.count(i),str(i))
        frequency.append(data.count(i))
    frequency.sort()
    for i in num:
        print(''.join(statistics.get(frequency[i-1])),end='')
    print('
')
    return(statistics)
if __name__ == '__main__':
    letters=["tonight","success","notice","example","should","crypto","backspace","learn","found","morning","we","system","sublim","the","user","enter"]
    print(zipin(letters))

之后我们按给的顺序去拼接就可以了,得到flag

flag{weshouldlearnthecrypto}