
Rétro-ingénierie de la communication du protocole oBike (BLE et HTTP)
Ce document fournit une analyse des protocoles de communication oBike en date de janvier 2018.
Les résultats ont été présentés à la conférence de sécurité insomni'hack 2019:
ainsi qu'à la conférence de sécurité AREA41 2018:
La serrure oBike se compose d'un microcontrôleur TI CC2541, un système sur puce (SoC) optimisé pour la consommation électrique, utilisé pour les applications Bluetooth Low Energy (BLE). La serrure elle-même n'a pas de connectivité IP ; elle utilise la connexion 3G/4G de l'appareil mobile pour communiquer avec le backend oBike. La serrure communique via BLE avec l'application oBike sur l'appareil mobile. Les messages du protocole sont ensuite transmis au backend oBike via une API REST.
La serrure ne dispose pas de module GPS propre. Ainsi, la position signalée au backend est toujours celle de l'appareil mobile, et non celle de l'oBike lui-même.``` GPS | +---------+ +---------+ +----------+ | oBike | | Mobile | | oBike | | Lock | +--- BLE ---> | Device | +--- HTTPS ---> | Backend | +---------+ +---------+ +----------+
## Séquence de déverrouillage```
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)
Étapes :
hello via BLE, pousser les coordonnées vers la serrure.keySource, une valeur de 32 bits représentant le nombre de
millisecondes écoulées depuis la mise sous tension de la puce (little endian).keySource au backend oBike via l’appel REST unlockPass.encKey (index de clé) et une valeur de clé de 128 bits dans keys.encKey (tronquée à 96 bits) et index (correspond à
encKey). À ce moment, le vélo se déverrouillera.macKey et index, un accusé de réception indiquant que le déverrouillage a
réussi.lockMessage, avec les valeurs correspondantes (macKey et
index). À ce moment, le backend oBike enregistrera le trajet et démarrera la
facturation.Les composants du protocole BLE décrits dans les sections suivantes sont implémentés
dans le module Python obike.ble_client. De plus, un scanner pour détecter les publicités
BLE d’obike est implémenté dans obike.ble_scanner.py.
6774 0D 86 59AEB6...3931 FD | | | | | | | | | +-- Check byte | | | +----------------- Payload | | +--------------------- Command type | +------------------------- Length of payload in bytes +------------------------------- Command Signature ('gt')
Le message, qu'il soit entrant ou sortant, commence toujours par la signature `\x67\x74`
(ascii `gt`).
La longueur de la charge utile correspond au nombre d'octets sans l'en-tête ni le pied de trame.
Le protocole prend en charge différents types de messages identifiés par un octet. Les deux
bits les plus significatifs définissent la direction du message :```
0x86 1000 0101 mobile -> obike
0x46 0100 0101 obike -> mobile
L'octet de contrôle est calculé en effectuant un XOR entre le type de commande et les octets de charge utile :``` check_byte = cmdtype ^ b[0] ^ b[1] ^ ... ^ b[N-1]
La taille maximale de la PDU est de 19 octets (en-tête + charge utile + fin de trame). Les messages dépassant cette taille sont fragmentés.
### BLE getLockRecord/deleteLockRecord
Type de commande : `6`
Ces messages sont utilisés pour gérer l'« enregistrement de verrouillage » (lock record), un enregistrement de données persisté par la puce, contenant les informations du dernier trajet, telles que l'identifiant du membre, l'horodatage, l'identifiant oBike, les coordonnées, etc.
Appelée sans charge utile, la commande est utilisée pour récupérer l'enregistrement de verrouillage sauvegardé :```
00000000 67 74 00 86 86 |gt...|
Si aucun enregistrement de verrou n'est disponible, le verrou répond avec un payload vide.``` 00000000 67 74 00 46 46 |gt.FF|
Sinon, la réponse de la serrure contient plusieurs valeurs du dernier trajet,
au format suivant :```
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 |...........|
0004 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