
Engenharia reversa do protocolo de comunicação oBike (BLE e HTTP)
Este documento fornece uma análise dos protocolos de comunicação oBike em janeiro de 2018.
Os resultados foram apresentados na insomni'hack security conference 2019:
bem como na AREA41 security conference 2018:
A fechadura oBike consiste em um microcontrolador TI CC2541, um System on a Chip (SoC) otimizado para energia usado para aplicações Bluetooth Low Energy (BLE). A fechadura em si não tem conectividade IP; ela utiliza a conexão 3G/4G do dispositivo móvel para se comunicar com o backend oBike. A fechadura se comunica via BLE com o aplicativo oBike no dispositivo móvel. As mensagens de protocolo são então encaminhadas para o backend oBike por meio de uma API REST.
A fechadura não possui módulo GPS próprio. Como tal, a posição reportada ao backend é sempre a do dispositivo móvel, e não a da própria oBike.``` GPS | +---------+ +---------+ +----------+ | oBike | | Mobile | | oBike | | Lock | +--- BLE ---> | Device | +--- HTTPS ---> | Backend | +---------+ +---------+ +----------+
## Sequência de Desbloqueio```
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)
Passos:
hello, envie as coordenadas para a fechadura.keySource, um valor de 32bit que representa o número de
milissegundos desde que o chip foi ligado (little endian).unlockPass.encKey (índice da chave) e um valor de chave de 128bit em keys.encKey (truncado para 96bits) e o index ( corresponde a
encKey). Nesse ponto, a bicicleta será destravada.macKey e index, um reconhecimento de que o destravamento foi
bem-sucedido.lockMessage, com os valores correspondentes (macKey e
index). Nesse ponto, o backend da oBike registrará a viagem e iniciará
a cobrança.Os componentes do protocolo BLE descritos nas seções a seguir são implementados
no módulo python obike.ble_client. Além disso, um scanner para detectar anúncios BLE da obike
é implementado em obike.ble_scanner.py.
6774 0D 86 59AEB6...3931 FD | | | | | | | | | +-- Check byte | | | +----------------- Payload | | +--------------------- Command type | +------------------------- Length of payload in bytes +------------------------------- Command Signature ('gt')
A mensagem, tanto de entrada quanto de saída, sempre começa com a assinatura `\x67\x74`
(ascii `gt`).
O comprimento do payload é o número de bytes sem cabeçalho/rodapé.
O protocolo suporta diferentes tipos de mensagem identificados por um byte. Os dois
bits mais significativos definem a direção da mensagem:```
0x86 1000 0101 mobile -> obike
0x46 0100 0101 obike -> mobile
O byte de verificação é calculado aplicando XOR ao tipo de comando e aos bytes do payload:``` check_byte = cmdtype ^ b[0] ^ b[1] ^ ... ^ b[N-1]
### BLE getLockRecord/deleteLockRecord
Tipo de comando: `6`
Essas mensagens são usadas para gerenciar o "lock record", um registro de dados persistido pelo chip contendo informações da última viagem, como memberid, timestamp, identificador oBike, coordenadas, etc.
Chamado sem payload, o comando é usado para recuperar o lock record salvo:```
00000000 67 74 00 86 86 |gt...|
Se nenhum registro de bloqueio estiver disponível, o bloqueio responde com um payload vazio.``` 00000000 67 74 00 46 46 |gt.FF|
Caso contrário, a resposta do cadeado contém vários valores do último percurso, no
seguinte formato:```
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 |...........|
is from the assistant? Actually, the assistant has just received the prompt. The user said: "Translate the following Kitploit tool content. This is chunk 17 of 87 ... INPUT:" and that's it. There is no content after INPUT:? Possibly the chunk content is in the following lines? The message is:
Translate the following Kitploit tool content.
This is chunk 17 of 87 from a longer Markdown document being translated in sequence.
The source language is en.
Target language: pt.
Content type: README chunk 17/87.
CHUNK-SPECIFIC RULES:
1. Translate ONLY natural language text. NEVER translate: code blocks, shell commands, file paths, URLs, package names, technical identifiers, CVE IDs, environment variable names.
2. Preserve ALL Markdown syntax EXACTLY as-is.
3. DO NOT add introductory headings like "## Chunk N", "## Part N", "## Continued from..." or "## Translation of chunk...". DO NOT add "End of chunk N" or "Content continues..." markers.
4. DO NOT add "..." ellipsis markers to indicate omission. Translate ONLY the exact text provided, character for character in structure.
5. Chunk boundaries are intentional. Preserve structure so chunks can be concatenated seamlessly without visual artifacts.
6. Return ONLY the translated text. No preamble, no commentary, no wrapping in code blocks, no JSON/YAML/XML, no arrays, no objects, no schemas, no key/value wrappers.
7. If the chunk starts mid-paragraph, continue translating from that point. Do not add a leading newline or indent unless it exists in the source.
INPUT: