[NPUCTF2020]Mersenne twister(mt73991伪随机)

本文介绍了NPUCTF2020中涉及的Mersenne twister mt73991伪随机数生成器的解题思路。由于题目给出的序列长度不足,无法直接逆向,作者提出了通过爆破方法来求解,并指出Python性能可能不足,建议使用C/C++。关键在于逆向Next()函数,通过一系列移位和异或操作还原随机数生成过程。通过已知的明文字符推测初始种子,验证得到正确的随机数序列,从而解密整个问题。
摘要由CSDN通过智能技术生成

encrypt

from hashlib import *
from itertools import *
from binascii import hexlify , unhexlify

from flag import flag ,seed

assert len(flag) == 26
assert flag[:7] == 'npuctf{'
assert flag[-1] == '}'

XOR = lambda s1 ,s2 : bytes([x1 ^ x2 for x1 ,x2 in zip(s1 , s2)])

class mt73991:
    def __init__(self , seed):
        self.state = [seed] + [0] * 232
        self.flag = 0
        self.srand()
        self.generate()
    def srand(self):
        for i in range(232):
            self.state[i+1] = 1812433253 * (self.state[i] ^ (self.state[i] >> 27)) - i
            self.state[i+1] &= 0xffffffff


    def generate(self):
        for i in range(233):
            y = (self.state[i] & 0x80000000) | (self.state[(i+1)%233] & 0x7fffffff)
            temp = y >> 1
            temp ^= self.state[(i + 130) % 233]
            if y & 1:
                temp ^= 0x9908f23f
            self.state[i] = temp
    def getramdanbits(self):
        if self.flag == 233:
            self.generate()
            self.flag = 0
        bits = self.Next(self.state[self.flag]).to_bytes(4 , 'big')
        self.flag += 1
        return bits
        
    def Next(self , tmp):
        tmp ^= (tmp >> 11)
        tmp ^= (tmp << 7) & 0x9ddf4680
        tmp ^= (tmp << 15) & 0xefc65400
        tmp ^= (tmp >> 18) & 0x34adf670
        return tmp

def encrypt(key , plain):
    tmp = md5(plain).digest()
    return hexlify(XOR(tmp , key))

if __name__ == "__main__":
    flag = flag.encode()
    random = mt73991(seed)
    f = open('./cipher.txt' , 'wb')
    for i in flag:
        key = b''.join([random.getramdanbits() for _ in range(4)])
        cipher = encrypt(key , chr(i).encode())
        f.write(cipher)

decrypt

这是一道伪随机的题目,mt73991算法.题目并未给我们足够长的序列,也就是说不能逆向回去,因此想到可能要爆破,考虑到python的性能并不是很好,因此在c/c++中爆破较好(实际上计算机的好坏也影响很大).
首先先要逆向Next()函数.该函数是由一系列的移位异或运算得到的.(与运算用作掩码)
因此在每个式子中只需分段一段一段还原即可.

def reverse1(x):
    x1=x[:18]
    tmp=eval('0b'+x[:14])&(eval('0b'+bin(0x34adf670)[2:][-14:
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值