Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
obike — Обратная разработка протокола связи oBike (BLE и HTTP) | Kitploit
Инструменты/GitHubGitHub/antoinet/obike
Безопасность BluetoothБезопасность IoTОбратная инженерияБезопасность беспроводных сетейКриптографияСтатьи и ИсследованияБезопасность API
GitHubantoinet/obike

obike

Обратная разработка протокола связи oBike (BLE и HTTP)

Репозиторий
42867 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Описание протокола oBike (BLE/HTTP)

В этом документе представлен анализ коммуникационных протоколов oBike по состоянию на январь 2018 года.

Результаты были представлены на конференции по безопасности insomni'hack 2019:

  • слайды
  • запись

а также на конференции по безопасности AREA41 2018:

  • слайды
  • запись

Общая коммуникация oBike

Замок oBike состоит из микроконтроллера TI CC2541 — энергооптимизированной системы на кристалле (SoC), используемой для приложений Bluetooth Low Energy (BLE). Сам замок не имеет IP-подключения; он использует 3G/4G-соединение мобильного устройства для связи с бэкендом oBike. Замок взаимодействует по BLE с приложением oBike на мобильном устройстве. Затем сообщения протокола передаются в бэкенд oBike через REST API.

Замок не имеет собственного GPS-модуля. Поэтому позиция, сообщаемая бэкенду, всегда является позицией мобильного устройства, а не самого oBike.``` GPS | +---------+ +---------+ +----------+ | oBike | | Mobile | | oBike | | Lock | +--- BLE ---> | Device | +--- HTTPS ---> | Backend | +---------+ +---------+ +----------+

root@kitploit:~
## Последовательность разблокировки```
 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)

Steps:

  1. BLE отправляет сообщение hello, передаёт координаты замку.
  2. BLE получает keySource — 32-битное значение, представляющее количество миллисекунд с момента включения чипа (little endian).
  3. HTTPS отправляет keySource в бэкенд oBike через REST-вызов unlockPass.
  4. HTTPS получает encKey (индекс ключа) и 128-битное значение ключа в keys.
  5. BLE отправляет encKey (усечённый до 96 бит) и index (соответствует encKey). В этот момент велосипед разблокируется.
  6. BLE получает macKey и index — подтверждение успешной разблокировки.
  7. HTTPS отправляет lockMessage с соответствующими значениями (macKey и index). В этот момент бэкенд oBike зарегистрирует поездку и начнёт биллинг.

BLE-протокол

Компоненты BLE-протокола, описанные в следующих разделах, реализованы в Python-модуле obike.ble_client. Кроме того, сканер для обнаружения рекламных BLE-пакетов obike реализован в obike.ble_scanner.py.

Общий формат команд```

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

root@kitploit:~
И входящие, и исходящие сообщения всегда начинаются с сигнатуры `\x67\x74`
(ascii `gt`).

Длина полезной нагрузки — это количество байт без учёта заголовка/хвостовой части.

Протокол поддерживает различные типы сообщений, идентифицируемые байтом. Два старших
бита определяют направление сообщения:```
 0x86   1000 0101     mobile -> obike
 0x46   0100 0101     obike  -> mobile

Контрольный байт вычисляется XOR-сложением типа команды и байтов полезной нагрузки:``` check_byte = cmdtype ^ b[0] ^ b[1] ^ ... ^ b[N-1]

root@kitploit:~
Максимальный размер PDU составляет 19 байт (заголовок + полезная нагрузка + трейлер). Сообщения, превышающие этот размер, фрагментируются.

### BLE getLockRecord/deleteLockRecord

Command type: `6`  
Эти сообщения используются для управления «lock record» — записью данных, сохраняемой чипом и содержащей информацию о последней поездке: memberid, timestamp, идентификатор oBike, координаты и т.д.

Вызванная без полезной нагрузки, команда используется для получения сохранённой записи блокировки:```
00000000  67 74 00 86 86                                    |gt...|

Если запись о блокировке недоступна, блокировка отвечает пустой полезной нагрузкой.``` 00000000 67 74 00 46 46 |gt.FF|

root@kitploit:~
В противном случае ответ замка содержит несколько значений из последней поездки, в следующем формате:```
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                 |...........|

