Перейти к публикации
Rabb1tRun

Пошаговое руководство взлома фитнес-браслета Xiaomi MiBand 2 в Linux

Рекомендованные сообщения

В этой статье будет приведено пошаговое руководство взлома фитнес-трекера с поддержкой Bluetooth и низким энергопотреблением средствами ОС Linux. 

Эта история началась с моего поста в Facebook, посвященного проблеме отсутствия API для фитнес-трекеров, и почему сей факт мешает исследователям данных создавать что-то полезное и крутое для этих девайсов. 

Тот пост спровоцировал жаркую дискуссию и привлек внимание моего друга Володимира Шиманского, пытавшегося помочь мне с кодом Лео Соареса для моего фитнес-трекера MiBand 2. Володимир пытался запустить этот код, но были проблемы с соединением. Проблема была решена в течение нескольких часов, и код обновлен

Эта ситуация подтолкнула меня к активным действия. Используя вышеуказанный код, я смог подключиться к MiBand 2, поработать с уведомлениями и измерить ритм сердца. Однако этот функционал меня не устраивал. Я хотел получать данные с сенсоров в режиме реального времени и поэкспериментировать с полученной информацией. Мне хотелось создать советника по физическим упражнениям. 

В итоге было решено хакнуть фитнес-трекер. 

Приступаем. 

У меня не было никакого опыта работы с BLE-девайсами (Bluetooth Low Energy), и я решил начать с изучения этой технологии. Выяснилось, что никаких особых сложностей нет: 

  • У каждого BLE-устройства есть несколько служб. 
  • У каждой службы есть некоторые характеристики. 
  • У некоторых характеристик есть дескрипторы (если у характеристики больше чем один параметр или тип соответствует чтению или уведомлению). 
  • У некоторых характеристик есть доступ только на чтение/запись (например, текущее время, статус батареи или информация о последней ревизии). 
  • Некоторые характеристики более сложны и работают, используя запросы/цикл уведомлений (например, монитор частоты сердцебиения в режиме реального времени или авторизация). 

Вышеуказанного списка вполне достаточно для начала работы с фитнес-трекером. 

Также вам понадобятся два приложения для отладки BLE-устройства: анализаторпротоколов Wireshark и BLE отладчик. Кроме того, нужно активировать опции разработчика в устройстве на базе Android (для любителей iOS придется поискать эквивалент в этой платформе). 

Для начала нужно отключить MiBand2 от приложения телефона. 

Посмотрим, какие службы и характеристики есть у нашего устройства. Открываем отладчик для BLE и запускаем сканирование. Должно появиться примерно следующее: 

7D-rVmOdHFk.jpg
 

MAC адрес устройства нам понадобится позже, поэтому лучше эту информацию где-то сохранить или записать. Подключаемся и смотрим перечень служб и характеристик.

hW9neXUQIQ8.jpg
 

Выполнив две простые операции, мы уже получили полезную информацию о нашем устройстве. Схожая функция доступна через командную строку при помощи утилит hcitool и gatttool. 

Запуск сканирования из командной строки: 

sudo hcitool lescan 

Подключение к BLE устройство через Mac адрес и получение списка служб и дескрипторов: 

sudo gatttool -b YOUR_MAC -I -t random 
> connect 
> primary 
> char-desc 

В некоторых случаях могут возникнуть проблемы. В том случае можно перезагрузить устройство или запустить следующую команду: 

ssudo hciconfig hci0 rese 

 Подготовка к сниффингу данных 

Для сниффинга данных во время коммуникации телефона и BLE-устройства нужно включить Bluetooth-логи в настройках разработчика. Вначале необходимо включить настройки на Android-устройстве. Следуйте по шагам, описанным далее. 

До Android 4.1 опции разработчика доступны по умолчанию. Начиная с версии 4.2, нужно сделать следующее: 

1. Откройте раздел Settings на Android-устройстве. 

 2. Выберите раздел System (только на устройствах с Android 8.0 и выше). 

3. Прокрутите вниз и выберите About phone

4. Прокрутите вниз и тапните 7 раз на Build number. 

5. Возвратитесь к предыдущему разделу. Почти в самом низу должен появиться раздел Developer options. 

Откройте настройки разработчика и включите опцию «Enable Bleutooth HCI snoop log». Теперь все коммуникации между телефоном и любым внешним Bluetooth-устройством должны отражаться в файле btsnoop_hci.log. (на моем телефоне с Android 7.0 логи находятся в /mtklog/btlog/btsnoop_hci.log). 

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

 Теперь нужно выполнить следующие шаги для получения информации о том, как работает аутентификация (сопряжение). 

 1. Включите Bluetooth и HCI логи. 

