
oBike プロトコル通信 (BLE および HTTP) のリバースエンジニアリング
このドキュメントは、2018年1月時点のoBike通信プロトコルの分析です。
結果は insomni'hack security conference 2019 で発表されました:
また、AREA41 security conference 2018 でも発表されました:
oBikeのロックは、TI CC2541マイクロコントローラと、Bluetooth Low Energy(BLE)アプリケーション用の電力最適化型System on a Chip(SoC)で構成されています。ロック自体にはIP接続機能はなく、モバイルデバイスの3G/4G接続を利用してoBikeのバックエンドと通信します。ロックはBLEを介してモバイルデバイス上のoBikeアプリと通信します。プロトコルメッセージは、REST APIを介してoBikeのバックエンドに中継されます。
ロックには独自のGPSモジュールはありません。そのため、バックエンドに報告される位置情報は常にモバイルデバイスのものであり、oBike本体のものではありません。``` GPS | +---------+ +---------+ +----------+ | oBike | | Mobile | | oBike | | Lock | +--- BLE ---> | Device | +--- HTTPS ---> | Backend | +---------+ +---------+ +----------+
## ロック解除シーケンス```
oBike Lock (BLE) Mobile Device (HTTPS) oBike Backend
------------+------------------------+---------------------------+--------------
| | |
| [1] hello(lat, lng) | |
| <--------------------- | |
Generate | | |
32bit | [2] keySource | |
Challenge | ---------------------> | [3] unlockPass(keySource) |
| | ========================> | Compute
| | | Response
| [5] | [4] encKey, keys |
| sendKeys(encKey, keys) | <======================== |
!Unlock | <--------------------- | |
Bike! | | |
| | |
Generate | | |
Acknowledge | [6] macKey, index | [7] |
Message | ---------------------> | lockMessage(macKey,index) |
| | ========================> | Register
| | | Ride (start
| | | billing)
手順:
hello メッセージを送信し、座標をロックに送信する。keySource を受信する。これは、
チップの電源投入からの経過ミリ秒数(リトルエンディアン)を表す 32bit 値である。unlockPass REST 呼び出しを介して keySource を oBike バックエンドに送信する。encKey(キーインデックス)と、keys 内の 128bit キー値を受信する。encKey(96bit に切り詰めたもの)と index(
encKey に対応する)。その時点で、自転車のロックが解除される。macKey と index を受信する。これは、ロック解除が成功したことを示す
確認応答である。macKey と
index)を含む lockMessage を送信する。その時点で、oBike バックエンドは走行を登録し、
課金を開始する。以下のセクションで説明する BLE プロトコルコンポーネントは、
python モジュール obike.ble_client に実装されている。さらに、obike の BLE アドバタイズメントを検出するスキャナーは、
obike.ble_scanner.py に実装されている。
6774 0D 86 59AEB6...3931 FD | | | | | | | | | +-- Check byte | | | +----------------- Payload | | +--------------------- Command type | +------------------------- Length of payload in bytes +------------------------------- Command Signature ('gt')
送受信されるメッセージは、常にシグネチャ `\x67\x74`(ASCII `gt`)で始まります。
ペイロードの長さは、ヘッダーとトレーラーを除いたバイト数です。
プロトコルは、バイトで識別されるさまざまなメッセージタイプをサポートしています。最上位2ビットがメッセージの方向を定義します。```
0x86 1000 0101 mobile -> obike
0x46 0100 0101 obike -> mobile
チェックバイトは、コマンドタイプとペイロードバイトをXORして計算されます:``` check_byte = cmdtype ^ b[0] ^ b[1] ^ ... ^ b[N-1]
最大PDUサイズは19バイトです(ヘッダー + ペイロード + トレーラー)。このサイズを超えるメッセージは断片化されます。
### BLE getLockRecord/deleteLockRecord
コマンドタイプ: `6`
これらのメッセージは、「ロックレコード」を管理するために使用されます。ロックレコードとは、チップによって保持されるデータレコードで、前回のライドからの情報(memberid、タイムスタンプ、oBike識別子、座標など)で構成されます。
ペイロードなしで呼び出された場合、このコマンドは保存されたロックレコードを取得するために使用されます:```
00000000 67 74 00 86 86 |gt...|
ロックレコードが利用できない場合、ロックは空のペイロードで応答します。``` 00000000 67 74 00 46 46 |gt.FF|
それ以外の場合、ロックの応答には前回の走行からのいくつかの値が含まれており、
次の形式になります:```
00000000 67 74 46 46 00 00 01 23 45 67 59 9d 72 2a 44 31 |gtFF...#d2Y.r*D1|
00000010 39 33 36 42 33 31 37 2a 72 9d 59 00 34 37 2e 33 |936B317*r.Y.47.3|
00000020 37 32 37 36 30 00 00 00 30 38 2e 35 33 30 38 34 |72760...08.53084|
00000030 32 32 00 00 87 76 f3 7a 8c be 90 f8 4b a4 fa 00 |22...v.z....K...|
00000040 2e ae e3 dc 91 00 00 00 a9 01 8b |...........|
OCI Image Formatタグのサポート。これらのタグはターゲットレジストリの特定のリポジトリタグにマッピングされます。
例:
sha256-9b3b13f501d9fa04445790cd6ecb146c1b340a58f0b4a0b4dd3f0899e1c2e10d.sig -> `latest````
Offset Value Description0004 000001234567 member-id (explicitly coded in decimal, value is: 1234567)
000a 599d722a UNIX timestamp, 08/23/2017 @ 12:16pm
000e 443139333642333137 obike identifier (D1936B317) this corresponds to the MAC address without the first 3 hex digits, in this case: D4:3D:19:36:B3:17
0017 2a729d59 same UNIX timestamp, little endian
001b 00 transaction type
001c 34372e333732373630000000 latitude (47.372760)
0028 30382e353330383432320000 longitude (08.5308422)
0034 8776f37a8cbe90f84ba4fa002eaee3dc mackey (128 bits)
0044 91 key index
0045 000000 ? 0048 a901 battery voltag level (little endian) e.g. 4.25V
ペイロードと共に使用すると、このコマンドは現在のロックレコードを削除します:```
00000000 67 74 0d 86 59 d5 ff a4 36 33 39 38 37 37 31 33 |gt..Y...63987713|
00000010 43 14 |C.|
0004 59d5ffa4 timestamp (little endian) 000e 3633393837373133 "63987713C" obike identifier
### BLE Push Coords / Get Challenge