Контент для перевода отсутствует — входной фрагмент пуст.``` 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:~
При использовании с полезной нагрузкой эта команда удаляет текущую запись блокировки:```
00000000  67 74 0d 86 59 d5 ff a4  36 33 39 38 37 37 31 33  |gt..Y...63987713|
00000010  43 14                                             |C.|

Полезная нагрузка для команды delete состоит из «Bike Trade Number», который был считан ранее, т.е. временной метки, когда велосипед был арендован, и идентификатора obike:``` Offset Value Description

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

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

Тип команды: `1`  
Эти сообщения используются мобильным устройством для указания текущего местоположения obike, которое оно сохранит.```
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.|

Полезная нагрузка состоит из широты и долготы:``` Offset Value Description

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

root@kitploit:~
Команда также может использоваться без полезной нагрузки:```
00000000 67 74 00 81 81                                     |gt...|

В ответ obike отправляет challenge — 32-битное целое число (little endian), представляющее количество миллисекунд, прошедших с момента включения питания:``` 00000000 67 74 0b 41 00 11 51 00 06 ef 5f 34 aa 01 00 28 |gt.A..Q..._4...(|

root@kitploit:~
I need to translate the provided text, but I notice the actual content to translate is missing from this request. The chunk data wasn't included after "INPUT:".

Could you provide the Markdown content for chunk 31 so I can translate it from English to Russian? I'll follow all the format-preservation rules once I have the text.```
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)

BLE Отправка ключей

Тип команды: 2
Эти сообщения используются для передачи ответа на вызов (challenge) устройству 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|

root@kitploit:~
3. Если `podman` ещё не установлен, установите его через brew (для macOS) или следуйте [официальной инструкции](https://podman.io/docs/installation) для других платформ:

    ```bash
    brew install podman
    ```

В macOS запустите виртуальную машину Linux под управлением Podman:

    ```bash

    ```

Не подключайтесь от имени root. Пароль — `pass````
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)

obike отвечает одним байтом состояния (00):``` 00000000 67 74 01 42 00 42 |gt.B.B|

root@kitploit:~
### Сброс BLE

Тип команды: `9`    
Сброс микросхемы CC2541.```
00000000: 67 74 00 89 89                                    gt...

Ответ не возвращается.

oBike HTTP REST API

Клиент для obike REST API, включая слой шифрования, реализован в Python-модуле obike.http_client.

Спецификация REST API

Конечная точка REST API для всего взаимодействия с бэкендом oBike:``` https://mobile.o.bike/api//

root@kitploit:~
В зависимости от типа REST-вызова в настоящее время используется либо `v1`, либо `v2`.

Запросы, отправляемые мобильным приложением oBike в backend oBike, используют
следующие заголовки:```
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

Шифрование

Начиная с осени 2017 года была представлена версия 2 API, которая шифрует большинство полезных нагрузок HTTP POST с использованием симметричной схемы шифрования. Зашифрованные значения передаются в полезной нагрузке JSON-объекта следующего вида:``` {"value": "b9fb151cd004e1d570201c8ee1a42a6bea3053550c545c446f192f11cfebac8389741 94cff9d3985cebf2bc751acc98359769a9886bc02fe9ab9fc1a5a646c46e1c51e668a717343307fc 5dcef00f8bf92e1badc6d0506f31303e5947ee3453d"}

root@kitploit:~
Шестнадцатеричное значение шифруется с помощью AES-128 в режиме CBC следующим образом:```
ciphertext = AES(plaintext_with_hash, secret_key, iv)

где secret_key — это строка oBAddMYFUzLed с добавленным номером версии мобильного приложения. Например, для версии 2.5.4 секретный ключ — oBAddMYFUzLed254. Используемый вектор инициализации — 1234567890123456.

plaintext_with_hash вычисляется из:``` plaintext_with_hash = plaintext + '&' + SHA1(hash_key + plaintext + '&')

root@kitploit:~
где `hash_key` — это строка `oBaddX4buhBMG`.

Вот как расшифровать полезную нагрузку с помощью OpenSSL:```
$ echo -n "b9fb151cd0...453d" | \
xxd -r -p | \
openssl enc -aes-128-cbc -d -K 6f424164644d5946557a4c6564323534 -iv 313233343536
37383930313233343536

Аутентификация

Схема аутентификации REST API отдалённо напоминает OAuth/OpenID. Имя пользователя и пароль отправляются, а в ответ сервер присылает access и refresh токены для новой сессии. Пример:

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"}

root@kitploit:~
Расшифрованная полезная нагрузка:```
{"phone":"791234567","deviceId":"0123456789abc-0123456789abcdef01","password":"s
wordfish","countryCode":"41","dateTime":"1515100814123"}&687fdcb704d0661b67cf1a2
97b5059b1d4d67900

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}

root@kitploit:~
Аутентифицированные запросы должны содержать токен доступа в заголовке Authorization
, например:```
Authorization: Bearer 0123456789abcdef0123456789abcdef

Разблокировка велосипеда

Отправьте вызов и получите ответ, используемый для разблокировки oBike.

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"}

root@kitploit:~
Расшифрованная полезная нагрузка:```
{"dateTime":1515016440105,"deviceId":"0123456789abc-0123456789abcdef01","bikeId"
:"041001337","keySource":"54835578"}&cd835995e39c8076f15e3d989727106115b02b8b

Примечания:

  • bikeId не должен соответствовать фактическому oBike, который разблокируется
  • keySource — это 32-битный вызов, генерируемый замком oBike в ответ на команду "BLE Push Coords / Get Challenge".

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}

