def main(): # Generate random delay time.sleep(utils.random_num(1, 5)) # Get time t = int(time.time()) # Init seed with current time prng = MT19937(t) # Sleep a bit time.sleep(utils.random_num(1, 10)) # Get value v = prng.get_num(); print ("PRNG val = ", v) # Brute-force PRNG seed backwards in time t = int(time.time()); print ("Time now = ", t) for i in range(20000000): seed = t-i # Try seed prng = MT19937(seed) # Get number x = prng.get_num(); # Check if seed found if x==v: print ("Seed is = ", seed) break
def bruteforceseed(num): """Attempts to brute-force the MT19937 seed value using recent (and future) timestamp values)""" for i in range(1472077165, 1482076170): m = MT19937(i) if (m.extract_number() == num): print("Cracked seed value was:", i) return i
def play(): seed = int(time()) res = server.get('casino/playMt', {'id': acc_id, 'bet': 1, 'number': 1}) print(res) real_number = res['realNumber'] i = -2 while True: i += 1 mt = MT19937(seed + i) number = mt.extract_number() if number == real_number: print('seed is', seed + i) break if 'account' in res: money = res['account']['money'] while money < 1000000: next_number = mt.extract_number() print(next_number) res = server.get('casino/playMt', {'id': acc_id, 'bet': int(money / 10), 'number': next_number}) print(res) if 'account' in res: money = res['account']['money'] final_res = server.get('casino/playMt', {'id': acc_id, 'bet': 1, 'number': 1}) print('Final results:', final_res) print('PWNED!')
def randomsleepcrack(): """Waits a random interval, seeds the RNG with the current timestamp, extracts one random integer and returns it""" time.sleep(random.randint(40, 10001)) timestamp = int(time.time()) print("Seeding with timestamp", timestamp) m = MT19937(timestamp) time.sleep(random.randint(40, 10001)) extracted = m.extract_number() print("Random number:", str(extracted)) return extracted
def crackTheSeed(): startTime = int(time.time()) randomOut = generateOracle() endTime = int(time.time()) mt = MT19937(0) for i in range(startTime, endTime + 1): mt.reinitialize(i) bruteOut = mt.temper() if bruteOut == randomOut: print "Found the seed: " + str(i)
def mt19937_stream_encipher(seed, mystr): m1 = MT19937(seed) crypted = bytearray() for i in range(0,len(mystr),4): # Extract a 32-bit integer and break it into bytes myint = m1.extract_number() stream = [myint >> 24, (myint & 16711680) >> 16, (myint & 65280) >> 8, \ myint & 255] segment = mystr[i:i+4] crypted += xor_byte_arrays(segment,stream[:len(segment)]) return crypted
def play(): seed = int(time()) print(seed) print("collecting numbers...") numbers = [] for i in range(623): if i % 25 == 0: print(i, '...') res = server.get('casino/playBetterMt', { 'id': acc_id, 'bet': 1, 'number': 1 }) real_number = res['realNumber'] numbers.append(real_number) res = server.get('casino/playBetterMt', { 'id': acc_id, 'bet': 1, 'number': 1 }) real_number = res['realNumber'] numbers.append(real_number) print("collected numbers, transforming...") transformed_numbers = list(map(lambda x: undo_transformation(x), numbers)) print("transformed numbers, playing...") mt = MT19937(transformed_numbers, True) if 'account' in res: money = res['account']['money'] while money < 1000000: next_number = mt.extract_number() print(next_number) res = server.get('casino/playBetterMt', { 'id': acc_id, 'bet': int(money / 10), 'number': next_number }) print(res) if 'account' in res: money = res['account']['money'] final_res = server.get('casino/playBetterMt', { 'id': acc_id, 'bet': 1, 'number': 1 }) print('Final results:', final_res) print('PWNED!')
def main(): # Initialize PRNG with random seed prng = MT19937(int(time.time())) # Clone PRNG cloned_prng = clone_prng(prng) # Test cloned PRNG for i in range(1000): x = prng.get_num() y = cloned_prng.get_num() if x != y: print(x, y) print('PRNG was not cloned successfully') return print('PRNG was cloned successfully')
def generateOracle(): waitTime_1 = random.randint(40, 1000) waitTime_2 = random.randint(40, 1000) time.sleep(waitTime_1) mt = MT19937(int(time.time())) time.sleep(waitTime_2) first = mt.temper() return first
def decrypt(key, cipher): if len(key) > 16: raise Exception("key greater than 16 bits") keyStream = '' cipherLen = len(cipher) seed = int(key,2) mt = MT19937(seed) for i in range(cipherLen/8 + 1): keyStream += hex(mt.temper())[2:].zfill(8).rstrip('L') keyLen = len(keyStream) diffBytes = (keyLen - cipherLen) if diffBytes > 0: tempKeyStream = keyStream[:(-1)*diffBytes] return fixedXOR(tempKeyStream, cipher) else: return fixedXOR(keyStream, cipher)
def encrypt(key, message): if len(key) > 16: raise Exception("key greater than 16 bits") keyStream = '' message = message.encode("hex") msgLen = len(message) seed = int(key,2) mt = MT19937(seed) for i in range(msgLen/8 + 3): keyStream += hex(mt.temper())[2:].zfill(8).rstrip('L') keyLen = len(keyStream) diffBytes = (keyLen - msgLen) if diffBytes > 0: tempKeyStream = keyStream[:(-1)*diffBytes] return fixedXOR(tempKeyStream, message) else: return fixedXOR(keyStream, message)
def messageRecovery(): original = "HELLO" oracle = recoveryOracle() cipher = oracle.encrypt(original) message = oracle.decrypt(cipher) # HELLO failed = oracle.decrypt(cipher) # [*] failed decryption with error # get all necessary data for attack N = oracle.n e = oracle.e S = 0 while S < 1: S = MT19937(int(time.time())).getNumber() % N # start attack intercepting ciphertext cipherPrime = (modexp(S, e, N) * cipher) % N plainPrime = bytes_to_long(oracle.decrypt(cipherPrime)) recovered = long_to_bytes(plainPrime * modinv(S, N) % N) assert recovered == message == original
def clone_prng(prng): # Get 624 PRNG outputs, for each output unroll PRNG state mt = [] for i in range(624): mt += [unroll_state(prng.get_num())] return MT19937(0, mt)
y = y ^ ((y << 7) & bitmask) # 133169152 = '111111100000000000000000000' bitmask = 2636928640 & 133169152 y = y ^ ((y << 7) & bitmask) # 4160749568 = '11111000000000000000000000000000' bitmask = 2636928640 & 4160749568 y = y ^ ((y << 7) & bitmask) # inverse of: y = y ^ (y >> 11) y = y ^ ((y >> 11) & 2096128) y = y ^ ((y & 2095104) >> 11) return y print("Initializing our RNG to-be-cloned with a random seed value...\n") original = MT19937(random.randint(0, 500000)) # The seed value shouldn't matter since we'll be # overriding the class's state array and index print("Initializing our RNG to-be-cloned-into...\n") clone = MT19937(0) savestate = [] print("Extracting 624 random numbers from our original RNG, \ inverting them and placing them into a temporary array...\n") for i in range(0, 624): n = original.extract_number() savestate.append(untemper(n)) print("Transplanting our cloned state array into our clone RNG \ and resetting its index to 0...\n")
def unshift(Y, S, M, D): M = int_to_bin(M) recovered_x = [None] * w if D == 1: start, end = 0, w else: start, end = w - 1, -1 for i in range(start, end, D): if 0 <= i - D * S < w: recovered_x[i] = Y[i] ^ (recovered_x[i - D * S] & M[i]) else: recovered_x[i] = Y[i] return recovered_x def recover(output): x = int_to_bin(output) x = unshift(x, l, w_bit_mask, 1) x = unshift(x, t, c, -1) x = unshift(x, s, b, -1) x = unshift(x, u, d, 1) return bin_to_int(x) return [recover(output) for output in known_output] RNG = MT19937() seen = [RNG.extract_number() for _ in range(624)] recovered = recover_state(seen) assert(recovered == RNG.get_state()) print(f"Recovered[ : 10] = {recovered[ : 10]}") print(f"Original[ : 10] = {RNG.get_state()[ : 10]}")
def MT19937_encrypt(key, stream): prng = MT19937(key) return bytes([(x ^ prng.get_num()) & 0xFF for x in stream])
from MT19937 import MT19937 import random import time globalMT = MT19937(5987) def generateOracle(): waitTime_1 = random.randint(40, 1000) waitTime_2 = random.randint(40, 1000) time.sleep(waitTime_1) mt = MT19937(int(time.time())) time.sleep(waitTime_2) first = mt.temper() return first def temperOracle(): global globalMT return globalMT.temper() if __name__ == "__main__": print generateOracle() print temperOracle()
def main(): # Init seed prng = MT19937(0) # Print some numbers for i in range(100): print (prng.get_num())
from MT19937 import MT19937 from time import time, sleep from random import randint seed = int(time()) print(f"Actual seed was {seed}") rand_num = MT19937(seed).extract_number() sleep(randint(10, 20)) # PoC start_of_crack = int(time()) for i in range(0, 1000): guess = start_of_crack - i if MT19937(guess).extract_number() == rand_num: print(f"The recovered seed is {guess}") break else: print("Did not recover the seed")
return temp def undoStepOne(y): u = 11 temp = y for i in range(2): temp >>= u temp ^= y return temp mt = MT19937(12345) state = [] for i in range(624): state.append(untemper(temperOracle())) mt.setState(state) mt.regenerate() print mt.temper() print temperOracle() ''' 4th Step Reversal 11010011 00001101 - 4 bit right shift and XOR --------
from MT19937 import MT19937 rng = MT19937(0) for _ in range(10): print(rng.extract_number())
def __init__(self, seed: int): assert (len(bin(seed)[2:]) <= 16) self.__PRNG = MT19937(seed)