[Перевод] Взламываем «умную» зубную щётку
Только задумайтесь: мы всё чаще используем умные холодильники, машины, розетки и лампочки, умные часы и колонки. Нас окружают умные вещи и умные люди. Но насколько они умные и так ли нужна эта «умность»? А ещё — насколько легко взломать эти вещи? Часы, например, несложно. Давайте посмотрим другой пример: умную зубную щётку.
Однажды я купил новую зубную щётку Philips Sonicare, и во время чистки зубов заметил, что она реагирует на установку насадки миганием светодиода. Быстрый поиск в интернете показал, что насадка взаимодействует с ручкой зубной щётки, позволяя напоминать пользователю о том, что пора купить новую.
Описание щётки на сайте Philips. Она выглядит действительно умной!
Кажется, это стоит изучить.
Реверс-инжиниринг щётки
На основание насадки можно увидеть антенну и крошечную чёрную коробочку, предположительно являющуюся микросхемой. Следующую подсказку можно найти в руководстве: «Радиооборудование в этом продукте работает на частоте 13,56 МГц», похоже на метку NFC. И действительно, при поднесении насадки к моему телефону открылась ссылка на страницу продукта.
Используя приложение NFC Tools, мы можем многое узнать об этой метке:
Это NTAG213.
Он использует NfcA
Он защищён паролем
Есть ссылка на страницу Philips.
Также с помощью NFC Tools можно считывать данные о состоянии памяти и доступе к ней:
Address | Data | Type | Access |
---|---|---|---|
0×00 | 04: EC: FC:9C | UID0-UID2/BCC0 | Read-Only |
0×01 | A2:94:10:90 | UID3-UDI6 | Read-Only |
0×02 | B6:48: FF: FF | BCC1/INT./LOCK0-LOCK1 | Read-Only |
0×03 | E1:10:12:00 | OTP0-OTP3 | Read-Only |
0×04 | 03:20: D1:01 | DATA | Read-Only |
0×05 | 1C:55:02:70 | DATA | Read-Only |
0×06 | 68:69:6C:69 | DATA | Read-Only |
0×07 | 70:73:2E:63 | DATA | Read-Only |
0×08 | 6F:6D:2F:6E | DATA | Read-Only |
0×09 | 66:63:62:72 | DATA | Read-Only |
0×0A | 75:73:68:68 | DATA | Read-Only |
0×0B | 65:61:64:74 | DATA | Read-Only |
0×0C | 61:70: FE:00 | DATA | Read-Only |
0×0D… | 00:00:00:00 | DATA | Read-Only |
0×1F | 00:01:07:00 | DATA | Readable, write protected by PW |
0×20 | 00:00:00:02 | DATA | Read-Only |
0×21 | 60:54:32:32 | DATA | Read-Only |
0×22 | 31:32:31:34 | DATA | Read-Only |
0×23 | 20:31:32:4B | DATA | Read-Only |
0×24 | B3:02:02:00 | DATA | Readable, write protected by PW |
0×25 | 00:00:00:00 | DATA | Readable, write protected by PW |
0×26 | 00:00:00:00 | DATA | Readable, write protected by PW |
0×27 | 00:00:00:01 | DATA | Readable, write protected by PW |
0×28 | 00:03:30: BD | LOCK2 — LOCK4 | Readable, write protected by PW |
0×29 | 04:00:00:10 | CFG 0 | Read-Only |
0×2A | 43:00:00:00 | CFG 1 | Read-Only |
0×2B | 00:00:00:00 | PWD0-PWD3 | Write-Only |
0×2C | 00:00:00:00 | PACK0-PACK1 | Write-Only |
Я повторил этот процесс для одной черной и двух белых насадок W DiamondClean и узнал следующее:
0x00-0x02
содержит уникальный идентификатор и его контрольную сумму.0x04-0x0C
содержит ссылку на магазин Philips.0x22
равен31:32:31:34
для черных и31:31:31:31
для белых насадок соответственно.0x24
содержит общее время чистки.Все остальные читаемые данные идентичны для всех насадок
Расшифровка сохранённого времени
Давайте проведём эксперимент и посмотрим, какие изменения происходят с NFC меткой при использовании зубной щётки:
Считывание метки
При считывании новой насадки, которой ещё не пользовались, данные addr. 0×24 равны 00:00:02:00.
Если просто поставить насадку на ручку щётки (без чистки зубов), ничего не меняется.
Чистка
Я дал щётке поработать 5 секунд
Считываю данные с метки повторно
Данные addr. 0×24 изменились, теперь это 05:00:02:00
Похоже, что addr. 0×24 сохраняет количество секунд, в течение которых использовалась насадка щётки.
Когда щетка используется более 255 секунд, этот таймер переходит на второй бит (02:01:02:00 → 258s). Попытка перезаписать сохранённое время, к сожалению, не увенчалась успехом, так как этот адрес памяти защищён паролем.
Подбор пароля
К счастью, оказалось, что требуемый пароль передается открытым текстом! Значит, все, что мне нужно сделать, это перехватить обмен данными между зубной щёткой и головкой. Покопавшись в своём программно-определяемом радио HackRF, методом проб и ошибок пришёл к следующему рабочему алгоритму.
Запись радиочастотного сигнала
Откроем программу gqrx и настроим её на частоту 13,736 МГц. Теперь, если держать зубную щётку близко к антенне, можно заметить, что головка опрашивается несколько раз в секунду. Приятно удивило, что простая несимметричная антенна принимает сигнал, достаточно сильный для этих целей. Вы можете скачать файл конфигурации gqrx здесь.
Во время чистки зубов считыватель NFC делает короткую паузу, и первая последующая пачка пакетов обновляет счётчик времени. Благодаря возможности gqrx делать I/Q-записи, мы можем записать радиочастотные сигналы пароля следующим (очень сложным) образом:
Включаем зубную щетку
Начинаем запись
Выключаем зубную щетку
Останавливаем запись
Первые пакеты в файле теперь должны содержать пароль в виде обычного текста.
Преобразование записи
Прежде чем этот необработанный I/Q файл будет декодирован, его нужно преобразовать в немного другой формат, чтобы программа декодирования могла его прочитать. Я создал небольшой скрипт-компаньон для gnuradio, который применяет фильтр низких частот и преобразует данные в wav-файл с двумя каналами, содержащими действительную и мнимую составляющие комплексного сигнала. Убедитесь, что подставили правильные пути в блоки источник/приемник и проверьте частоту дискретизации (я использовал 2МГц). Сам скрипт доступен здесь.
Декодирование записи
Я нашел идеальный инструмент для этой задачи под названием NFC-laboratory. После открытия только что созданного WAV-файла он должен выглядеть примерно так, как показано на рисунке выше. В этом случае запись позволяет только увидеть связь, которая идет от хоста к метке (зелёная стрелка). Но для подбора пароля это идеальный вариант. Если посмотреть на спецификацию NTAG213, то можно увидеть, что происходит:
Строка #0-#6 — устанавливается связь с уникальным ID метки
Строка #7 — зубная щётка отправляет пароль (команда 0×1B = PWD_AUTH)
Строка #9 — счётчик времени обновляется до нового значения (команда 0xA2 = WRITE).
Все строчки ниже — это повторный опрос без аутентификации по паролю или записи чего-либо
Итак, пароль для этой насадки 67: B3:8B:98 (подчёркнуто на картинке).
Запись на щетку
С успешно полученным паролем можно установить счётчик на головке щетки на любое нужное нам значение, отправив соответствующие байты по NFC. NFC Tools снова приходит на помощь:
Перейдите в «Другое» → «Дополнительные команды NFC» (Other → Advanced NFC commands)
Установите класс ввода-вывода (I/O Class) на NfcA
Установите данные на 1B:67: B3:8B:98, A2:24:00:00:02:00
Наслаждайтесь обновлённой насадкой щётки (вы же понимаете, что это касается только счётчика времени?)
Вот разбивка команды на шаге 3:
Команда | Описание |
---|---|
1B | PWD_AUTH |
67: B3:8B:98 | The password |
, | Package delimiter |
A2 | WRITE |
24 | To address 0×24 |
00:00:02:00 | Timer set to 0s |
Ниже вы можете увидеть память насадки щетки до и после пользовательских команд NFC:
Обратите внимание, как меняется таймер 0×24
Ну что, зубная щётка успешно взломана, и мы можем играть с таймером по своему усмотрению.
Вот несколько интересных наблюдений:
Только первые два байта по адресу 0×24 используются для хронометража. Как только счетчик достигает FF: FF:02:00, он перестаёт расти (18 часов непрерывной чистки зубов).
Когда сохраненное время превышает 0×5460, зубная щетка мигает светодиодом, чтобы уведомить вас о необходимости смены головки. Это соответствует 21 600 с → 180×2 мин → 3 месяца чистки два раза в день, что точно соответствует рекомендации Philips менять насадки каждые 3 месяца.
Послесловие
Защита при проверке пароля
Самые внимательные читатели могли заметить, что цвет насадки менялся на протяжении всего текста. Это потому, что мне пришлось покупать новую после того, как первая насадка была заблокирована.
Если внимательно посмотреть на содержимое 0×2A — 43:00:00:00 и страницу 18 технического описания, то можно увидеть, что метка настроена на постоянное отключение доступа к записи после трёх неправильных попыток ввода пароля (что у меня и произошло во время экспериментов).
Это означает, что даже ручка зубной щётки не сможет снова записать данные на эту головку.
Генерация пароля
К сожалению, пароль каждой головки щётки уникален, а процесс его извлечения с помощью SDR сложный и требует специального оборудования. Внизу страницы 30 в техническом описании компания NXP рекомендует генерировать пароль из 7-байтового UID. Ниже приведены все пары UID — пароль, которые я получил от своих трёх насадок:
UID | Пароль |
---|---|
04:79: CF:7A:89:10:90 | FF:34: CE:4C |
04: EC: FC: A2:94:10:90 | 61: F0: A5:0F |
04: D7:29:0A:94:10:90 | 67: B3:8B:98 |
Все мои попытки угадать одностороннюю функцию для генерации паролей не увенчались успехом. В зависимости от того, насколько тщательно инженеры Philips отнеслись к этой функции, угадать ее может быть практически невозможно. Но если вам удастся разгадать эту загадку, не стесняйтесь, напишите мне.
Спасибо за внимание!
Что ещё интересного есть в блоге Cloud4Y
→ Спортивные часы Garmin: изучаем GarminOS и её ВМ MonkeyC
→ NAS за шапку сухарей
→ Взлом Hyundai Tucson, часть 1, часть 2
→ Столетний язык программирования — какой он
→ 50 самых интересных клавиатур из частной коллекции