Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
obike — Ingeniería inversa de la comunicación del protocolo oBike (BLE y HTTP) | Kitploit
Herramientas/GitHubGitHub/antoinet/obike
Seguridad BluetoothSeguridad IoTIngeniería InversaSeguridad InalámbricaCriptografíaPapers e InvestigaciónSeguridad de APIs
GitHubantoinet/obike

obike

Ingeniería inversa de la comunicación del protocolo oBike (BLE y HTTP)

Ver Repositorio
4286hace 7 añosRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Descripción del Protocolo oBike (BLE/HTTP)

Este documento proporciona un análisis de los protocolos de comunicación de oBike a partir de enero de 2018.

Los resultados se han presentado en insomni'hack security conference 2019:

  • diapositivas
  • grabación

así como en AREA41 security conference 2018:

  • diapositivas
  • grabación

Comunicación General de oBike

El candado de oBike consta de un microcontrolador TI CC2541, un System on a Chip (SoC) optimizado para consumo de energía utilizado para aplicaciones Bluetooth Low Energy (BLE). El candado en sí no tiene conectividad IP; aprovecha la conexión 3G/4G del dispositivo móvil para comunicarse con el backend de oBike. El candado se comunica por BLE con la aplicación oBike en el dispositivo móvil. Los mensajes del protocolo se reenvían luego al backend de oBike a través de una API REST.

El candado no tiene módulo GPS propio. Por lo tanto, la posición notificada al backend es siempre la del dispositivo móvil, no la de la propia oBike.``` GPS | +---------+ +---------+ +----------+ | oBike | | Mobile | | oBike | | Lock | +--- BLE ---> | Device | +--- HTTPS ---> | Backend | +---------+ +---------+ +----------+

root@kitploit:~
## Secuencia de desbloqueo```
 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)

Pasos:

  1. Envío por BLE del mensaje hello, se envían las coordenadas al candado.
  2. Recepción por BLE de keySource, un valor de 32 bits que representa el número de milisegundos desde que el chip fue encendido (little endian).
  3. Envío por HTTPS de keySource al backend de oBike mediante la llamada REST unlockPass.
  4. Recepción por HTTPS de encKey (índice de clave) y un valor de clave de 128 bits en keys.
  5. Envío por BLE de encKey (truncado a 96 bits) y el index (corresponde a encKey). En ese punto, la bicicleta se desbloqueará.
  6. Recepción por BLE de macKey e index, un acuse de recibo de que el desbloqueo fue exitoso.
  7. Envío por HTTPS de lockMessage, con los valores correspondientes (macKey y ). En ese punto, el backend de oBike registrará el viaje y comenzará la facturación.

Protocolo BLE

Los componentes del protocolo BLE descritos en las siguientes secciones están implementados en el módulo de Python obike.ble_client. Además, se implementa un escáner para detectar anuncios BLE de obike en obike.ble_scanner.py.

Formato General del Comando```

6774 0D 86 59AEB6...3931 FD | | | | | | | | | +-- Check byte | | | +----------------- Payload | | +--------------------- Command type | +------------------------- Length of payload in bytes +------------------------------- Command Signature ('gt')

root@kitploit:~
El mensaje, tanto entrante como saliente, siempre comienza con la firma `\x67\x74`
(ascii `gt`).

La longitud del payload es el número de bytes sin cabecera/tráiler.

El protocolo soporta diferentes tipos de mensaje identificados por un byte. Los dos
bits más significativos definen la dirección del mensaje:```
 0x86   1000 0101     mobile -> obike
 0x46   0100 0101     obike  -> mobile

El byte de comprobación se calcula aplicando XOR al tipo de comando y a los bytes de carga útil:``` check_byte = cmdtype ^ b[0] ^ b[1] ^ ... ^ b[N-1]

root@kitploit:~
El tamaño máximo de PDU es de 19 bytes (cabecera + carga útil + tráiler). Los mensajes que exceden este tamaño se fragmentan.

### BLE getLockRecord/deleteLockRecord

Tipo de comando: `6`  
Estos mensajes se utilizan para gestionar el "lock record", un registro de datos que el chip persiste y que contiene información del último viaje, como memberid, timestamp, identificador de oBike, coordenadas, etc.

Si se llama sin payload, el comando se utiliza para recuperar el registro de bloqueo guardado:```
00000000  67 74 00 86 86                                    |gt...|

