本次算是被QCTF打趴了,本来做题时间就少(公司无限开会,开了一天,伪借口),加上难度和脑洞的增大,导致这次QCTF又酱油了。。。就连最基本的签到题都没做出来。。。这就很气
好了,以下是解题思路
MISC
0x01 X-man-A face
下载附件,得到图片
简单拖进binwalk扫一下,无果,查看附件属性信息,无果。
最后尝试补全一下图中的二维码
打开画图工具,键盘拼接一下,得到
扫描图中二维码,居然可以扫出东西,得到
KFBVIRT3KBZGK5DUPFPVG2LTORSXEX2XNBXV6QTVPFZV6TLFL5GG6YTTORSXE7I=
base64走起,没用
那base32走起,得到flag:QCTF{Pretty_Sister_Who_Buys_Me_Lobster}
0x02 X-man-Keyword
签到题,下载图片得到
提取图片信息
PVSF{vVckHejqBOVX9C1c13GFfkHJrjIQeMwf}
根据提示,搜索置换密码等关键字,查到该加密方式是Nihilist加密。
简单说一下原理
原26个英文字母为ABCDEFGHIJKLMNOPQRSTUVWXYZ
把关键字提前后为LOVEKFCABDGHIJMNPQRSTUWXYZ
在置换后的序列里可以发现对应关系P=Q,V=C,S=T,F=F。。。。。
规律确认无误后,最后通过脚本解出
# coding=utf-8 # author:401219180 import string enc = 'PVSF{vVckHejqBOVX9C1c13GFfkHJrjIQeMwf}' grid = 'LOVEKFC' + 'ABDGHIJMNPQRSTUWXY' flag = '' for i in enc: if i in string.ascii_lowercase: index = grid.lower().index(i) flag += string.ascii_lowercase[index] continue if i in string.ascii_uppercase: index = grid.upper().index(i) flag += string.ascii_uppercase[index] continue flag += i print flag
Crypto
0x01 babyRSA
最开始以为是一道常规的RSA破解,直接丢进msieve和yafu,fatorydb等跑起来。。。
。。。
。。。
。。。
跑炸了都没出个有用的东西。。。
就此卡住,先nc 47.96.239.28 23333看看后面的题目
发现是提供一个密文,系统会返回even和odd
于是联想到最低有效位(LSB)oracle攻击 (后来才知道的。。。)
从出题大佬那里py到的提示:https://crypto.stackexchange.com/questions/11053/rsa-least-significant-bit-oracle-attack
仍然看不懂。。。后来又找到了一个中文版:https://introspelliam.github.io/2018/03/27/crypto/RSA-Least-Significant-Bit-Oracle-Attack/
这里说一下我理解的大概原理:
如果我们已经知道公钥中N,e,c,那么我们就可以通过构造任意构造密文c1,即c1=(2**e mod n)*c,作为密文发送出去,根据返回此密文解密后p1的末尾某些比特位的性质(记为函数f),求得原始明文信息!
最简单的函数f 是表示 p 的奇偶性(即even和odd)。
若返回f(2P)
如果f(2P)f(2P) 返回的最后一位是0,那么2P<N2P<N,即P<N/2P<N/2
如果f(2P)f(2P) 返回的最后一位是1,那么2P>N2P>N,即 P>N/2P>N/2
接着我们来看看2P2P 和 4P4P
如果返回的是(偶,偶),那么有 P<N/4P<N/4
如果返回的是(偶,奇),那么有N/4<P<N/2N/4<P<N/2
如果返回的是(偶,奇),那么有N/2<P<3N/4N/2<P<3N/4
如果返回的是(奇,奇),那么有3N/4<P<N3N/4<P<N
结论就是
如果我们循环下去,基本上就可以得到P所处在的空间。当次数不断叠加,最终所处在的空间将会十分的小,于是就可以解出对应的解!
P∈[0,P] 也即LB=0, UB=N
使用log2 Nlog2 N 次可以根据密文C 求解出明文P
C′=(2e mod N)∗C
if (Oracle(C') == even): UB = (UB + LB)/2; else: LB = (UB + LB)/2;
模仿了写法,求得LB
# coding=utf-8 # author:401219180 import binascii import socket def getevenOrodd(c): """nc连接获取even or odd""" adress = "47.96.239.28" port = 23333 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((adress, int(port))) s.recv(1024) data = hex(c)[:-1] + "\n" s.send(data) codeindex = s.recv(1024) s.shutdown(1) s.close() print codeindex return codeindex def decrypt(n): LB = 0 UB = n e = 65537 c = int("0x4f377296a19b3a25078d614e1c92ff632d3e3ded772c4445b75e468a9405de05d15c77532964120ae11f8655b68a630607df0568a7439bc694486ae50b5c0c8507e5eecdea4654eeff3e75fb8396e505a36b0af40bd5011990663a7655b91c9e6ed2d770525e4698dec9455db17db38fa4b99b53438b9e09000187949327980ca903d0eef114afc42b771657ea5458a4cb399212e943d139b7ceb6d5721f546b75cd53d65e025f4df7eb8637152ecbb6725962c7f66b714556d754f41555c691a34a798515f1e2a69c129047cb29a9eef466c206a7f4dbc2cea1a46a39ad3349a7db56c1c997dc181b1afcb76fa1bbbf118a4ab5c515e274ab2250dba1872be0",16) while LB != UB: c1 = (pow(2, e, n) * c) % n if getevenOrodd(c1)[:-1] == "even": UB = (UB + LB) / 2 else: LB = (UB + LB) / 2 c = c1 print LB n=int("0x0b765daa79117afe1a77da7ff8122872bbcbddb322bb078fe0786dc40c9033fadd639adc48c3f2627fb7cb59bb0658707fe516967464439bdec2d6479fa3745f57c0a5ca255812f0884978b2a8aaeb750e0228cbe28a1e5a63bf0309b32a577eecea66f7610a9a4e720649129e9dc2115db9d4f34dc17f8b0806213c035e22f2c5054ae584b440def00afbccd458d020cae5fd1138be6507bc0b1a10da7e75def484c5fc1fcb13d11be691670cf38b487de9c4bde6c2c689be5adab08b486599b619a0790c0b2d70c9c461346966bcbae53c5007d0146fc520fa6e3106fbfc89905220778870a7119831c17f98628563ca020652d18d72203529a784ca73716db",16) decrypt(n)
LB=560856645743734814774953158390773525781916094468093308691660509501812320
这里的LB也就是明文P(Plaintext)
最后int转ascii即可
LB = 560856645743734814774953158390773525781916094468093308691660509501812320 plaintext = binascii.unhexlify(hex(LB)[2:-1]) print(plaintext)
plaintext =QCTF{RSA_parity_oracle_is_fun`
0x02 Xman-RSA
下载题目附件得到
依次点开查看,分析
应该是从encryption.encrypyed入手
从原文可以看出,这个语法有点像python,可能是python源码被做了简单的移位加密,例如gqhb=from,adg=def,urtd64应该是base64。。。
这里应该不是凯撒加密,移位的数字是没有规律的,所以只能一点一点的摸索猜测密文和明文字母的对应关系,如果熟悉python,就能猜出
最后人工手写出解密脚本
cpdic = { "a": "d", "d": "e", "g": "f", "q": "r", "h": "o", "b": "m", "u": "b", "r": "a", "t": "s", "p": "i", "k": "p", "w": "t", "z": "u", "e": "n", "x": "c", "y": "l", "l": "y", "f": "w", "m": "h", "j": "g", "i": "x", "v": "k" } f1 = open("C:\\Users\\fuzhi\\Desktop\\Downloads\\encryption.encrypted", "r") //本地文件 data1 = f1.read() listdata1 = list(data1) i = 0 for strindex in listdata1: if strindex in cpdic: listdata1[i] = cpdic[strindex] i += 1 s = "".join(listdata1) print s
来源:https://www.cnblogs.com/semishigure/p/9318258.html