Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CMF-Watch-Pro-2-BLE-Protocol — Обратно спроектированный протокол BLE для CMF Watch Pro 2, документирующий структуру GATT, зашифрованные командные фреймы AES-128-CBC, процедуру аутентификации и синхронизацию данных о здоровье для разработки альтернативного сопутствующего приложения. | Kitploit
Инструменты/GitHubGitHub/joshuapassos/cmf-watch-pro-2-ble-protocol
Безопасность встроенных системБезопасность BluetoothБезопасность IoTОбратная инженерияБезопасность беспроводных сетейКриптографияМобильная безопасностьБезопасность оборудования и IoTАнализ Прошивок

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
GitHubjoshuapassos/cmf-watch-pro-2-ble-protocol

CMF-Watch-Pro-2-BLE-Protocol

Обратно спроектированный протокол BLE для CMF Watch Pro 2, документирующий структуру GATT, зашифрованные командные фреймы AES-128-CBC, процедуру аутентификации и синхронизацию данных о здоровье для разработки альтернативного сопутствующего приложения.

РепозиторийСайт
3492 месяцев назадЕщё не проверено

CMF Watch Pro 2 — протокол BLE (реконструированный)

Неофициально. Этот документ описывает протокол Bluetooth Low Energy (BLE) часов CMF Watch Pro 2 (CMF by Nothing), восстановленный методом обратной разработки для альтернативного приложения-компаньона. Он не связан с Nothing/CMF и не одобрен ими. Используйте на свой страх и риск.

Все многобайтовые целые числа в заголовке кадра и кодах операций — big-endian. Целые числа внутри полезной нагрузки команд — little-endian, если не указано иное (это отражает прошивку устройства) — остерегайтесь исключений (GOALS_SET, GPS_PUSH, смещение/длина массовой передачи — big-endian).

Маркеры достоверности

Каждое неочевидное утверждение ниже помечено способом его установления:

  • ✅ проверено на устройстве — наблюдалось в расшифрованном живом захвате или проверено на реальных часах.
  • 🔎 из прошивки / RE APK — извлечено декомпиляцией прошивки (1.0.0.73) или официального APK (3.5.7); согласуется с кодом, но не протестировано в рантайме.
  • 🟡 частично доказано — установлено структурно (офлайн, по корпусу или через RE), но оставшийся шаг требует часов и не был выполнен.
  • ⚠️ [неопределённо] — предположительно, не подтверждено; может быть неверно.

Если более поздний раздел исправляет более ранний, ранний текст сохраняется с указателем, а не удаляется — знание того, какие чтения были опробованы и опровергнуты, избавит следующего человека от того же обходного пути.

Тестовое устройство для всех захватов: CMF Watch Pro 2-5485, прошивка 1.0.0.73, серийный номер CI04102520008192, MCU Actions ATS3089C (Cortex-M4), экран 466×360.


1. Структура GATT

Телефон является GATT-клиентом; часы — периферийным устройством, рекламирующимся как CMF Watch Pro 2-XXXX (4 шестнадцатеричных символа).

НазначениеСервисХарактеристикаСвойства
Запись команд0000fff0-0000-1000-8000-00805f9b34fb0000fff2-…Write
Уведомления команд0000fff0-…0000fff1-…Notify
Запись оболочки (AT)—77d4ff01-2fe2-2334-0d35-9ccd078f529cWrite
Уведомления оболочки (AT)—77d4ff02-…Notify
Запись массовых данных—02f00000-0000-0000-0000-00000000ffe1Write
Уведомления массовых данных—02f00000-…ffe2Notify

Включите уведомления, записав 01 00 в каждый CCCD (00002902-…). Канал команд (fff1/fff2) передаёт кадрированный протокол ниже. Канал оболочки (77d4…) передаёт обычный текст в стиле AT (например, AT GETSECRET; см. §14). Канал данных (02f0…) передаёт большие бинарные блоки (циферблат, прошивка, AGPS), координируемые управляющими кодами операций на канале команд.

UUID сервисов — часы рекламируют ~10 основных сервисов. Перечислены на реальном устройстве: 0xfff0 (команды), 0x180f (батарея), 0x180a (информация об устройстве), 0xefe7, 0xffd0, 02f00000-…ffe0 и 02f00000-…fe00 (данные), 77d4e67c-2fe2-2334-0d35-9ccd078f529c (оболочка / сопряжение), e49a3001-f69a-11e8-8eb2-f2801f1b9fd1, f48a23c0-f69a-11e8-8eb2-f2801f1b9fd1.

⚠️ UUID сервиса оболочки — 77d4e67c-…, а не 77d4ff00-…. В более ранних версиях этого документа предполагалось, что сервис разделяет префикс ff00 своих характеристик (77d4ff01/77d4ff02, §14) — это не так, по крайней мере на устройстве, на котором это проверялось (находка из freethinkel/fmc, см. §Источники). UUID характеристик не изменились. Не проверено, стабилен ли 77d4e67c между устройствами — перечисляйте, а не зашивайте жёстко.

