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

crack-prng.py
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.