Si no hay ningún registro de bloqueo disponible, el bloqueo responde con una carga útil vacía.``` 00000000 67 74 00 46 46 |gt.FF|

root@kitploit:~
De lo contrario, la respuesta del candado contiene varios valores del último viaje, en
el siguiente 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                 |...........|

La figura a continuación ilustra el almacenamiento de nodos en disco y memoria. Los nodos hoja se almacenan en la sección de datos mientras que los nodos internos se almacenan en la sección de metadatos. Las claves en la sección meta contienen referencias a las páginas hijas correspondientes en la sección de datos o en la sección de metadatos. Un archivo de base de datos en el modelo Bolt tiene dos secciones principales: sección de datos y sección de metadatos. La sección de metadatos son las dos primeras páginas del archivo de base de datos. Las páginas en la sección de metadatos almacenan nodos internos o ramas. Las páginas en la sección de datos almacenan nodos hoja o pares clave-valor reales.``` Offset Value Description

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

0045 000000 ? 0048 a901 battery voltag level (little endian) e.g. 4.25V

root@kitploit:~
Cuando se usa con una carga útil, este comando elimina el registro de bloqueo actual:```
00000000  67 74 0d 86 59 d5 ff a4  36 33 39 38 37 37 31 33  |gt..Y...63987713|
00000010  43 14                                             |C.|

El payload para el comando de eliminación consiste en el "Bike Trade Number" que se leyó previamente, es decir, la marca de tiempo en la que se alquiló la bicicleta y el identificador de obike:``` Offset Value Description

0004 59d5ffa4 timestamp (little endian) 000e 3633393837373133 "63987713C" obike identifier

root@kitploit:~
### BLE Push Coords / Get Challenge

Tipo de comando: `1`  
Estos mensajes son utilizados por el dispositivo móvil para indicar la ubicación actual de
la obike, que almacenará.```
00000000  67 74 13 81 30 38 2e 35  33 30 38 34 32 32 34 37  |gt..08.530842247|
00000010  2e 33 37 32 37 36 30 b7                           |.372760.|

El payload consiste en latitud y longitud:``` Offset Value Description

0004 30382e35333038343232 longitude (08.5308422) 000e 34372e333732373630 latitude (47.372763)

