青少年ctf-random(梅森算法-MT19973)

题目

import random
from hashlib import md5

def get_mask():
    file = open("random.txt","w")
    for i in range(104):
        file.write(str(random.getrandbits(32))+"\n")
        file.write(str(random.getrandbits(64))+"\n")
        file.write(str(random.getrandbits(96))+"\n")
    file.close()
get_mask()
flag = md5(str(random.getrandbits(32)).encode()).hexdigest()
print(flag)

附件

这道题的漏洞在于这个函数:

random.getrandbits(32)

MT19973算法能生成1-623个32位随机数,而我们有 (32/32+64/32+96/32)*104=624个已知随机数,那么我们就完全可以求出下一个随机数。

这里生成的一组数据里分别是32位、64位、96位,这里我们只需要32位,所以需要把64位和96位的数分成两个或者三个32位数,可以用它们与32位全为1的二进制数来分离。

这里可以直接引用RandCrack库,将已经生成的624个数按顺序传入RandCrack函数里,利用predict_getrandbits来计算出下一个32位随机数,再使用md5加密一下就可以得到flag。

exp:

from randcrack import RandCrack
from hashlib import md5

with open(r'random.txt','r') as f:
    l = f.readlines()
l = [int(i.strip()) for i in l]  #strip函数用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列,这里就默认为空格
arr = []
#print(l)
for i in range(len(l)):
    if i %3 == 0:
        arr.append(l[i])              #第三位数或三的倍数位就是32位数,直接加入
    elif i %3 == 1:
        arr.append(l[i] & (2**32-1))  #64位数,包含两个32位数,取第一个32位数,64位与32个1按位与,结果剩下低位32位
        arr.append(l[i] >> 32)        #右移32位,保留高位32位
    else:
        arr.append(l[i] & (2**32-1))         #保留低32位
        arr.append(l[i] & (2**64-1)>>32)     #保留中间32位
        arr.append(l[i]>>64)                 #保留高32位
rc = RandCrack()                            #解题关键函数
for i in arr:
    rc.submit(i)                            #按顺序传入RandCrack函数
flag = rc.predict_getrandbits(32)           #预测下一个32位数
print(md5(str(flag).encode()).hexdigest())  #md5加密

flag{14c71fec812b754b2061a35a4f6d8421}

成功拿到flag!!!

总结:梅森算法 预测随机数 randcrack库

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余切66

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值