题目信息

题目背景为在一次考试中两名学生作弊,给出他们的RSA公钥,附件两者通信的pcapng流量包。

分析

鉴于Alice与Bob的密钥位数如此地低,通过yafu或者去factordb立马就分解出模数,进而计算出私钥。

用wireshark打开流量包,按下Ctrl+Alt+Shift+T快捷键来追踪TCP流(并保存下来,比如我保存为data.txt);通过数据格式应该可以确定是base64编码后的数据格式,那么先解码前三个看看编码的数据;

1
2
3
SEQ = 13; DATA = 0x3b04b26a0adada2f67326bb0c5d6L; SIG = 0x2e5ab24f9dc21df406a87de0b3b4L;
SEQ = 0; DATA = 0x7492f4ec9001202dcb569df468b4L; SIG = 0xc9107666b1cc040a4fc2e89e3e7L;
SEQ = 5; DATA = 0x94d97e04f52c2d6f42f9aacbf0b5L; SIG = 0x1e3b6d4eaf11582e85ead4bf90a9L;

DATA应该是密文,但是另外两个数据也很重要,SEQ是明文的顺序,SIG是对明文的签名;因此对保存的TCP流依次解码,使用Bob的私钥对密文DATA解密,再验证SIG是否为Alice对明文的签名,如果是则放到明文列表的第SEQ位置;

解题

实现的Python脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from Crypto.PublicKey import RSA
from gmpy2 import invert,powmod
from base64 import b64decode

def solve():
N1=0x53a121a11e36d7a84dde3f5d73cfL
N2=0x99122e61dc7bede74711185598c7L
e=0x10001L
# p1,q1=38456719616722997L,44106885765559411L
p2,q2=49662237675630289L,62515288803124247L

# phi1=(p1-1)*(q1-1)
phi2=(p2-1)*(q2-1)
# d1=invert(e,phi1)
d2=invert(e,phi2)

# rsa_key1=RSA.construct((N1,e,long(d1),p1,q1))
rsa_key2=RSA.construct((N2,e,long(d2),p2,q2))

with open('data.txt','r') as f:
data=f.read()

cips=data.split('\n')
res=['']*len(cips)
for cip in cips[:-1]:
data=b64decode(cip)
seq=int(data[(data.find('= ')+2):data.find(';')])
cipher=data[(data.find('x')+1):data.find('L')]
sig=data[(data.rfind('x')+1):data.rfind('L')]
msg=rsa_key2.decrypt(long(cipher,16))
if msg==powmod(long(sig,16),e,N1):
res[seq]+=chr(msg)
return res

if __name__=='__main__':
#python solve.py
print ''.join(solve())

运行结果如下:

1
2
$ python solve.py
flag{n0th1ng_t0_533_h3r3_m0v3_0n}