BUUCTF-CRYPTO-[V&N2020 公开赛]Backtrace
每天一题,只能多不能少
[V&N2020 公开赛]Backtrace
题目分析
1、MT19937随机数破解
2、随机数状态state逆向破解
开始
1.题目
题目很简单,给了生产脚本backtrace.py
# !/usr/bin/env/python3
import random
flag = "flag{" + ''.join(str(random.getrandbits(32)) for _ in range(4)) + "}"
with open('output.txt', 'w') as f:
for i in range(1000):
f.write(str(random.getrandbits(32)) + "\n")
print(flag)
2.分析
MT19937随机数破解的破解,恕我这个数学白痴理解不能啊。。。
这里只能简单的说一下我理解的“结论”。
(1)MT19937算法生产随机数的过程
1.利用seed初始化624的状态
2.对状态进行旋转
3.根据状态提取伪随机数
(2)逆向 extract_number
extract_number函数,可以发现输出的伪随机数是对state[i]进行了异或,位运算后的结果。预测随机数的题型就是基于对extract_number 函数的逆向,我们可以根据题目输出的随机数逆向extract_number得到对应的n个state(n>624),实际上只需要前624个随机数恢复前624个state,就可以预测此后生成的随机数。
(3)逆向twist
在已知连续624个随机数时(state没有进行twist),可以还原state,预测后续的随机数。那么如何获得624个随机数之前的随机数呢?此时可以考虑,逆向twist获得前一组的state,进而获得前一组的624个随机数。
此题就是一个逆向twist。
3.解题思路
题目要求恢复前四个随机数(就是flag)。
这里要提一点的是不要纠结那个‘_’,其实跟Ii没有区别。就是连续取4个随机数的意思。
前面说过。逆向twist我们需要连续的624个随机数才能获得上一组随机数的状态,这里只有1000个随机数,这里的前4位随机数丢失,而前4位随机数产生的新状态对应第624,625,626,627位随机数的状态,而他们的状态是可逆的。所以不需要完整的连续624个随机数,也可以求解完整的state。
说实话还是不大理解,但是大概可以知道就是我们可以用后面产生的1000个随机数,利用随机数状态可逆的问题,反向(backtrace)得到之前产生的随机数。