PRNG Attacks
Randomness
Pseudo-random number generators (PRNGs) are deterministic algorithms. Using weak PRNGs or predictable seeds for security-sensitive operations leads to exploitable vulnerabilities.
Weak vs Secure PRNGs
❌ Insecure (Never for Crypto)
- • Math.random() (JavaScript)
- • random.random() (Python)
- • rand() (C/PHP)
- • java.util.Random
✓ Cryptographically Secure
- • crypto.randomBytes() (Node.js)
- • secrets.token_bytes() (Python)
- • /dev/urandom (Linux)
- • java.security.SecureRandom
Cracking Weak PRNGs
python
# Python random uses Mersenne Twister (MT19937)
# With 624 consecutive outputs, can predict all future values
# z3 solver approach
from z3 import *
def crack_mt19937(outputs):
"""Given 624 outputs, recover internal state"""
solver = Solver()
state = [BitVec(f's{i}', 32) for i in range(624)]
for i, output in enumerate(outputs):
# Reverse the tempering transformation
y = state[i]
y = y ^ (LShR(y, 11))
y = y ^ ((y << 7) & 0x9D2C5680)
y = y ^ ((y << 15) & 0xEFC60000)
y = y ^ (LShR(y, 18))
solver.add(y == output)
if solver.check() == sat:
model = solver.model()
return [model[s].as_long() for s in state]
# randcrack - Ready-made tool
# pip install randcrack
from randcrack import RandCrack
rc = RandCrack()
for output in outputs[:624]:
rc.submit(output)
predicted = rc.predict_getrandbits(32)Time-Based Seeds
Seeds based on time (like Unix timestamps) are highly predictable. Attackers can
brute force a small time window to recover the seed.