root@kitploit:~
### Сообщение блокировки
Отправьте код подтверждения на сервер. Сервер начинает биллинг, когда
получает это сообщение.

HTTP Request:```
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"}

Расшифрованный payload:``` {"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

root@kitploit:~
Примечания:
 * `mackey` соответствует 128-битному значению, полученному командой BLE Hello Command,
 когда велосипед находится в состоянии разблокировки.

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}

Список заказов

Получите список поездок, забронированных с помощью этой учётной записи.

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"}

root@kitploit:~
Расшифрованный payload:```
{"deviceId":"0123456789abc-0123456789abcdef01","current":1,"dateTime":"151605127
4357"}&11fae15b700f6f69133bfe167c1f99c503359cde

HTTP-ответ (отформатированный JSON):``` 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 }

root@kitploit:~
### Список велосипедов
Получите список велосипедов вокруг указанных координат (lat, lng).

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"}

Расшифрованная полезная нагрузка:``` {"countryCode":41,"latitude":"47.37326917039802","longitude":"8.531275056302547" ,"deviceId":"0123456789abc-0123456789abcdef01","dateTime":"1508318416019"}&21b7e af2631f62fca73faf4c63fd75b1302aed4f

root@kitploit:~
HTTP-ответ (с красиво отформатированным и обрезанным JSON):```
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
}

Установка```

$ 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

root@kitploit:~
## Ссылки
 * [Разбор замка oBike и его восстановление, спасение велосипеда без док-станции](https://www.youtube.com/watch?v=Vl3Gl8w8n-Q)
 * [Исследование уязвимостей в системе шеринга велосипедов](http://www.comp.nus.edu.sg/~hugh/CS3235/CS3235-SemI-2017-18-FinalProjects.pdf), [альтернативный источник](http://web.archive.org/web/20180102175104/http://www.comp.nus.edu.sg/%7Ehugh/CS3235/CS3235-SemI-2017-18-FinalProjects.pdf)
 * [Заявка в FCC: Huangzhou Luoping Electronics — Smart Locker HBT203](https://fccid.io/2ALWC-HBT203)
 * [Les vélos en libre service dans les villes de Zurich et de Berne sont désormais retirés de la circulation temporairement, rts.ch](https://www.rts.ch/play/tv/19h30/video/les-velos-en-libre-service-dans-les-villes-de-zurich-et-de-berne-sont-desormais-retires-de-la-circulation-temporairement?id=9797225&station=a9e7621504c6960e35c3ecbe7f6bed0446cdf8da)
 * [CVE-2018-16242](https://seclists.org/bugtraq/2018/Sep/30)

## Благодарности
Со мной связывались другие исследователи безопасности, которые также работали
над системой замков oBike. Спасибо за ваши замечания и вклад:
 * [@vincent_tky](https://twitter.com/vincent_tky)
 * mh ([SSD e.V.](https://ssdev.org))
 * Студенты CS3235 из [NUS Computing](https://www.comp.nus.edu.sg/)
Скачать инструмент