Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CMF-Watch-Pro-2-BLE-Protocol — CMF Watch Pro 2向けのリバースエンジニアリングされたBLEプロトコル。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

CMF Watch Pro 2向けのリバースエンジニアリングされたBLEプロトコル。GATTレイアウト、AES-128-CBC暗号化コマンドフレーム、認証ハンドシェイク、および代替コンパニオンアプリ開発のためのヘルスデータ同期を文書化しています。

リポジトリを見るウェブサイト
3492ヶ月前未レビュー

CMF Watch Pro 2 — BLEプロトコル(リバースエンジニアリング)

非公式。 このドキュメントは、CMF Watch Pro 2(CMF by Nothing)のBluetooth Low Energy(BLE)プロトコルを、代替コンパニオンアプリのためにリバースエンジニアリングによって再構築したものです。Nothing/CMFとは提携しておらず、その承認も受けていません。自己責任で使用してください。

フレームヘッダーとオペコード内のすべてのマルチバイト整数はビッグエンディアンです。コマンドペイロード内の整数は、特に明記されていない限りリトルエンディアンです(これはデバイスファームウェアを反映しています)— 例外(GOALS_SET、GPS_PUSH、バルク転送のオフセット/長さはビッグエンディアン)に注意してください。

信頼性マーカー

以下に示す明白でない主張にはすべて、その確立方法を示すタグが付いています:

  • ✅ デバイス上で検証済み — 復号されたライブキャプチャで観測されたか、実機のウォッチに対して実行された。
  • 🔎 ファームウェア/APKのREによる — ファームウェア(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桁の16進数)としてアドバタイズします。

目的サービスキャラクタリスティックプロパティ
コマンド書き込み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