2. Выполните сопряжение устройства с приложением Xiaomi Android App. 

3. Отключите Bluetooth. 

4. Загрузите btsnoop_hci.log на компьютер. 

 5. Откройте файл в Wireshark. 

6. Найдите первый запрос, имеющий отношение к протоколу ATT, с параметром Handle: 0x0055 (который связан с компанией Anhui Huami Information Technology Co, выпускающей переносные устройства и владеющей брендом Xiaomi). 

 Должно получиться примерно следующее:

iNF4iwVdIKE.jpg
 

Выделенный запрос – первый этап аутентификации. 

Как видно из рисунка выше, обрабатываются следующие значения UUID: 

  • Pairing device
  • Main service UUID
  • 0000fee1-0000–1000–8000–00805f9b34fb 
  • Auth Characteristic (Char) UUID
  • 00000009–0000–3512–2118–0009af100700 
  • Notification descriptor (Des) handle 

0x2902 (всегда неизменный) 

Аутентификация состоит из следующих шагов: 

  1. Настройка auth-уведомлений (для получения ответа) посредством отправки двухбайтового запроса \x01\x00 в Des. 
  2.  Отправка 16-байтового ключа шифрования в Char с командой и добавление двух байт \x01\x00 + KEY
  3. Запрос случайного ключа с устройства с командой посредством отправки двух байт \x02\x00 в Char. 
  4.  Получение случайного ключа от устройства (последние 16 байт).  
  5.   Шифрование этого случайного номера при помощи 16-байтового ключа, используя алгоритм шифрования AES/ECB/NoPadding (из Crypto.Cipher import AES) и обратная отправка в Char (\x03\x00 + закодированная информация). 

 Данные в режиме реального времени 

Процесс аутентификации Auth оказался чуть сложнее, и появились некоторые проблемы. Мониторинг частоты сердцебиений отключался через 15 секунд. Ниже показан перечень полученных значений UUID: 

  • Hardware service (HRDW) UUID
  •  0000fee0–0000–1000–8000–00805f9b34fb
  • Heart Monitor Service (HMS) UUID
  •  0000180d-0000–1000–8000–00805f9b34fb
  • Heart Rate Measure Characteristic (HRM) UUID
  •  00002a37–0000–1000–8000–00805f9b34fb
  • Heart Monitor Control Characteristic (HMC) UUID
  • 00002a39–0000–1000–8000–00805f9b34fb
  • Sensor Characteristic (SENS) UUID
  • 00000001–0000–3512–2118–0009af100700
  • Notification descriptor (DES) handle
  •  0x2902 (всегда неизменный)

Выполняются несколько стандартных операций: 

  1. 1. Отключение текущего мониторинга сердцебиений. Отправка запроса \x15\x02\x00 к HMC для одноразовых измерений. Отправка запроса \x15\x01\x00 к HMC для непрерывных измерений.2.  
  2.  Разрешение сырых данных от гироскопа и измерителя сердцебиений посредством отправки команды \x01\x03\x19 к SENS 
  3.   Включение уведомлений для HRM посредством отправки запроса \x01\x00 к DES 
  4.   Начало непрерывных измерений сердцебиения посредством отправки запроса \x15\x01\x01 к HMC 
  5.    Отправка команды \x02 к SENS (не очень понятно, зачем нужна эта команда) 
  6.   Затем в процессе получения уведомлений каждый 12 секунд нам нужно отсылать пинг со значением \x16 к HCM   

 Парсинг данных 

Далее нужно было разобраться, как распаковать информацию, приходящую с устройства, для последующего парсинга. 

Некоторую часть данных можно распарсить из логов, некоторую - нельзя. 

2IhSW4gncjE.jpg
 

Поиск правильных пакетов и изучение системы кодирования может отнять некоторое время. В моем случае я попытался найти похожие байты в пакетах рядом с друг с другом. Некоторые байты повторяются внутри пакета. 

Raw heart: 02102d8c348c448c458c3d8c428c488c 16
Raw heart: 0218468c418c3d8c468c3f8c398c418c 16
Realtime heart: 93
Raw heart: 0220408c448c3f8c428c498c3c8c3d8c 16
Raw heart: 02283d8c398c488c3e8c468c488c328c 16
Realtime heart: 99
Raw heart: 0230438c408c378c3a8c318c458c388c 16
Realtime heart: 102
Raw heart: 02404f8c408c458c428c4d8c558c4d8c 16
Raw heart: 02483e8c3b8c3f8c348c398c318c428c 16
Realtime heart: 98
Raw heart: 02504c8c428c5e8c4f8c588c498c558c 16
Raw heart: 0258478c458c3c8c4e8c3f8c468c4d8c 16
Realtime heart: 100
Raw heart: 0260518c4d8c4f8c4b8c4f8c528c458c 16
Raw heart: 0268408c3f8c538c4d8c408c548c598c 16
Realtime heart: 102
Raw heart: 0278418c508c4e8c548c588c468c498c 16
Raw heart: 0280368c328c2e8c3c8c338c308c3f8c 16
Realtime heart: 101