🌐 Примечание о Web Bluetooth. Chromium обнаруживает только те сервисы, которые страница перечислила в optionalServices, даже для нефильтрованного вызова getPrimaryServices() — страница, перечисляющая 3 сервиса, видит 3, тогда как chrome://bluetooth-internals (собственный C++-слой Chrome, без ограничений) показывает все 10. Если вы пишете браузерный клиент, перечислите все UUID выше заранее, иначе сопряжение завершится ошибкой с сервисами, которые явно существуют. Web Bluetooth нет в Firefox/Safari; требуется жест пользователя + HTTPS/localhost.

✅ Целая реальная сессия прошла на единственном канале команд — во время 160-секундного захвата при интенсивном использовании не было трафика на каналах данных/прошивки или оболочки, кроме явной передачи OTA/циферблата.


2. Формат кадра (0xF5)

Каждое сообщение канала команд обёрнуто в один или несколько кадров с 11-байтовым заголовком:``` +------+-----------+--------+-------------+-------------+--------+-------------------+ | 0xF5 | chunkLen | cmd1 | chunkCount | chunkIndex | cmd2 | chunk bytes … | | 1 B | 2 B (BE) | 2 B BE | 2 B BE | 2 B BE | 2 B BE | chunkLen bytes | +------+-----------+--------+-------------+-------------+--------+-------------------+ __________________________ 11-byte header ____________________________/

- `cmd1`/`cmd2` вместе образуют **опкод** (см. §6). 🔎 подтверждено по фрейм-билдеру официального приложения (`C6117b.m30831g`).
- `chunkCount` = общее количество чанков для этой команды; `chunkIndex` — **с 1**.
- `chunkLen` = количество байт `chunk` в этом фрейме.
- Одна BLE-запись может фрагментироваться по MTU канала; приёмник буферизует сырые байты и заново извлекает полные фреймы. Большие полезные нагрузки разбиваются на несколько чанков (одинаковые `cmd1/cmd2`, возрастающий `chunkIndex`) и собираются по порядку.

### Соглашение об опкодах (✅ подтверждено на проводе)

- `cmd1 = 0xFFFF`: `cmd2` в диапазоне `0x80xx`/`0x90xx` = телефон→часы (запрос/установка); `0x00xx`/`0xa0xx` = часы→телефон (ответ). Пары сопоставляются по младшему байту (`0x9055`↔`0xa055`, `0x8051`↔`0x0051`).
- специфичный для функции `cmd1`: суффикс `cmd2` = `0x0001` **SET**, `0x0002` **GET**, `0x0003` **ACK**.

### Тело чанка

Для каждого чанка тело — это `payloadPiece ‖ CRC32_LE(payloadPiece)` (4-байтный CRC, little-endian, zlib/IEEE). Если команда **зашифрована** (см. §3), весь `payloadPiece ‖ CRC` затем шифруется AES-128-CBC/PKCS7, и этот шифротекст становится `chunk` фрейма.

**Особенность открытого текста:** для опкодов без шифрования часы *учитывают* 4-байтный CRC в `chunkLen`, но **не** передают его. Поэтому при декодировании фрейма с открытым текстом фактическая длина данных равна `chunkLen − 4`. (Зашифрованные фреймы несут CRC внутри шифротекста как обычно.)

Размер чанка (чтобы зашифрованные чанки ложились на границы AES-блоков), при `maxWrite = mtu − 3`:
- зашифрованный: `floor((maxWrite − 11) / 16) * 16 − 4 − 1`
- открытый текст: `maxWrite − 11 − 4 − 1`

✅ Все наблюдаемые значения `chunkLen` зашифрованных фреймов были кратны 16 (выравнивание по блокам соблюдается).

---

## 3. Криптографические примитивы

- **AES-128-CBC** с дополнением **PKCS7** и **фиксированным IV** (из прошивки `CmfCharacteristic.AES_IV`):
  `50 51 52 53 54 55 56 57 60 61 62 63 64 65 66 5A`.
- **CRC32** (zlib/IEEE), выдаётся как 4 байта little-endian.
- **SHA-256** по конкатенации частей.

Вывод ключа:```
authkey      = SHA256( rnd1 ‖ rnd2 ‖ secret )[0..16]      // persisted across sessions
sessionKey   = SHA256( nonce ‖ authkey )[0..16]           // per connection
  • secret = 16-байтовый секрет устройства (получается с часов через shell-команду AT GETSECRET → GETSECRET:<32-hex>,OK).
  • rnd1 = 16 случайных байт, выбранных телефоном; rnd2 = 16 случайных байт с часов.
  • nonce = байты из ответа nonce часов.

После установки ключа все кадры командного канала шифруются AES, кроме открытых опкодов, перечисленных в §5.

✅ Обе производные проверены: authkey, восстановленный с рутованного телефона из ntwatch.db, совпал со значением, полученным из захваченных rnd1/rnd2/secret; sessionKey, воспроизведённый из захваченного nonce, расшифровывает живые кадры.


4. Аутентификация / процедура сопряжения

Два пути входа используют один и тот же хвост nonce/confirm.

Скачать инструмент