各CCCD(00002902-…)に01 00を書き込むことで通知を有効にします。コマンドチャネル(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-…ではありません。このドキュメントの以前の改訂版では、サービスがそのキャラクタリスティック(77d4ff01/77d4ff02、§14)のff00プレフィックスを共有していると想定していました — 実際にはそうではありません。少なくともこの確認が行われたユニットでは(freethinkel/fmcからの発見、§Sources参照)。キャラクタリスティックUUIDは変更されていません。77d4e67cがユニット間で安定しているかどうかは未検証です — ハードコードするのではなく列挙してください。

🌐 Web Bluetoothに関する注意。 Chromiumは、ページがoptionalServicesにリストしたサービスしか発見しません。フィルタリングされていないgetPrimaryServices()呼び出しでも同様です — 3つのサービスをリストしたページは3つしか見えませんが、chrome://bluetooth-internals(Chrome自身のC++レイヤー、スコープなし)は10個すべてを表示します。ブラウザクライアントを書く場合は、上記のすべてのUUIDを事前にリストしてください。そうしないと、明らかに存在するサービスでペアリングが失敗します。Firefox/SafariにはWeb Bluetoothはありません。ユーザージェスチャーとHTTPS/localhostが必要です。

✅ 単一のコマンドチャネル上で実際のセッション全体が実行されました — 160秒間の高負荷キャプチャ中、明示的なOTA/ウォッチフェイス転送中を除いて、データ/ファームウェアまたはシェルチャネルにはトラフィックがありませんでした。


2. フレーム形式(0xF5)

すべてのコマンドチャネルメッセージは、1つ以上の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` のバイト数。
- 1 回の 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、リトルエンディアン、zlib/IEEE)です。コマンドが**暗号化**されている場合(§3 参照)、`payloadPiece ‖ CRC` 全体が AES-128-CBC/PKCS7 で暗号化され、その暗号文がフレームの `chunk` になります。

**平文の癖:** 平文オペコードの場合、ウォッチは `chunkLen` に 4 バイトの CRC を*数えます*が、それを**送信しません**。したがって、平文フレームをデコードするとき、実際のデータ長は `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 バイトのリトルエンディアンとして出力。
- パーツの連結に対する **SHA-256**。

鍵導出:```
authkey      = SHA256( rnd1 ‖ rnd2 ‖ secret )[0..16]      // persisted across sessions
sessionKey   = SHA256( nonce ‖ authkey )[0..16]           // per connection
  • secret = 16バイトのデバイスシークレット(シェルコマンド AT GETSECRET → GETSECRET:<32-hex>,OK でウォッチから取得可能)。
  • rnd1 = 電話側が選択する16ランダムバイト、rnd2 = ウォッチからの16ランダムバイト。
  • nonce = ウォッチのnonce応答からのバイト。

キーが設定された後、§5に記載された平文オペコードを除き、すべてのコマンドチャネルフレームはAES暗号化されます。

✅ 両方の導出が検証済み:ルート化された電話のntwatch.dbから復元されたauthkeyが、 キャプチャしたrnd1/rnd2/secretから導出された値と一致しました。キャプチャしたnonceから再現されたsessionKeyは、ライブフレームを復号します。


4. 認証 / ペアリングハンドシェイク

2つのエントリパスが同じnonce/confirmテールを共有します。

4.1 初回ペアリング(デバイスシークレットを保持)```

phone → (shell) AT GETSECRET watch → (shell) GETSECRET:<32hex>,OK phone: rnd1 = random16 ; signed1 = SHA256(rnd1 ‖ secret) phone → AUTH_PAIR_REQUEST (plaintext) payload = rnd1(16) ‖ signed1(32) // 48 B watch → AUTH_PAIR_REPLY (plaintext) payload = rnd2(16) ‖ signed2(32) // 48 B phone verifies signed2 == SHA256(rnd2 ‖ secret) phone: authkey = SHA256(rnd1 ‖ rnd2 ‖ secret)[0..16] → set crypto key = authkey phone → AUTH_PHONE_NAME (encrypted) payload = 0xA5 ‖ model(UTF-8) // e.g. "CMF Watch Pro 2" watch → AUTH_WATCH_MAC (encrypted) phone → AUTH_NONCE_REQUEST (encrypted) payload = 0xA5 watch → AUTH_NONCE_REPLY (encrypted) payload = nonce phone: sessionKey = SHA256(nonce ‖ authkey)[0..16] → set crypto key = sessionKey phone → AUTHENTICATED_CONFIRM_REQUEST (encrypted) payload = 0xA5 watch → AUTHENTICATED_CONFIRM_REPLY (encrypted) → state = Initialized

`AUTH_FAILED (0xFFFF,0xA061)` または署名の不一致が発生した場合、認証は失敗します。

### 4.2 再接続(authkey が既知の場合)```
        set crypto key = authkey (persisted)
phone → AUTH_PHONE_NAME      (encrypted)  payload = 0xA5 ‖ model
watch → AUTH_WATCH_MAC       (encrypted)
phone → AUTH_NONCE_REQUEST   (encrypted)  payload = 0xA5
watch → AUTH_NONCE_REPLY     (encrypted)  payload = nonce
        sessionKey = SHA256(nonce ‖ authkey)[0..16]   → set crypto key = sessionKey
phone → AUTHENTICATED_CONFIRM_REQUEST (encrypted)  payload = 0xA5
watch → AUTHENTICATED_CONFIRM_REPLY   (encrypted)  → Initialized

✅ 再接続順序(シェルトラフィックなし)は、実際のキャプチャでそのまま観測されました。

4.3 認証後初期化(フェーズ2)

⚠️→✅ データクエリの前に TIME が必須です。 Initialized 後、ウォッチはセッション内で TIME (FFFF 8004) が送信されるまで BATTERY、SERIAL_NUMBER_GET、ACTIVITY_FETCH_* ハンドシェイクに 応答しません — それがない場合、未承諾の FIRMWARE_VERSION_RET だけが届き、他はすべてタイムアウトします。✅ ライブで確認済み(Pixel 8a): TIME なしで3つのGETを送信 → ファームウェアのみ応答;TIME を先に送信 → バッテリー と シリアル番号が応答し始めます。

推奨されるフェーズ2の順序:TIME → FIRMWARE_VERSION_GET → SERIAL_NUMBER_GET → BATTERY (0xA5) → 設定プッシュ → ヘルス同期(§8)。

4.4 GET → SET エコーパターン(✅)

ほとんどの設定に独立した「読み取り」オペコードはありません。*_GET(cmd2 = 0x0002、ペイロード 0xA5)を送信すると、ウォッチは現在値を保持した SET オペコード(cmd2 = 0x0001)で応答します。 SET コマンドは cmd2 = 0x0003 と空のボディで確認応答されます。


5. 平文 vs 暗号化

フレームはキーが設定されると AES 暗号化されますが、以下を除く これらのオペコードは常に平文です:

  • AUTH_PAIR_REQUEST(FFFF 8047)、AUTH_PAIR_REPLY(FFFF 0048)
  • DATA_CHUNK_WRITE_WATCHFACE(FFFF 9064)、DATA_CHUNK_WRITE_FIRMWARE(FFFF 9042)、 DATA_CHUNK_WRITE_AGPS(FFFF 905F)
ツールをダウンロード