laforge has submitted this change. ( 
https://gerrit.osmocom.org/c/pysim/+/42624?usp=email )

Change subject: pySim-prog: fix Insecure PRNG for SIM Authentication Keys 
(CWE-338)
......................................................................

pySim-prog: fix Insecure PRNG for SIM Authentication Keys (CWE-338)

Root Cause:
pySim-prog.py uses Python's random module (Mersenne Twister MT19937) to
generate Ki and OPC — the root authentication keys for SIM cards. MT19937
is a deterministic PRNG that is not cryptographically secure. Its internal
state (624 × 32-bit words, 19,937 bits) can be fully recovered after
observing 624 consecutive outputs.

Impact:
1. SIM Card Cloning: An attacker who determines the PRNG state can predict
all Ki/OPC values generated before and after. With these keys, SIM cards
can be cloned.
2. Network Authentication Bypass: Ki/OPC are used in the Milenage algorithm
for 3G/4G/5G authentication. Predictable keys mean an attacker can
authenticate as any subscriber whose SIM was provisioned with the weak RNG.
3. Batch Compromise: In bulk provisioning scenarios (pySim-prog's primary
use case), hundreds or thousands of SIMs may be programmed sequentially.
Compromising one batch means recovering the PRNG state to predict all keys.

Fix:
Replace random.randrange() with os.urandom()

Change-Id: Id3e00d3ec5386f17c1525cacfc7d3f5bba43381f
---
M pySim-prog.py
1 file changed, 2 insertions(+), 3 deletions(-)

Approvals:
  osmith: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved
  Jenkins Builder: Verified




diff --git a/pySim-prog.py b/pySim-prog.py
index 3f2bb94..6111fc1 100755
--- a/pySim-prog.py
+++ b/pySim-prog.py
@@ -27,7 +27,6 @@
 import hashlib
 import argparse
 import os
-import random
 import re
 import sys
 import traceback
@@ -436,7 +435,7 @@
         if not re.match('^[0-9a-fA-F]{32}$', ki):
             raise ValueError('Ki needs to be 128 bits, in hex format')
     else:
-        ki = ''.join(['%02x' % random.randrange(0, 256) for i in range(16)])
+        ki = os.urandom(16).hex()

     # OPC (random)
     if opts.opc is not None:
@@ -447,7 +446,7 @@
     elif opts.op is not None:
         opc = derive_milenage_opc(ki, opts.op)
     else:
-        opc = ''.join(['%02x' % random.randrange(0, 256) for i in range(16)])
+        opc = os.urandom(16).hex()

     pin_adm = sanitize_pin_adm(opts.pin_adm, opts.pin_adm_hex)


--
To view, visit https://gerrit.osmocom.org/c/pysim/+/42624?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Id3e00d3ec5386f17c1525cacfc7d3f5bba43381f
Gerrit-Change-Number: 42624
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: osmith <[email protected]>

Reply via email to