The fetch handler tried to cache every intercepted request, so a chrome-extension:// request made cache.put() throw 'Request scheme chrome-extension is unsupported'. Skip non-http(s) and non-GET requests, and swallow cache-write failures.
simtrace2-pysniff
Python-based replacement for simtrace2-sniff — SIM card communication sniffer
for Osmocom SIMtrace2 hardware (firmware in trace mode). It bundles the
simtrace-analyser PWA (in frontend/) and an analysis server
that both captures APDU traffic and serves that PWA.
Single dependency: PyUSB (libusb wrapper). No libosmocore, no libosmosim.
Prerequisites
- Python 3.9+
- PyUSB —
pip install pyusb - libusb — system library, present by default on Linux; on Windows the SIMtrace2 driver must be swapped (see USB Device Access)
- SIMtrace2 hardware running firmware in trace mode
(VID
1d50, PID60e3, USB classff, subclass01). For building and flashing trace firmware, see the upstream SIMtrace2 project.
No other dependencies. PCAP, GSMTAP, and hex dump output use only Python stdlib.
Install
git clone https://github.com/anttro/simtrace2-pysniff.git
cd simtrace2-pysniff
pip install pyusb
Or install the package into your environment:
pip install -e .
# then run: simtrace2-pysniff [opts]
Running
Two tools are provided:
Sniffer CLI (simtrace2-pysniff)
Captures SIMtrace2 traffic and writes it to stdout, GSMTAP (Wireshark), or PCAP files.
Startup script (Linux only)
./sniff-start.sh performs a pre-flight USB permission check (prints udev
install instructions if the SIMtrace2 device is not writable) and then
launches the Python module.
./sniff-start.sh
./sniff-start.sh --format timestamp
./sniff-start.sh --gsmtap 127.0.0.1:4729
./sniff-start.sh --pcap trace.pcap --format atr-time
OPTIONS can also be set via environment variables:
FORMAT=timestamp GSMTAP=127.0.0.1 ./sniff-start.sh
Analysis server + PWA (simtrace2-pysniff-server)
Stores captured APDU traffic in SQLite and serves it over HTTP, together with
the bundled simtrace-analyser PWA (frontend/) on the same origin. Two
capture modes:
# Listen for GSMTAP from simtrace2-pysniff (or original simtrace2-sniff):
simtrace2-pysniff-server --capture gsmtap
# Capture directly from SIMtrace2 hardware (no external tool needed):
simtrace2-pysniff-server --capture direct
Then open http://127.0.0.1:8081/ in a browser — the PWA is served by the
server, so the UI and the API share an origin and no CORS/Private-Network-Access
setup is involved. Use --web-dir PATH to serve a different PWA directory
(default: <repo>/frontend).
Hosted PWA (landing page)
A standalone copy of the PWA is hosted at https://simtrace.atroshin.ru.
It is a pure frontend: point it (Settings → Server URL) at a locally running
simtrace2-pysniff-server.
Browser restriction: when the PWA is served from a public HTTPS host, reaching a local server (
http://127.0.0.1:8081) requires two things: the server must sendAccess-Control-Allow-Private-Network: true(this server does), and the browser must be allowed to access the local network — in Chrome/Edge/Vivaldi: Site settings → Local network access → allow the site (or accept the permission prompt). Without the browser permission, the request to127.0.0.1is blocked before any preflight is sent.
Python module (cross-platform)
python -m simtrace2_pysniff
python -m simtrace2_pysniff --format timestamp --gsmtap 127.0.0.1:4729
python -m simtrace2_pysniff --pcap trace.pcap
If installed via pip install -e ., use the console script directly:
simtrace2-pysniff --format atr-time
USB Device Access
Linux
A udev rule is required for non-root USB access to the SIMtrace2 device.
sudo cp 70-simtrace2-pysniff.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
Then reconnect the SIMtrace2 USB cable. The rule uses TAG+="uaccess"
(systemd-logind ACL) — no group membership or world-writable permissions needed.
Windows
Windows does not ship a libusb-compatible driver for SIMtrace2. Use Zadig to replace the default driver:
- Download and run Zadig
- Plug in the SIMtrace2 device
- Select it in the dropdown (VID
1D50, PID60E3— "Osmocom SIMtrace 2") - Choose WinUSB (or libusbK) as the replacement driver
- Click Replace Driver (one-time operation)
After that, python -m simtrace2_pysniff works identically to Linux.
CLI Options
python -m simtrace2_pysniff [OPTIONS]
--format, -f FORMAT Output format (default: hex)
hex — plain hex dump
timestamp — TPDU lines prefixed with [HH:MM:SS.mmm]
atr-time — TPDU lines prefixed with [SSSS.mmm] from last ATR
--gsmtap HOST[:PORT] Send ATR/TPDU as GSMTAP over UDP (default port 4729)
--pcap FILE Write sniffed data to PCAP file for Wireshark
--output, -o FILE Write hex dump to file
--no-stdout Suppress hex dump to stdout
--vendor HEX USB vendor ID (default: 0x1d50)
--product HEX USB product ID (default: auto-detect)
Recovery options:
--no-reconnect Exit on USB disconnect instead of reconnecting
--inactivity-timeout SEC Reconnect after N seconds of silence (default: disabled)
Output Formats
hex(default): plain hex dump —ATR: 3b 9e ...,TPDU: a0 a4 00 00 02 3f 00timestamp: TPDU lines prefixed with local time —[14:32:05.123] TPDU: a0 a4 00 00 02 3f 00atr-time: TPDU lines prefixed with seconds since last ATR —[0001.234] TPDU: a0 a4 00 00 02 3f 00
Non-TPDU messages (ATR, PPS, card state changes, Fi/Di) print identically in all formats.
- GSMTAP: ATR and APDU messages over UDP (port 4729) to Wireshark
- PCAP: ATR/TPDU messages as Ethernet/IP/UDP/GSMTAP packets, openable in Wireshark
Background / Daemon
SIGHUP is automatically ignored when stdin is not a terminal (i.e. run in background or via a pipe). Foreground terminal sessions still respond to SIGHUP normally.
To run persistently in the background with output to files:
nohup ./sniff-start.sh --output /tmp/sniff.log &> /tmp/sniff-err.log &
# or
FORMAT=timestamp nohup python -m simtrace2_pysniff --output /tmp/sniff.log &> /tmp/sniff-err.log &
Library Usage
from simtrace2_pysniff import SniffSession
session = SniffSession(inactivity_timeout=30.0)
for msg in session.iter_messages():
print(f"{msg.type}: {msg.data.hex()}")
Recovery
The tool survives hardware resets, cable disconnects, and firmware hangs
by default — it reconnects with exponential backoff (1s → 30s cap).
Use --inactivity-timeout to also trigger reconnect on silent firmware hangs.
Related
- simtrace2 — the upstream SIMtrace2 hardware/firmware project that this tool sniffs from.