17 KiB
simtrace2-pysniff
English | Русский
Замена simtrace2-sniff на Python — сниффер обмена с SIM-картой для
оборудования Osmocom SIMtrace2 (прошивка в режиме trace). Включает PWA
simtrace-analyser (в frontend/) и анализирующий сервер,
который и захватывает APDU-трафик, и отдаёт эту PWA.
Единственная зависимость: PyUSB (обёртка над libusb). Без libosmocore, без libosmosim.
Возможности
Декодер APDU (на стороне сервера, отображается в PWA):
- Полное декодирование APDU — CLA по ISO 7816-4 / ETSI (логический канал, secure messaging, chaining команд), имена INS из таблицы спецификаций, учёт SFI в P1/P2 для READ/UPDATE BINARY и команд с записями
- Статусные слова — полный набор ISO 7816-4 плюс специфичные для UICC
значения:
91XX(ожидается proactive-команда),62F1/F2/F3,63F1/F2(больше данных),9300(SAT busy),9850,9862–64 - SIM Toolkit — SAT (GSM 11.14), CAT (TS 102 223) и USAT (TS 31.111): proactive-команды с декодированными квалификаторами, TERMINAL RESPONSE, ENVELOPE (Menu Selection, Call Control, SMS-PP download…); учитываются известные несоответствия старых карт, нераспознанные TLV сохраняются
- SMS TPDU — SMS-DELIVER/SUBMIT, метки времени SCTS, информационные элементы UDH
- SCP80 OTA secured packets — биты SPI (шифрование, требование/режим PoR, RC/CC/DS, счётчик), алгоритм KIc/KID + набор ключей, TAR, CNTR/PCNTR; декодирование Response Packet (PoR) по GET RESPONSE; опциональная расшифровка на клиенте зашифрованных пакетов — вставьте 3DES/AES-ключ карты в панели деталей, чтобы увидеть настоящие CNTR и защищённые данные приложения (ключ остаётся в браузере, только в памяти; зашифрованные в эфире CNTR/PCNTR/RC — это шифротекст, и они так и помечены); защищённое сообщение приложения декодируется как поток C-APDU (SELECT, UPDATE BINARY, …) с полной разбивкой CLA/INS/P1/P2/Lc/Le — сразу для открытого текста или после расшифровки для зашифрованных пакетов
- Разбор ATR (пересчёт тактовой частоты, Fi/Di, битовая маска T) и FCP/FCI TLV
PWA simtrace-analyser (frontend/):
- Окно трассировки с режимами «Карта»/«Список» — proactive, TERMINAL RESPONSE, ENVELOPE и AUTH-команды выделяются в режиме карты
- Сессии с прямыми ссылками (
#session=N), импорт PCAP (.pcap/.pcapng/.cap), поиск и фильтрация по типу - Устанавливаемая PWA, тёмная тема, интерфейс на английском/русском
Требования
- Python 3.9+
- PyUSB —
pip install pyusb - libusb — системная библиотека, обычно уже есть в Linux; в Windows нужно заменить драйвер SIMtrace2 (см. Доступ к USB-устройству)
- Оборудование SIMtrace2 с прошивкой в режиме trace
(VID
1d50, PID60e3, USB classff, subclass01). О сборке и прошивке trace-прошивки см. проект SIMtrace2.
Других зависимостей нет. Вывод PCAP, GSMTAP и hex dump использует только стандартную библиотеку Python.
Установка
git clone https://github.com/anttro/simtrace2-pysniff.git
cd simtrace2-pysniff
pip install pyusb
Или установите пакет в своё окружение:
pip install -e .
# затем запуск: simtrace2-pysniff [opts]
Запуск
Предоставляются два инструмента:
CLI сниффера (simtrace2-pysniff)
Захватывает трафик SIMtrace2 и выводит его в stdout, GSMTAP (Wireshark) или файлы PCAP.
Скрипт запуска
./sniff-start.sh выполняет предварительную проверку прав доступа к USB
(при неудаче печатает инструкцию по установке udev-правила) и затем
запускает модуль Python. В Windows используйте sniff-start.bat с теми же
параметрами (проверка прав не требуется).
./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
Параметры также можно задавать через переменные окружения:
FORMAT=timestamp GSMTAP=127.0.0.1 ./sniff-start.sh
Анализирующий сервер + PWA (simtrace2-pysniff-server)
Сохраняет захваченный APDU-трафик в SQLite и отдаёт его по HTTP вместе
со встроенной PWA simtrace-analyser (frontend/) на том же origin.
Три режима захвата:
# Слушать GSMTAP от simtrace2-pysniff (или оригинального simtrace2-sniff):
simtrace2-pysniff-server --capture gsmtap
# Захват напрямую с оборудования SIMtrace2 (внешний инструмент не нужен):
simtrace2-pysniff-server --capture direct
# Просмотр/анализ существующих записей без бэкенда захвата:
simtrace2-pysniff-server --capture disabled
Сервер пишет в stderr информацию о жизненном цикле захвата (каждая строка
с локальным временем): Capture started при старте, периодический
heartbeat Capture alive: session=N messages=M bytes=B dropped=D
и Capture stopped (либо ERROR: capture thread stopped on error …,
если поток захвата неожиданно умер). Неверно сформированные или не-SIM
датаграммы GSMTAP отбрасываются и считаются (dropped), а не молча
убивают захват. Интервал heartbeat по умолчанию 60 с, настраивается
через --log-interval SECONDS.
GSMTAP-листенер также принимает декодер sigrok-iso7816-stream
(https://github.com/anttro/sigrok_iso7816_stream) — пассивный SIM-сниффер
на базе FX2-логического анализатора, выдающий тот же формат GSMTAP-SIM
на UDP 4729. Его пользовательские подтипы для событий линий RST/VCC
(0x10/0x11, добавлены для совместимости с тем проектом) декодируются
как временные маркеры RESET ASSERTED/DE-ASSERTED и VCC ON/OFF,
а сброс или пропадание питания корректно сбрасывает отслеживание
выбранного файла. GSMTAP-пакеты с флагом десинхронизации
GSMTAP_FLAG_BAD_FCS (устанавливается тем декодером при нарушении
кадрирования) отображаются в таймлайне как помеченная/десинхронизированная
запись, чтобы такие артефакты было легко заметить при разборе, а не молча
искажали декодирование.
Параметры сервера:
--host ADDR адрес привязки HTTP (по умолчанию: 127.0.0.1)
--port PORT порт HTTP-сервера (по умолчанию: 8081)
--db FILE путь к базе SQLite (по умолчанию: ~/.simtrace-analyser/sessions.db)
--capture MODE gsmtap | direct | disabled (по умолчанию: gsmtap)
--gsmtap-port PORT UDP-порт листенера GSMTAP (по умолчанию: 4729)
--web-dir PATH каталог статических файлов PWA (по умолчанию: <repo>/frontend)
Затем откройте http://127.0.0.1:8081/ в браузере — PWA отдаётся
сервером, поэтому UI и API используют один origin, и настройка
CORS/Private-Network-Access не требуется. Используйте --web-dir PATH,
чтобы отдавать другой каталог PWA (по умолчанию: <repo>/frontend).
Размещённая PWA (лендинг)
Автономная копия PWA размещена на https://simtrace.atroshin.ru.
Это чистый фронтенд: укажите в нём (Settings → Server URL) адрес
локально запущенного simtrace2-pysniff-server.
Ограничение браузера: когда PWA отдаётся с публичного HTTPS-хоста, доступ к локальному серверу (
http://127.0.0.1:8081) требует двух вещей: сервер должен отправлятьAccess-Control-Allow-Private-Network: true(этот сервер отправляет), и браузер должен иметь разрешение на доступ к локальной сети — в Chrome/Edge/Vivaldi: Настройки сайта → Доступ к локальной сети → разрешить сайту (или принять запрос разрешения). Без разрешения браузера запрос к127.0.0.1блокируется ещё до отправки preflight.
Модуль Python (кроссплатформенный)
python -m simtrace2_pysniff
python -m simtrace2_pysniff --format timestamp --gsmtap 127.0.0.1:4729
python -m simtrace2_pysniff --pcap trace.pcap
Если пакет установлен через pip install -e ., используйте консольный
скрипт напрямую:
simtrace2-pysniff --format atr-time
Доступ к USB-устройству
Linux
Для доступа к устройству SIMtrace2 без root нужно udev-правило.
sudo cp 70-simtrace2-pysniff.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
Затем переподключите USB-кабель SIMtrace2. Правило использует
TAG+="uaccess" (ACL systemd-logind) — членство в группе и права на
запись для всех не нужны.
Windows
В Windows нет libusb-совместимого драйвера для SIMtrace2. Используйте Zadig, чтобы заменить драйвер по умолчанию:
- Скачайте и запустите Zadig
- Подключите устройство SIMtrace2
- Выберите его в выпадающем списке (VID
1D50, PID60E3— "Osmocom SIMtrace 2") - Выберите WinUSB (или libusbK) как драйвер замены
- Нажмите Replace Driver (однократная операция)
После этого python -m simtrace2_pysniff работает так же, как в Linux.
Параметры CLI
python -m simtrace2_pysniff [OPTIONS]
--format, -f FORMAT Формат вывода (по умолчанию: hex)
hex — обычный hex-дамп
timestamp — строки TPDU с префиксом [ЧЧ:ММ:СС.мс]
atr-time — строки TPDU с префиксом [СССС.мс] от последнего ATR
--gsmtap HOST[:PORT] Отправлять ATR/TPDU как GSMTAP по UDP (порт по умолчанию 4729)
--pcap FILE Записывать перехваченные данные в PCAP для Wireshark
--output, -o FILE Записывать hex-дамп в файл
--no-stdout Не выводить hex-дамп в stdout
--vendor HEX USB vendor ID (по умолчанию: 0x1d50)
--product HEX USB product ID (по умолчанию: автоопределение)
Параметры восстановления:
--no-reconnect Выходить при отключении USB вместо переподключения
--reconnect-delay-min SEC Минимальная задержка переподключения (по умолчанию: 1.0)
--reconnect-delay-max SEC Максимальная задержка переподключения (по умолчанию: 30.0)
--backoff-factor N Множитель экспоненциальной задержки (по умолчанию: 1.5)
--inactivity-timeout SEC Переподключаться после N секунд тишины (по умолчанию: выключено)
Форматы вывода
hex(по умолчанию): обычный hex-дамп —ATR: 3b 9e ...,TPDU: a0 a4 00 00 02 3f 00timestamp: строки TPDU с локальным временем —[14:32:05.123] TPDU: a0 a4 00 00 02 3f 00atr-time: строки TPDU с секундами от последнего ATR —[0001.234] TPDU: a0 a4 00 00 02 3f 00
Сообщения, не являющиеся TPDU (ATR, PPS, изменения состояния карты, Fi/Di), выводятся одинаково во всех форматах.
- GSMTAP: сообщения ATR и APDU по UDP (порт 4729) в Wireshark
- PCAP: сообщения ATR/TPDU как пакеты Ethernet/IP/UDP/GSMTAP, открываются в Wireshark
Фоновый режим / демон
SIGHUP автоматически игнорируется, когда stdin не является терминалом (т.е. при запуске в фоне или через канал). Сессии в терминале на переднем плане по-прежнему обрабатывают SIGHUP обычным образом.
Для постоянной работы в фоне с выводом в файлы:
nohup ./sniff-start.sh --output /tmp/sniff.log &> /tmp/sniff-err.log &
# или
FORMAT=timestamp nohup python -m simtrace2_pysniff --output /tmp/sniff.log &> /tmp/sniff-err.log &
Использование как библиотеки
from simtrace2_pysniff import SniffSession
session = SniffSession(inactivity_timeout=30.0)
for msg in session.iter_messages():
print(f"{msg.type}: {msg.data.hex()}")
Восстановление
Инструмент по умолчанию переживает сбросы оборудования, отключения кабеля
и зависания прошивки — он переподключается с экспоненциальной задержкой
(1с → 30с). Используйте --inactivity-timeout, чтобы также переподключаться
при «тихих» зависаниях прошивки.
Связанные проекты
- simtrace2 — вышестоящий проект оборудования/прошивки SIMtrace2, с которого этот инструмент снимает трафик.
- sigrok_iso7816_stream — пассивный ISO 7816 сниффер на базе FX2LP, выдающий такой же поток GSMTAP-SIM на UDP 4729 (принимается GSMTAP-листенером этого проекта).
