MT19937预测

首先介绍该模块的用法:主要用于预测随机数 getrandbits(k)

用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> import random
>>> from mt19937predictor import MT19937Predictor
>>> predictor = MT19937Predictor()
>>> for _ in range(624):
... x = random.getrandbits(32)
... predictor.setrandbits(x, 32)
>>> random.getrandbits(32) == predictor.getrandbits(32)
True
>>> random.random() == predictor.random()
True
>>> a = list(range(100))
>>> b = list(range(100))
>>> random.shuffle(a)
>>> predictor.shuffle(b)
>>> a == b
True

解释:可以通过生成predictor预测器,将之前生成的随机数以及位数放入预测器中,即可预测之后的随机getrandbits数。

案例:

这是一道结合aes的随机生成数。

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
38
39
40
41
42
43
44
45
46
47
48
49
from Crypto.Cipher import AES
from binascii import b2a_hex
from libnum import s2n
from random import *
from secret import flag

def add_to_16(text):
if len(text.encode('utf-8')) % 16:
add = 16 - (len(text.encode('utf-8')) % 16)
else:
add = 0
text = text + ('\0' * add)
return text.encode('utf-8')

def init():
r1 = getrandbits(64)
r2 = getrandbits(32)
m = "{:X}".format(r1).encode('utf-8')
salt = "{:X}".format(r2).encode('utf-8')
m += salt
return add_to_16(m.decode())

def encrypt(m, key, iv):
mode = AES.MODE_CBC
cryptos = AES.new(key, mode, iv)
cipher_text = cryptos.encrypt(m)
return cipher_text

def chall(key, iv):
old_m = init()
c = encrypt(old_m, key, iv)
return b2a_hex(c)

if __name__=="__main__":
f = open("msg.txt", 'w+')
old_key = b'73E5602B54FE63A5'
old_iv = b'B435AE462FBAA662'
for i in range(208):
old_c = chall(old_key, old_iv)
f.write("{}\n".format(old_c.decode()))

salt = "{:X}".format(getrandbits(32)).encode('utf-8')
m = flag.encode() + salt
key = "{:X}".format(getrandbits(64)).encode('utf-8')
iv = "{:X}".format(getrandbits(64)).encode('utf-8')
c = encrypt(add_to_16(m.decode()), key, iv)
print("c = %r"%(b2a_hex(c)))

# c = b'c82dc20b7512d03f1a0982eb8a6e855db20f6fe3ff8d202a6fb74c6522fa6e623c6abe6725cafe78f9624ad59f3e90af6f985f38f75ec4d62ff7e02bd7c2f051'

解密思路:

首先根据msg中信息利用aes解密函数还原old_c,发现init中利用了随机数生成,通过old_c还原得到m和salt,放入生成器中,

则后续key,iv即可直接通过生成器进行预测,最终再一次aes解密得到flag。

exp:

xbW79S.png