Здесь можно заметить четкий повторяющийся шаблон 368c 328c 2e8c 3c8c 338c 308c 3f8c в пакете размером 16 байт. Если мы распакуем с учетом, что каждое измерение представляет собой беззнаковый короткий тип размером 2 байта, то получим 7 непосредственных измерений от сенсора сердца. 

Также видно, что второй байт просто увеличивается и связан, как я думаю, с временной разницей между измерениями (ответами). 

Raw gyro: 01de49ffd9ff3c004cffd8ff3b004dffdcff4400 

Raw gyro: 01df4cffd6ff44004dffd8ff40004cffd1ff4700 

Raw gyro: 02e1103231323d3274328e329632af32c732cf32 

Raw gyro: 01e34fffd7ff56004bffc7ff590049ffccff4c00 

Raw gyro: 01e443ffccff43004effcdff40005bffd4ff4c00 

Raw gyro: 01e558ffc9ff5f005effbfff66005fffb0ff5900 

Raw gyro: 01e64cffacff60005cffa7ff410066ffc9ff4600 

Raw gyro: 01e760ffdcff4b0051ffe4ff4f0034ffdeff5300 

Raw gyro: 02e903365c36813663361036543688374139fe3a 

Raw gyro: 01eb4bffc3ff50004fffc1ff430047ffbbff4100 

Raw gyro: 01ec3effb2ff3c0050ffbfff560047ffccff7300 

Raw gyro: 01ed4fffe0ff78005cffebff8e0056fff6ff8300 

Raw gyro: 01ee7efffbffa1008bff0f00bc00b1ff1900b800 

Raw gyro: 01ef9bff0c00d10095fff3ffd600b7ff0800df00 

Raw gyro: 02f12445314600479e473348aa481c499749244a 

Raw gyro: 01f3c3ff1600fe00beff1800f200a6ff0800e700 

Raw gyro: 01f4a9fff8ffd300a7fff3ffd700a9fff1ffdf00 

Raw gyro: 01f5b1fff8ffe800b4fff1fff700acfffcffef00 

Raw gyro: 01f67ffff7ffc0006bfff4ffb00078ffe9ffb600 

Raw gyro: 01f786ffecffc0006ffff0ffbc0060fff1ffc000 

Raw gyro: 02f9ca4cbb4c784c964ca84c784c854c444c1b4c 

Raw gyro: 01fb7cff0f00bb007eff2700ae0083ff30009800 

Raw gyro: 01fc79ff1800b00076ff0f00bc0068ff0900d900 

Raw gyro: 01fd78ff07000c01f6fffbff19011c000b00f600 

Raw gyro: 01fe4b001100d30054000700c3004300efffeb00 

Raw gyro: 01ff1f00d0ff1701fbffe8ff1b01e3ffffff1101 

Raw gyro: 0201214b014bec4ad04aba4acb4abe4aba4abd4a 

Raw gyro: 0103efffecfffc00e3fff3fff300defff3fffc00 

Raw gyro: 0104e3fff0fff400e6ffefff0301dbffe9ff0c01 

Raw gyro: 0105e3fff0ff0301e6ffe6fffc00dcffecfffc00 

Raw gyro: 0106dffff0fff700dbffeefff600d6fff0fff400 

Raw gyro: 0107dfffecffff00e1fff0ff0301defff3fffc00 

В случае с гироскопом ситуация оказалась чуть сложнее. Но я думаю, что упаковка должна выполняться схожим образом, как и для данных о частоте сердцебиения. Однако здесь у нас 3 измерения знакового типа для каждой оси гироскопа, а сам пакет размером 20 байт. Таким образом, данные от всех сенсоров укладываются не в 12, а в 3 измерения по осям x, y, z. Первые 2 байта играют ту же роль, что и в предыдущем случае. В итоге моя гипотеза оказалась верной. 

 Код 

Код, как обычно, можно найти на Github с примером использования. Ничего сложного нет, и я решил подробно не рассматривать этот момент в статье. 


View full article

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да нах он нужен уде 4 вышел

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

не представляю в какой вселенной это может пригодиться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я в качестве разминки бы попробовал)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете опубликовать сообщение сейчас, а зарегистрироваться позже. Если у вас есть аккаунт, войдите в него для написания от своего имени.
Примечание: вашему сообщению потребуется утверждение модератора, прежде чем оно станет доступным.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.


×
×
  • Создать...