大家好,欢迎来到IT知识分享网。
一、简介
mt19937算法是梅森旋转算法(Mersenne Twister)的变体,是一个伪随机数发生算法,可以产生32位整数序列。具有以下的优点
二、代码实现
32位的MT19937的python代码如下:
def _int32(x): return int(0xFFFFFFFF & x) class MT19937: # 根据seed初始化624的state def __init__(self, seed): self.mt = [0] * 624 self.mt[0] = seed self.mti = 0 for i in range(1, 624): self.mt[i] = _int32(1812433253 * (self.mt[i - 1] ^ self.mt[i - 1] >> 30) + i) # 提取伪随机数 def extract_number(self): if self.mti == 0: self.twist() y = self.mt[self.mti] y = y ^ y >> 11 y = y ^ y << 7 & 2636928640 y = y ^ y << 15 & 4022730752 y = y ^ y >> 18 self.mti = (self.mti + 1) % 624 return _int32(y) # 对状态进行旋转 def twist(self): for i in range(0, 624): y = _int32((self.mt[i] & 0x80000000) + (self.mt[(i + 1) % 624] & 0x7fffffff)) self.mt[i] = (y >> 1) ^ self.mt[(i + 397) % 624] if y % 2 != 0: self.mt[i] = self.mt[i] ^ 0x9908b0df
三、例题
以昨天打的DASCTF10月赛为例
pycode
阅读pyc字节码后的加密算法如下
def extract_number(x): x = x ^ (x >> 11) x = ((x << 7) & 2022072721) ^ x x = ((x << 15) & 2323163360) ^ x x = (x >> 18) ^ x return x def transform(m): new_message = b"" l = len(m) for i in range(l//4): enc = m[i * 4 : i*4+4] enc = number.bytes_to_long(enc) enc = extract_number(enc) enc = number.long_to_bytes(enc,4) new_message += enc #flag提交格式为DASCTF{账号+密码} enc = '8b2e4e858126bc8478d6a6a485215f03' num = input('input your number:') tmp = bytes.fromhex(num) res = hex(transform(tmp)) if enc == res: print(f"ok,your flag : DASCTF\{{num\}}") else: print("wrong")
那么我们有
1、解法一
使得明文通过不断的加密最后还是明文
from Crypto.Random import random from Crypto.Util import number def extract_number(x): x = x ^ (x >> 11) x = ((x << 7) & 2022072721) ^ x x = ((x << 15) & 2323163360) ^ x x = (x >> 18) ^ x return x def transform(message): assert len(message) % 4 == 0 new_message = b'' for i in range(len(message) // 4): block = message[i * 4 : i * 4 +4] block = number.bytes_to_long(block) block = extract_number(block) block = number.long_to_bytes(block, 4) new_message += block return new_message def circle(m): t=m while True: x=t t=transform(t) if t==m: return x transformed_flag='8b2e4e858126bc8478d6a6a485215f03' flag = circle(bytes.fromhex(transformed_flag)).hex() print('transformed_flag:', flag) # DASCTF{89196e63ab5556e7389d2bb44f8e6e06}
2、解法二
逆向 extract_number函数
# 解法二 from Crypto.Util import number # right shift inverse def inverse_right(res, shift, bits=32): tmp = res for i in range(bits // shift): tmp = res ^ tmp >> shift return tmp # right shift with mask inverse def inverse_right_mask(res, shift, mask, bits=32): tmp = res for i in range(bits // shift): tmp = res ^ tmp >> shift & mask return tmp # left shift inverse def inverse_left(res, shift, bits=32): tmp = res for i in range(bits // shift): tmp = res ^ tmp << shift return tmp # left shift with mask inverse def inverse_left_mask(res, shift, mask, bits=32): tmp = res for i in range(bits // shift): tmp = res ^ tmp << shift & mask return tmp # def extract_number(x): # x = x ^ (x >> 11) # x = ((x << 7) & 2022072721) ^ x # x = ((x << 15) & 2323163360) ^ x # x = (x >> 18) ^ x # return x def convert(y): y = inverse_right(y,18) y = inverse_left_mask(y,15, 2323163360) y = inverse_left_mask(y,7,2022072721) y = inverse_right(y,11) return y&0xffffffff def transform(message): assert len(message) % 4 == 0 new_message = b'' for i in range(len(message) // 4): block = message[i * 4 : i * 4 +4] block = number.bytes_to_long(block) block = convert(block) block = number.long_to_bytes(block, 4) new_message += block return new_message transformed_flag = '8b2e4e858126bc8478d6a6a485215f03' c = bytes.fromhex(transformed_flag) flag = transform(c) print (flag.hex())
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/30690.html