- Security researcher Matt Brown shows how to read and program blank SIM cards with PySim on Linux, the authentication trick that lets you stand up a private 4G LTE lab and pull IoT devices onto a network you fully control.
TL;DR
To analyze a cellular IoT device's traffic you often need to become the cell tower it talks to. That only works if the device authenticates to your network — which means you need control over the SIM. Matt Brown's new tutorial walks through using PySim, a GPL-2.0 Python toolkit from the Osmocom project, to read and program blank sysmoISIM-SJA2 cards on Linux. With the right IMSI, Ki and OPc loaded, an unlocked Google Pixel happily attaches to his 4G LTE lab network and every byte becomes inspectable.

What's new
Matt Brown (@nmatt0, Brown Fine Security) released a hands-on video showing the exact Linux setup: PC/SC stack, an Omnikey CardMan 3121 USB CCID reader, blank programmable SIMs, and pySim-shell.py driving the whole thing. The contribution is not the tools — those have existed for years — but a clean, reproducible recipe that connects the previously separate worlds of SIM provisioning and private-LTE test benches.
Why it matters
Cellular IoT devices — trackers, LTE routers, smart meters, industrial modems — usually have no Wi-Fi or Ethernet interface. If you cannot see their traffic, you cannot audit them. The classic workaround is to stand up your own eNodeB with srsRAN or OpenAirInterface, but a device only attaches if it trusts the SIM. As Matt puts it: it's mTLS, but with symmetric crypto — both sides share a long-term key Ki and derive session keys via Milenage (AES-128). No Ki, no attach. PySim is what gives the researcher the key.
Without this capability, a huge class of devices sits in a research blind spot. Cellular modems ship firmware updates over the air, talk to carrier APNs with proprietary protocols, and in many cases hard-code IP addresses or TLS pins that you can only observe once you are inside the radio link. Owning the SIM flips that blind spot into a controlled bench.
Technical facts
- PySim supports SIM, UICC, USIM, ISIM, HPSIM and eUICC profiles — one toolkit for the whole 3GPP card family.
- Core binaries:
pySim-shell.py(interactive),pySim-prog.py(batch write),pySim-read.py,pySim-trace.py(APDU decode),osmo-smdpp.py(PoC eSIM SM-DP+). - Python dependencies:
pyscard,pycryptodomex,pyserial,pyyaml >= 5.4. - Values programmed per card: IMSI, Ki, OPc, ICCID, MSISDN, MCC/MNC.
- Hardware in Matt's lab: Omnikey CardMan 3121 reader (~$30) + sysmoISIM-SJA2 programmable SIMs (~€10–15/card).
- Authentication: Milenage — the 3GPP standard AES-128 function that turns
(RAND, Ki, OPc)into(RES, CK, IK). - Test device in the demo: an unlocked Google Pixel, attaching to the MCC/MNC Matt chose.
Comparison: carrier SIM vs programmable SIM
| Aspect | Carrier SIM | Programmable SIM (sysmoISIM-SJA2) |
|---|---|---|
Who holds Ki/OPc | Operator only | You set them |
| ADM key access | Not user-accessible | Ships with card |
| Attach to your own eNodeB | No | Yes — any MCC/MNC |
| Cost | Free with plan | ~€10–15/card |
| Typical use | Phone service | Research, private LTE, labs |
Use cases
- IoT device pentest — inspect, rewrite or fuzz cellular traffic that would otherwise be invisible.
- Modem & baseband research — explore proprietary AT command sets, OTA firmware channels, NB-IoT / LTE-M stacks.
- Protocol fuzzing — craft malformed RRC or NAS messages safely inside an RF-shielded enclosure.
- Private LTE — provision SIMs for factory floors, mining, agriculture and campus networks.
- Education & CTF infrastructure — a reproducible cellular stack for teaching 3GPP security.
Limitations & pricing
Programmable SIMs only work because you provision Ki — you cannot clone a real carrier SIM, the Ki never leaves a production card. Each programmable SIM ships with its own ADM1 key; supply the wrong one and the card bricks permanently. LTE spectrum is licensed, so transmissions must happen inside a shielded enclosure or at very low power to stay legal. 5G NR SA needs newer USIM profiles with 5G AKA support — some older programmable SIMs only cover 4G. And some IoT devices ship with an operator IMSI allowlist and will refuse to attach to arbitrary MCC/MNC pairs, even with a valid SIM.
What's next
This tutorial is the missing prerequisite for the full DIY cellular lab: once the SIM is provisioned, the natural next steps are loading the same credentials into an HSS (Open5GS, srsEPC, OsmoHLR), standing up the eNodeB, capturing NAS and RRC signaling, and fuzzing the device's IP stack once it attaches. The frontier from here is eSIM / eUICC remote provisioning — PySim already ships osmo-smdpp.py as a proof-of-concept SM-DP+, and as more IoT vendors drop physical SIMs for embedded eUICCs, the same research workflow will have to follow. Expect eSIM provisioning to become the next major security research surface, and expect the PySim project to remain at the center of that conversation — it is one of the very few freely available, standards-compliant, vendor-neutral toolkits for talking to real USIM and ISIM applets at the APDU level.
Sources: Matt Brown on X, YouTube tutorial, osmocom/pysim, LibreCellular SIM docs.

