Weak randomness (RNG)
A huge amount of security depends on unpredictable random numbers: keys, IVs/nonces, session tokens, password resets, OTPs, identifiers. When the generator is weak or predictable, the attacker predicts those values and breaks the system without touching the cryptography itself.
CSPRNG vs regular PRNG
Section titled “CSPRNG vs regular PRNG”Standard PRNG (rand(), Math.random(), mt_rand, java.util.Random) fast but PREDICTABLE: given enough output, the state is recovered and the rest predicted NEVER for anything security-related
CSPRNG (cryptographically secure) /dev/urandom, getrandom(), secrets (Python), crypto.randomBytes (Node), SecureRandom (Java), RNGCryptoServiceProvider/.NET designed so output is unpredictable even knowing previous outputsTypical flaws (what’s exploitable)
Section titled “Typical flaws (what’s exploitable)”Predictable seed seed = time() or PID -> small seed space -> brute forceNon-crypto PRNG for tokens session/reset tokens generated with rand()/Mersenne Twister -> recover the state and predict future/past tokensInsufficient entropy at boot IoT/VM devices generate keys with little entropy -> REPEATED or factorable KEYS across devicesPredictable or fixed nonce/IV breaks CTR/GCM/CBC (see crypto-sym)Repeated k in (EC)DSA reusing the nonce 'k' when signing REVEALS the private keyPredicting Mersenne Twister (lab)
Section titled “Predicting Mersenne Twister (lab)”# MT19937 (used by PHP's mt_rand, Python's random, Math.random in many runtimes):# with 624 consecutive 32-bit outputs you reconstruct the internal state and predict everything# tool: randcrack (Python)from randcrack import RandCrackrc = RandCrack()for v in observed_624: rc.submit(v)rc.predict_randint(0, n) # next "random" value# real application: predictable tokens/IDs -> account takeover, OTP bypassRepeated nonce in ECDSA/DSA signatures
Section titled “Repeated nonce in ECDSA/DSA signatures”# if two signatures use the SAME k: with both signatures (r,s1),(r,s2) and the messages# you solve for k and then the PRIVATE KEY. Historic case: PS3 (Sony) signed with a fixed k.# detection: the same r value in two distinct signatures = repeated kTwin keys from low entropy
Section titled “Twin keys from low entropy”# large-scale studies of public RSA keys on the Internet found keys sharing a prime# (GCD between moduli != 1) from weak RNG at router/IoT boot -> trivial factorization- randcrack (MT19937), language-specific PRNG crackers, sage/z3 to model.
- openssl/msieve/yafu for the factoring part; token analysis with Burp Sequencer (session randomness quality).
Defense
Section titled “Defense”- Always use a CSPRNG from the system for keys, IVs/nonces, tokens, resets, and OTPs (
secrets,crypto.randomBytes,SecureRandom). - Unique nonce/
kper operation (or deterministic signing RFC 6979 in ECDSA); random IV. - Ensure sufficient entropy at boot (hardware RNG, don’t generate keys on first boot without entropy).
- Long (≥128-bit), opaque tokens; audit with Burp Sequencer.
CVEs and real-world cases
Section titled “CVEs and real-world cases”- Debian OpenSSL (CVE-2008-0166): a patch cut entropy → predictable SSH/SSL keys worldwide.
- PS3 / fail0verflow (2010): ECDSA with a fixed
krevealed Sony’s signing key. - Mining your Ps and Qs (2012): RSA/DSA keys factorable via shared primes (weak RNG in IoT).
- Numerous predictable-reset-token bugs from using a non-cryptographic PRNG.
Testing checklist
Section titled “Testing checklist”- Identify what uses randomness (tokens, resets, OTP, IV/nonce, keys)
- Non-cryptographic PRNG (rand/mt_rand/Math.random)?
- Collect outputs and try prediction (randcrack for MT19937)
- Tokens/IDs: sequential or predictable? (Burp Sequencer)
- ECDSA/DSA signatures: repeated
rvalue? → reused k - RSA keys: shared primes (GCD)? (low entropy)
- Verify CSPRNG and RFC 6979 use in the defense