[Перевод] Реверс инжиниринг BLE GATT для взлома Domyos EL500
EL500 — это недорогой эллиптический тренажер от Decathlon с несколькими настройками сопротивления, пульсометром и возможностью подключения по Bluetooth.
el500-чертеж
Мобильное приложение под названием eConnected предназначено для мониторинга сеанса упражнений со смартфона и сохранения его в виде графика для дальнейшего использования. Активные сеансы выглядят следующим образом:
Мне было интересно создать специфичный пользовательский интерфейс и регистрировать данные гораздо более подробно, поэтому я решил выполнить реверс инжиниринг BLE-коммуникаций и создать свой собственный интерфейс на Python.
Но сначала необходимо понять основы BLE и инструменты, которые мы будем использовать.
Протокол: BLE GATT
BLE (Bluetooth Low Energy) — это беспроводная технология для связи между устройствами на коротких расстояниях. BLE поддерживает несколько профилей с различной степенью гибкости, пропускной способностью, энергопотреблением и т. д.
Протокол BLE, который нас интересует, — это GATT (Generic Attribute Profile), он обычно используется на беспроводных устройствах для обмена произвольными данными. Он строго определен для облегчения взаимодействия, что в нашем случае очень кстати.
Если сильно упростить, то профиль — это предопределенный набор служб, и каждая служба содержит группу характеристик. Характеристики могут иметь связанные дескрипторы, которые предоставляют метаданные или специфичные для соединения параметры конфигурации.
Вот диаграмма, иллюстрирующая самые основы:
Диаграмма GATT
Мы можем легко запустить устройство, обнаружить его с помощью какого-либо инструмента Bluetooth, убедиться, что оно действительно работает под управлением GATT, подключиться к нему и узнать, как настроены свойства GATT.
Скриншот nRF Connect
Несмотря на то, что это устройство, как и многие другие, похоже, не использует ни один из механизмов безопасности, поддерживаемых BLE, их все равно стоит упомянуть:
Сопряжение: клиент и сервер проходят через «безопасный» процесс соединения для аутентификации друг друга и обмена ключами, используемыми для дальнейшей коммуникации. Процесс сопряжения поддерживает 4 различные модели ассоциации, каждая со своим собственным набором свойств безопасности и подходящими устройствами с разными возможностями:
Just Works: Неаутентифицированный процесс сопряжения, распространенный в устройствах без экрана или других средств представления кода сопряжения. Начиная с «Secure Connections» BLE 4.2 (обновление более старого Secure Simple Pairing), обмен ключами выполняется с помощью P-256 Elliptic Curve Diffie-Hellman (ECDH), что защищает процесс от пассивного подслушивания, но не слишком эффективен против атак Man-in-the-Middle.
Numeric Comparison: Устройства проходят процедуру обмена ключами ECDH и используют секретный ключ вместе со своими закрытыми ключами для вычисления одного и того же кода сопряжения. Каждое устройство отображает код пользователю, который должен подтвердить, что коды совпадают на обоих устройствах.
Passkey: Одно устройство отображает код сопряжения, который пользователь должен ввести на другом устройстве. Или, что встречается реже, пользователь вводит один и тот же код на обоих устройствах. Код сопряжения используется вместе с общим секретным ключом, полученным из ECDH.
Out of Band: устройства могут использовать или не использовать ECDH для обмена ключами, но они будут использовать каналы связи за пределами Bluetooth для обмена некоторыми защищенными элементами. Например, коснуться устройств, чтобы начать обмен ключами на основе NFC, или устройство отобразит QR-код, который пользователь сможет отсканировать из мобильного приложения и т. д.
Связывание: Аналог функции «запомнить меня» на сайтах. Сопряженные устройства обмениваются и сохраняют необходимую информацию для повторного подключения в будущем без необходимости повторного прохождения процесса сопряжения.
Подписи сообщений: устройства BLE могут генерировать и использовать специальный ключ (CSRK) для цифровой подписи сообщений в целях аутентификации, целостности и неотказуемости.
Авторизация: спецификация BLE учитывает возможность предоставления различных уровней доступа для подключенных клиентов. Учитывая характер функции, GATT может просто сообщать, требует ли данный атрибут авторизации, но последствия этого для продукта остаются на уровне приложения.
Для получения более подробной информации можете ознакомиться со спецификациями BLE Bluetooth SIG.
Инструменты: bluetoothctl, nRF Connect, Android, BlueZ, gattacker…
Учитывая популярность BLE в современных устройствах, существует множество инструментов для работы с ним. Некоторые предназначены для разработчиков, другие — для пользователей или исследователей безопасности…
Их можно разделить на 3 категории:
Агрессивные инструменты: созданы специально для проведения атак или разведки против целей BLE.
Системные инструменты: созданы для интеграции и управления BLE в ОС.
Linux: bluetoothctl, hcitool, bluez, gatttool, и т.д.
Инструменты разработчика: помогают разработчикам создавать и отлаживать свои системы.
Приложения для Android: nRF Connect
Android: Bluetooth HCI snoop log опция режима разработчика
Библиотеки BLE/GATT: bluepy, pygatt, gatt, встроенные SDK, библиотеки Arduino и т. д.
Я попробовал сниффить трафик с помощью ubertooth, просто чтобы убедиться, что не происходит ничего странного. Но подобный проект не стоит этих усилий.
Кроме того, я решил не использовать ни один из многочисленных агрессивных инструментов. Я не смог найти донгл, который бы поддерживал подмену MAC-адреса производителя, хорошо работал с моей установкой и т. д.
Я предпочел создавать свои собственные инструменты по мере необходимости и узнавать больше по ходу дела. В вашем случае всё может быть иначе.
Процесс:
1. Изучение настройки GATT — прямое подключение/обнаружение
Простой способ быстрой проверки устройства на Linux — bluetoothctl. Однако для скорости и удобства я рекомендую использовать приложение для Android nRF Connect Оно простое, универсальное и имеет интуитивно понятный интерфейс. Оно также бесплатное и не требует сложной настройки или специального оборудования.
Запустите EL500, используйте nRF Connect для его обнаружения, подключитесь к нему и изучите службы, характеристики и дескрипторы. Экспортируйте список и сохраните его:
Для очень простых устройств этой информации может быть достаточно. Я нашел устройства, которые имели всего пару характеристик.
В данном случае характеристик много. Включение уведомлений в каждой из них от nRF connect недостаточно для начала приема данных, а запись в них случайных значений тоже ничего не дает.
Нам нужно понять, как выглядит обычный диалог между целью и официальным приложением…
Вы можете попробовать использовать nRF Connect, чтобы подделать цель, и попытаться подключиться к ней из приложения на другом телефоне. Но если вам нужно подделать MAC-адрес, чтобы приложение его распознало, как в данном случае, придётся использовать другой подход…
2. Уведомления «пиявкой»
Вероятно, для этого процесса есть более удачный термин, но лично я называю это «пиявкой»:
Подключитесь к устройству с помощью nRF Connect
Запустите приложение eConnected
Подключитесь к устройству. Это должно привести nRF Connect к автоматическому переподключению.
Начните сеанс
Управляйте устройством (меняйте сопротивление, измеряйте частоту сердечных сокращений и т. д.)
Наблюдайте за полученными уведомлениями nRF Connect (должно произойти автоматическое повторное подключение)
Мне нравится этот процесс, потому что он прост, чрезвычайно информативен и полностью соответствует спецификации BLE.
В этом случае, как только eConnected подключается к устройству, нас начинает заваливать уведомлениями. Они отправляются по разным характеристикам, но начинают вырисовываться некоторые полезные закономерности:
Большинство уведомлений поступает по одной характеристике:49535343–1e4d-4bd9-ba61–23c647249616
Эта характеристика, вероятно, используется для большинства коммуникаций между устройством и приложением, включая отчеты о состоянии.
Около половины уведомлений имеют длину 20 байт и начинаются с одинаковых 4 байт: F0-BC-FF-FF
Если сгруппировать уведомления по длине, то многие из этих групп, по-видимому, имеют общий префикс длиной от 2 до 4 байт, что указывает на то, что реализация использует своего рода идентификатор сообщения/команды для уведомлений.
Мы повторяем процесс несколько раз, по-разному управляя устройством и каждый раз экспортируя журналы nRF Connect. Затем мы переносим их на ПК для дальнейшего анализа. После этого процесса мы можем подтвердить, что сообщения F0-BC сообщают о состоянии устройства, и мы можем начать выяснять, что означает каждый байт в сообщении:
Я надеялся узнать, какое сообщение отправляет приложение, чтобы запустить соединение: я проверил журналы на наличие сообщений с тем же идентификатором, которое было отправлено только один раз за сеанс. Я нашел одно, но создание чистого сеанса из nRF Connect и отправка этого сообщения на ту же характеристику не заставили устройство что-либо сделать.
Если сообщение о запуске передается только логике устройства, без уведомления всех подписчиков (как можно было бы ожидать), придется найти какой-то другой способ.
Поскольку трафик, похоже, не зашифрован, мы могли бы использовать инструменты разработчика Android, чтобы сбросить трафик и проанализировать его. Я так и сделал, но решение вышло довольно медленным и громоздким, данные трудно контекстуализировать и т. д.
Другим быстрым способом, вероятно, будет реверс инжиниринг eConnected приложения и выяснение всего протокола. Попытка сделать дамп прошивки или найти и расшифровать файл обновления прошивки также будет допустимым вектором атаки, хотя это потребует гораздо больше усилий и риск будет выше.
Однако в этом проекте я бы предпочел продолжить беспроводной подход…
3. Подмена цели
Если мы сможем просто обмануть приложение, заставив его думать, что наша система — это легитимное устройство, оно должно отправить нам сообщение о запуске…
схема спуфинга
Как приложение может определить, какие устройства BLE являются эллиптическими тренажерами Domyos, если повсюду бесчисленное множество устройств BLE? Несколько возможных способов:
MAC-адрес устройства. Первые 3 байта — это MAC-адрес поставщика, назначено IANA.
Рекламируемые данные: данные производителя, услуги и т. д.
Имя устройства (настраивается пользователем)
У нас есть доступ ко всей этой информации, поэтому мы можем попытаться ее подделать. Мой адаптер BLE не позволял устанавливать пользовательский MAC-адрес, и я не стал искать тот, который это делает.
Вместо этого я решил написать быстрый и грязный набросок Arduino для платы разработки ESP32. Модули, работающие на этих платах разработки, предназначены для интеграции в реальные продукты, поэтому в них должно быть все, что мне нужно.
Клонирование MAC-адреса, сервисов и характеристик поставщика было достаточно очевидным. Это заставило приложение отобразить поддельное устройство в списке доступных устройств. Но при подключении к нему это не сработало.
Мне также пришлось заново создать CCCD (Client Characteristic Configuration Descriptors). После этого приложение смогло подключиться к устройству и начать отправлять сообщения. Оно написало одно и то же сообщение 10 раз, а затем отключилось:
При использовании версии приложения для iOS eConnected поведение существенно отличалось, вплоть до появления ошибок:
Итак, теперь приложение должно ожидать сообщения от устройства. Я мог бы записать его на устройство с помощью nRF Connect, а затем вернуться в ESP для следующего сообщения… Но это быстро начнет раздражать.
Я бы предпочел автоматизировать этот процесс.
4. Man In The Middle
Самое время найти правильный BLE-донгл и инструмент для атаки, запустить стандартный MITM за несколько минут. Но разве это весело?
Настройка MITM
Python то, Arduino то, бла-бла-бла… Просто куча глючного спагетти-кода для передачи соответствующих сообщений BLE по последовательному порту и предоставления мне красивых журналов для чтения.
Ура! Я успешно вклинился между приложением и устройством и могу перехватывать и изменять сообщения по своему желанию. Все регистрируется в режиме реального времени в формате по моему выбору, что значительно упрощает анализ пакетов.
Журналы MITM
Этого достаточно, чтобы удовлетворить мои текущие «потребности»: создать пользовательское приложение, которое подключается к устройству и регистрирует/отображает его статус с течением времени.
На этом этапе, вместо того, чтобы тратить больше времени на реверс инжиниринг протокола посредством анализа сырых пакетов, я решил сделать шаг назад и начать писать собственный клиент. Он мне в любом случае понадобится в конце концов, и он значительно упростит подделку и манипуляцию пакетами, что в свою очередь ускорит реверс инжиниринг протокола.
Спасибо за внимание. Удачного взлома!