root@kitploit:~
El comando también puede usarse sin un payload:```
00000000 67 74 00 81 81                                     |gt...|

En respuesta, el obike envía un desafío, un entero de 32 bits (little endian) que representa el número de milisegundos transcurridos desde el encendido:``` 00000000 67 74 0b 41 00 11 51 00 06 ef 5f 34 aa 01 00 28 |gt.A..Q..._4...(|

root@kitploit:~
### CLI

Todos los comandos de la API web tienen comandos equivalentes para la CLI. Para un registro de salida significativo, use la variable de entorno `RUST_LOG=info`.

```bash
source <(cargo run -- --shell-completions bash)
cargo run -- user list

API

Se puede encontrar un ejemplo de HTTPS basado en Rustls-acme en el repositorio de Rauthy. Se recomienda encarecidamente usar la API a través de HTTPS.

  • Swagger UI: https://<hostname>:<port>/swagger-ui/
  • Swagger: https://<hostname>:<port>/api/v1/swagger.json
  • redoc: `https://:/api/v1/redoc```` Offset Value Description

0004 00115100 ? (constant, sometimes also 00115900) 0008 06ef5f34 challenge (aka keysource) 000c aa01 battery voltage level (little endian), e.g 4.26V 000e 00 ? (constant)

root@kitploit:~
### BLE Enviar claves

Tipo de comando: `2`   
Estos mensajes se utilizan para transmitir la respuesta del desafío a la obike.```
00000000  67 74 18 82 8b 00 00 01  23 45 67 00 2a 72 9d 59  |gt......#d2.*r.Y|
00000010  2f 42 d3 b4 3b 1b 9d 51  e7 67 13 e3 77           |/B..;..Q.g..w|

El contenido del fragmento está vacío: no hay texto que traducir.``` Offset Value Description

0004 8b key index 0005 00000123456700 member-id (explicitly coded in decimal, value is 1234567) 000c 2a729d59 UNIX timestamp, little endian 08/23/2017 @ 12:16pm (UTC) 0010 2f42d3b43b1b9d51e76713e3 enckey (truncated to 96 bits)

root@kitploit:~
El obike responde con un solo byte de estado (00):```
00000000  67 74 01 42 00 42                                 |gt.B.B|

Reinicio BLE

Tipo de comando: 9
Reinicia el chip CC2541.``` 00000000: 67 74 00 89 89 gt...

root@kitploit:~
No se devuelve ninguna respuesta.

## API REST HTTP de oBike

Un cliente para la API REST de obike, incluida la capa de cifrado, está implementado en el
módulo de Python `obike.http_client`.

### Especificación de la API REST

El endpoint de la API REST para toda la comunicación con el backend de oBike es:```
https://mobile.o.bike/api/<version>/

Dependiendo de la llamada REST, se utiliza actualmente v1 o v2.

Las solicitudes realizadas por la aplicación móvil oBike hacia el backend de oBike utilizan los siguientes encabezados:``` Host: mobile.o.bike Connection: keep-alive Accept-Encoding: gzip, deflate Accept: / User-Agent: okhttp/3.4.2 platform: Android Content-Type: application/json; charset=utf-8 version: 2.5.4 Authorization: Bearer 0123456789abcdef0123456789abcdef Content-Length: 397

root@kitploit:~
### Cifrado

A partir del otoño de 2017, se introdujo la versión 2 de la API, que cifra la mayoría
de los payloads de HTTP POST mediante un esquema de cifrado simétrico. Los valores cifrados
se transmiten en el payload de un objeto JSON de la forma:```
{"value": "b9fb151cd004e1d570201c8ee1a42a6bea3053550c545c446f192f11cfebac8389741
94cff9d3985cebf2bc751acc98359769a9886bc02fe9ab9fc1a5a646c46e1c51e668a717343307fc
5dcef00f8bf92e1badc6d0506f31303e5947ee3453d"}

El valor hex se cifra con AES-128, modo CBC, de la siguiente manera:``` ciphertext = AES(plaintext_with_hash, secret_key, iv)

root@kitploit:~
donde `secret_key` es la cadena `oBAddMYFUzLed` con el número de versión de la aplicación móvil
añadido. P. ej., para la versión 2.5.4, la clave secreta es `oBAddMYFUzLed254`.
El vector de inicialización utilizado es `1234567890123456`.

El `plaintext_with_hash` se calcula a partir de:```
plaintext_with_hash = plaintext + '&' + SHA1(hash_key + plaintext + '&')

donde hash_key es la cadena oBaddX4buhBMG.

Así es como se descifra un payload usando OpenSSL:``` $ echo -n "b9fb151cd0...453d" |
xxd -r -p |
openssl enc -aes-128-cbc -d -K 6f424164644d5946557a4c6564323534 -iv 313233343536 37383930313233343536

root@kitploit:~
### Autenticación

El esquema de autenticación de la API REST recuerda vagamente a OAuth/OpenID. Nombre de usuario
y contraseña se envían y, a cambio, el servidor envía tokens de acceso y de actualización
para una nueva sesión. Ejemplo:

Solicitud HTTP:```
POST /api/v2/member/login HTTP/1.1
platform: Android
Connection: close
Accept-Language: en
version: 2.5.4
Content-Type: application/json; charset=utf-8
Content-Length: 396
Host: mobile.o.bike
Accept-Encoding: gzip
User-Agent: okhttp/3.4.2

{"value":"e4526007ae3791e4fabdd5f6833563f8499d076fe5a4039e1ac1bcb7788dc7a053e8b4
384faf202828e6587bbc4bf32f505429129871253ecc388b493f32368ac418f627acc7720c1b5e1a
4ecc35fca7e80dd99062c24cea0b920fcc297164f8703511520f05c2f91ada946dbee9320a0d2f24
f1101036133d53425e91f2b52b7abbea95cde3f395ce8f2c586aa1ea9eaa35fecb26214eb498dbd3
5c56d37b88ebdc100180da662cdae6d6aa50c31d2f92063c2acb8ff45f62d12d34005d48a3"}

Payload descifrado:``` {"phone":"791234567","deviceId":"0123456789abc-0123456789abcdef01","password":"s wordfish","countryCode":"41","dateTime":"1515100814123"}&687fdcb704d0661b67cf1a2 97b5059b1d4d67900

root@kitploit:~
Respuesta HTTP:```
HTTP/1.1 200
Server: nginx/1.10.3 (Ubuntu)
Date: Thu, 04 Jan 2018 21:20:14 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: close
Vary: Accept-Encoding

{"data":{"resourceOwnerId":1234567,"accessToken":"0123456789abcdef0123456789abcd
ef","refreshToken":"0123456789abcdef0123456789abcdef","scope":"customer","expire
sIn":5184000,"registerCoupon":null},"success":true,"errorCode":100}

Las solicitudes autenticadas deben incluir el token de acceso en la cabecera Authorization , por ejemplo:``` Authorization: Bearer 0123456789abcdef0123456789abcdef

root@kitploit:~
### Desbloquear bicicleta

Envía un desafío y recibe una respuesta utilizada para desbloquear la oBike.

Solicitud HTTP:```
POST /api/v2/bike/unlockPass HTTP/1.1
Host: mobile.o.bike
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: okhttp/3.4.2
platform: Android
Content-Type: application/json; charset=utf-8
version: 2.5.4
Authorization: Bearer 0123456789abcdef0123456789abcdef
Content-Length: 397

{"value": "697560f47a113c7950836a914d60a342ea3feac166dd74ae67aabfa5c51f79f27d0a0
3335e72d6fcf747681badbd177499deec15a2e545ef1e293431592f2e080ae5fa6e031064369bbfe
f7bccf1a626d7c22265d2df4bcc20b514bf8aa0263d808d1de57ab3a8ef71093e0d558f0f6fba15b
59901b01ca6c95878d69f2f85c5dd90d9610222eb5f7ca2cf955991b7701496e701d39ed0b05514b
6f014634554"}

Payload descifrado:``` {"dateTime":1515016440105,"deviceId":"0123456789abc-0123456789abcdef01","bikeId" :"041001337","keySource":"54835578"}&cd835995e39c8076f15e3d989727106115b02b8b

root@kitploit:~
Notas:
 * `bikeId` no debe corresponder a la oBike real que se está desbloqueando
 * `keySource` es el desafío de 32 bits generado por el candado oBike como respuesta
 al comando "BLE Push Coords / Get Challenge".

Respuesta HTTP:```
HTTP/1.1 200
Server: nginx/1.10.3 (Ubuntu)
Date: Fri, 05 Jan 2018 16:03:35 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: close
Vary: Accept-Encoding
X-Application-Context: customer:prod:8084

{"data":{"encryptionKey":136,"keys":"ff533ae8ec0b1a1816160e9182af7d74","serverTi
me":1515168215665},"success":true,"errorCode":100}

Mensaje de bloqueo

Envía el código de confirmación al servidor. El servidor comienza a facturar al recibir este mensaje.

Solicitud HTTP:``` POST /api/v2/bike/lockMessage HTTP/1.1 platform: Android Connection: close Accept-Language: en version: 2.5.4 Authorization: Bearer 80828d0bd57c95f6d5012c45e548598e Content-Type: application/json; charset=utf-8 Content-Length: 652 Host: mobile.o.bike Accept-Encoding: gzip User-Agent: okhttp/3.4.2

{"value":"14420a2ef69b61c06667a58bc6842c7b781b3fc650100652982bbe369b5c818df3225c 6cd8bb63e9cbd7c33a21b6d7be5c66b4ff7744ddcc3b5debf1a1fc0a1a8b379278b360edb5ab3ceb 7014954dc084c1f05a76aa311b09aafe5ca84215f8f3e03f4d9187c14bd0215c8f8c1f535cb46f8f fc3cd8f327a9410b0378a61dddc0ffdbadd084ccae67442da6598e52f69452a5a7c4fc087df6f8f0 dfd3277db90ae6ecbaf4c7763f5c2bb24611fd8b89c00a2f87442b526bce73405b7370b8adca045c 2852068516c3f8a473cb79c8635092531ef9104f361370c2d11f352c8b3ad9c356a8f363e8da7120 0dcf36d264009e0098c208089f7fbc113fdf342b4222b1466e3d40287dd1b024b3c55bfcf4dbce28 e7156ea5ef1883dd2c390bf7f5eef7833e72ff33eb04ed501f91c7915670f4bb24382fe232adbe30 7ebf80acfb"}

root@kitploit:~
Payload descifrado:```
{"deviceId":"0123456789abc-0123456789abcdef01","lati":47.3732953,"longi":8.53144
7,"memberId":1234567,"dateTime":"1515159966559","index":"85","timestamp":"151515
9965000","mackey":"6C81C6822A08C30881CFB0D0FAF7D89B","vol":"3.79","transtype":0,
"bikeTradeNo":"5A4F819D639BC4AE1"}&4b5d220310f48744cfadcfd0d554384e2df03921

Notas:

  • mackey corresponde al valor de 128 bits recibido por el comando BLE Hello Command, cuando la bicicleta está en el estado de desbloqueo.

Respuesta HTTP:``` HTTP/1.1 200 Server: nginx/1.10.3 (Ubuntu) Date: Fri, 05 Jan 2018 13:46:07 GMT Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Connection: close Vary: Accept-Encoding

{"data":{"startTime":1515159967958,"message":"Unlocked successfully."},"success" :true,"errorCode":100}

root@kitploit:~
### Lista de pedidos
Obtén una lista de viajes reservados con esta cuenta.

Solicitud HTTP:```
POST /api/v2/order/list HTTP/1.1
platform: Android
Connection: close
Accept-Language: en
version: 2.5.4
Authorization: Bearer 0123456789abcdef0123456789abcdef
Content-Type: application/json; charset=utf-8
Content-Length: 268
Host: mobile.o.bike
Accept-Encoding: gzip
User-Agent: okhttp/3.4.2

{"value":"14420a2ef69b61c06667a58bc6842c7b781b3fc650100652982bbe369b5c818df3225c
6cd8bb63e9cbd7c33a21b6d7be45a70bc261bf64e65f985aa51faefe44de6dcafd6e4037b82f1d05
029b4dcb85caeac6f67df317710c7ccd0b3303c92bb9557e2fde213bc397ede304c0c13a16b0310c
799a569df81f2f07a89c5cca06"}

Payload descifrado:``` {"deviceId":"0123456789abc-0123456789abcdef01","current":1,"dateTime":"151605127 4357"}&11fae15b700f6f69133bfe167c1f99c503359cde

root@kitploit:~
Respuesta HTTP (con JSON formateado):```
HTTP/1.1 200
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 15 Jan 2018 21:21:16 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: close
Vary: Accept-Encoding

{
  "data": {
    "per": 20,
    "current": 1,
    "count": 42,
    "list": [
      {
        "id": 15871962,
        "orderNo": "1801060003123123",
        "status": 5,
        "price": 0,
        "bookTime": null,
        "cancelBookTime": null,
        "startTime": 1515168315000,
        "endTime": 1515168321000,
        "userId": 1234567,
        "bikeId": "041001337",
        "trackId": 17041234,
        "distance": 0,
        "minutes": 0,
        "freeMinutes": 0,
        "carbon": 0,
        "calorie": 0,
        "grade": 0,
        "unitPrice": 1.5,
        "currency": "CHF",
        "currencySymbol": "CHF",
        "actualPrice": 0,
        "actualCurrency": "CHF",
        "actualCurrencySymbol": "CHF",
        "activityId": null,
        "couponId": null,
        "clubcardId": null,
        "savedMoney": null,
        "tempActualPrice": null,
        "tradeNo": "5A4FA1D763990A444",
        "tempEndTime": null,
        "tempMinutes": null,
        "lockType": 1,
        "countryId": 167,
        "cityId": null,
        "platForm": null,
        "promotionActivityId": 0,
        "parkingAreaType": 0
      },
      ...
    ],
    "pages": 3
  },
  "success": true,
  "errorCode": 100
}

Listar bicicletas

Obtén una lista de bicicletas alrededor de las coordenadas proporcionadas (lat, lng).

Solicitud HTTP:``` POST /api/v2/bike/list HTTP/1.1 platform: Android Connection: close Accept-Language: en version: 2.5.4 Authorization: Bearer 0123456789abcdef0123456789abcdef Content-Type: application/json; charset=utf-8 Content-Length: 428 Host: mobile.o.bike Accept-Encoding: gzip User-Agent: okhttp/3.4.2

{"value":"1a585fffc27493e530e50c48b834f0df905fa023d59a7db8d64bae39473cd75adc7c33 e8a0e9173845c9478046cff0c85bccbaecc7acd9cfadfc650c30cae4278d7f906da3a710742b6372 79f21f5367f3ea2fd95564ee7077b85af5ef9ebcf7d456c15616ffda4f25524b587936984b62abfe 8a2a94c042d4893c9e74c267a42aed5310acc5fbb4924d57008cb2081e3e3009fdab5cbc7fc640b7 2efc4e2ba2a10af81ac72aee5100e1c706b9eb500810e40aae855134fe9f625bb34a3626e843922c 7c2b222e6f32daf69f130e9350"}

root@kitploit:~
Payload descifrado:```
{"countryCode":41,"latitude":"47.37326917039802","longitude":"8.531275056302547"
,"deviceId":"0123456789abc-0123456789abcdef01","dateTime":"1508318416019"}&21b7e
af2631f62fca73faf4c63fd75b1302aed4f

Respuesta HTTP (con JSON formateado y truncado):``` HTTP/1.1 200 Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Connection: close Server: cloudflare-nginx

{ "data": { "iconUrl": null, "list": [{ "id": "041003059", "longitude": 8.527892, "latitude": 47.369085, "imei": "6F6E384C30503166", "countryId": 167, "helmet": 0 }, { "id": "041001731", "longitude": 8.526518, "latitude": 47.369303, "imei": "6F6E53696D39706C", "countryId": 167, "helmet": 0 }, ... { "id": "041000911", "longitude": 8.526561, "latitude": 47.377715, "imei": "72616C48496E6974", "countryId": 167, "helmet": 0 }] }, "success": true }

root@kitploit:~
## Instalación```
 $ apt update
 $ apt install git build-essential python python-pip libbluetooth-dev libglib2.0-dev
 $ git clone https://github.com/antoinet/obike.git
 $ cd obike
 $ pip install -r requirements.txt

Referencias

  • Desmontaje y reconstrucción del candado oBike, rescate de bicicletas compartidas sin estación
  • Exploración de debilidades en el sistema de bicicletas compartidas, fuente alternativa
  • Presentación ante la FCC de Huangzhou Luoping Electronics - Smart Locker HBT203
  • Las bicicletas en libre servicio en las ciudades de Zúrich y de Berna quedan retiradas temporalmente de la circulación, rts.ch
  • CVE-2018-16242

Créditos

He contactado con otros investigadores de seguridad, que también han estado trabajando en el sistema de candado de oBike. Gracias por sus aportaciones y contribuciones:

  • @vincent_tky
  • mh (SSD e.V.)
  • Estudiantes de CS3235 de NUS Computing
Descargar herramienta
index