Введение
Когда у меня появился умный чайник Xiaomi Mi Smart Kettle Pro - у меня возник тот же вопрос, что и у многих его пользователей: почему его нельзя включить удаленно? Чайник позволяет подключиться к нему через блютуз, задать температуру которую он будет поддерживать и еще пару незначительных параметров, но его невозможно удаленно включить, что нивелируют его ценность как компонента умного дома.
Первая мысль - найти стороннее приложение, которое позволим мне подключиться к чайнику и сжечь его, удаленно включив без воды заставить включаться по утрам, но оказалось что этого до сих пор никто не сделал. При гуглении протокола нашлось его описание, выдранное из приложения для андроида. Само собой, ничего о удаленном включении там не было, зато была заметка что чайник работает на чипе QN9022. QN9022 - чип с открытой документацией, что позволяет проанализировать прошивку малой кровью или написать свою.
Аппаратная часть
Благо (для меня), чайники мрут как мухи, и на барахолке несложно найти мертвый экземпляр за копейки. Внутри чайника всего две платы: плата с силовой частью и плата с логикой. Подвергнув мертвечинку вивисекции можно добыть из него блютуз-модуль с микроконтроллером, зачастую переживающий ТЭН.
Блютуз-модуль должен быть намертво залит силиконом, но китайцы часто экономят и на плате можно встретить всего пару капель силикона, из-за чего модули довольно быстро коррозируют при активном использовании чайника. После нескольких циклов отмачивания в растворителе и грубой чистке щеткой с платы снимаются хлопья силикона, и она становится пригодна для анализа. Платка компактная, состоит из трех основных компонентов (МК, флешка и предположительно микроконтроллер сенсорных кнопок). На платке достаточно много пятачков для доступа к ключевым цепям для тестирования и прошивки. Микроконтроллер достаточно большой, и, слава богу, не BGA, что позволяет отследить дорожки на плате. Вооружившись скальпелем и мультиметром можно выяснить какие ноги микроконтроллера к каким точкам подключены (добрые китайцы оставили на плате шелкографию и у точек есть имена для их идентификации). После прозвона выходит примерно следующая картина:
На самой плате не так и много свободного места, к тому же мне попадались платы как минимум двух видов (различия незначительные), было необходимо как-то зарисовать расположение точек, а заодно и назначение разъемов. Всего два разъема, каждый с тремя проводами, все разных цветов. Назначение всех проводов кроме одного удалось выяснить сняв маску со второй, силовой платы, однако назначение одного из контактов так и осталось для меня загадкой. На одной версии силовой платы он не подключен вовсе, на другой через резистор посажен на землю. Вероятно, он был нужен когда-то раньше, а затем от него отказались, но для совместимости решили форм-фактор плат не изменять. Назначение U3 для меня остается не совсем ясным, но похоже что это контроллер сенсорных кнопок. U1 это явно SPI-флешка, но никакой документации по нанесенным на корпус кодам я найти не смог.
QN9020
У использованной тут модели чипа (QN9022) память для программ не интегрирована внутрь самого чипа, но используется внешняя флеш-память с интерфейсом SPI. Казалось бы - бери и читай, но зачастую в таких случаях используется шифрование данных на флешке, с ключем уникальным для конкретного микроконтроллера. И этот чип оказался не исключением, в даташите явно сказано:
Стоит обратить внимание на вторую заметку: код, выполняющийся внутри микроконтроллера, всегда может вычитывать из флеши данные в их декодированном виде. И даже SWD блокируется после прошивки. У этого чипа есть два брата-близнеца (QN9020 и QN9021) с важным отличием от QN9022: у них флешка интегрирована внутрь чипа. Однако, структура и способ доступа к ней никак не отличается, это все еще отдельный кристалл с интерфейсом SPI.
Тем не менее, никто не гарантирует что процесс прошивки был выполнен в соответствии с рекомендациями и интерфейс SWD действительно отключен, так что стоит проверить этот вариант в первую очередь. Китайцы оставили на плате точки для подключения, видимо использовавшиеся для отладки, однако SWCLK соединено с линией питания резистором с нулевым сопротивлением R4. Зачем это может быть сделано? У этого микроконтроллера, как и у многих других, одни и те же ноги могут быть сконфигурированы для разных целей, и нога P0_7 может быть как SWCLK, так и AIN3.
Зачем нам тут AIN3 к подключать к питанию? На это нам ответит схема устройства АЦП.
AIN3 может быть сконфигурирован как опорное напряжение для АЦП. Учитывая, что у нас аналоговый температурный сенсор, это ожидаемый ход. Значит, для работы SWD надо выпаять R4, и подпаявшись к пятачкам T9-T12 можно попробовать подключиться к микроконтроллеру, для чего я попытался использовать J-Link. Однако, результат немного предсказуем, контроллер не отвечает и наиболее простой путь оказался недоступен.
Загрузчик
Значит, нужно копать дальше, и в первую очередь изучить как происходит процесс прошивки. А происходит он через загрузчик, что хороший знак: чем больше кода, тем больше шансов встретить баг сюрприз-фичу. Загрузчик может работать через UART или SPI и имеет простой командный интерфейс. В нашем случае, необходимые для прошивки пины через UART вынесены на точки T1-T3, и остается подпаять их к USB-UART преобразователю.
Рассмотрим команды загрузчика:
CMD Code |
UART Commands |
Functions |
---|---|---|
0x33 |
B_C_CMD |
Build connection with bootloader. |
0x34 |
SET_BR_CMD |
Set UART baud rate used in ISP mode. |
0x35 |
SET_FLASH_CLK_CMD |
Set clock frequency used by QN902x’s flash. |
0x36 |
RD_BL_VER_CMD |
Read bootloader version. |
0x37 |
RD_CHIP_ID_CMD |
Read the chip number of QN902x. |
0x38 |
RD_FLASH_ID_CMD |
Read flash ID of QN902x. |
0x39 |
SET_APP_LOC_CMD |
Set application routine download location, internal SRAM or Flash. |
0x3A |
SETUP_FLASH_CMD |
Set the flash operation commands. |
0x3B |
SET_ST_ADDR_CMD |
Set the start address of Read, Program, Erase and Verify commands. |
0x3C |
SET_APP_SIZE_CMD |
Set the application size. |
0x3E |
SET_APP_CRC_CMD |
Set the CRC result of verifying application. |
0x40 |
SET_APP_IN_FLASH_ADDR_CMD |
Set the starting address of application storage location. |
0x42 |
SE_FLASH_CMD |
Sector erase flash |
0x43 |
BE_FLASH_CMD |
Block erase flash |
0x44 |
CE_FLASH_CMD |
Chip erase flash |
0x45 |
PROGRAM_CMD |
Download. |
0x46 |
RD_CMD |
Read NVDS. |
0x47 |
VERIFY_CMD |
Verify the application. |
0x48 |
PROTECT_CMD |
Enter into protect mode. |
0x49 |
RUN_APP_CMD |
Run application. |
0x4A |
REBOOT_CMD |
Reboot system. (software reset) |
0x4B |
WR_RANDOM_DATA_CMD |
Write a random number to Bootloader. |
0x4C |
SET_APP_IN_RAM_ADDR_CMD |
Set the starting address of application location in the SRAM. |
0x4D |
SET_APP_RESET_ADDR_CMD |
Set the address of application entry point. |
И там же, рядом, карта разметки флеши:
В глаза бросается команда чтения RD_CMD, которая позволяет прочитать флешку по указанному адресу. Казалось бы - задача решена, но на практике область действия RD_CMD ограничена первыми 0x1000 байтами, в которых располагается NVDS (non-volatile data storage, набор хранимых параметров в виде словаря).
Однако, обнаружилось что загрузчик позволяет загружать программу не только во флешку, но и в ОЗУ. Новый план - загрузить программу в ОЗУ, запустить ее, и используя ее как мост между компьютером, посылающем команды, и микроконтроллером, вычитать содержимое флеши. Последовательность действий для загрузки кода в ОЗУ указана в том же документе:
Накидав простую прошивку, которая через простой UART-интерфейс позволяет читать и писать данные по указанным адресам, и спустя много попыток все же запустив ее, я смог вычитать флешку. Однако, вместо ожидаемого образа была получена пустая область NVDS и очень странные данные в области программы:
Явно виднелась какая-то последовательность, повторяющаяся каждые 0x100 байт, но это отдельная тема. А вот плата перестала запускаться, хотя до этого исправно мигала диодами и сообщала о себе через блютуз. Чтож, видимо придется копать глубже. Посмотрим на карту памяти микроконтроллера:
Нас интересуют области помеченные как "BootLoader" и "ROM". Хотя прошивка и погибла в процессе считывания, код загрузчика никуда из области ПЗУ деться не мог, а значит был доступен для чтения. Анализ, как ожидалось, мог открыть какие-то ошибки реализации командного интерфейса, или проявить скрытые команды (например, показать куда делись команды с пропавшими из списка команд кодами, например 0x3C, вдруг там окажется UNPROTECT_CMD). Дальше уже ничего сложного: загружаем в ОЗУ свой код, через него вычитываем загрузчик, сохраняем его и анализируем дизассемблером. Анализ кода показал следующее:
При загрузке программы (первая команда PROGRAM_CMD) загрузчик стирает флешку. Разумный ход, хотя в документации об этом не было ни слова.
Присутствуют несколько скрытых команд (хотя и не во всех ревизиях чипа), однако мои надежды они не оправдали. Недокументированные команды всего лишь позволяют включить режим быстрой загрузки и сократить время нахождения загрузчика в режиме ожидания активации.
Обнаружилась довольно неожиданная реализация switch-case, поначалу поставившая меня в ступор: вычисление адреса команды выполнялось в подфункции, которая вместо возврата выполняла переход на вычисленный адрес исходя из переданного кода, адреса возврата и массива констант сохраненных по адресу возврата.
После этих новостей у меня появилась новая идея: закоротить флешке ноги MOSI/MISO (или другим способам аппаратно защитить ее от стирания) на время выполнения первой команды PROGRAM_CMD, однако мне не нравился этот способ своей неэлегантностью и неприменимостью к чипам QN9020/QN9021, и я отложил его на случай если ничего другое не сработает. Продолжив ковырять загрузчик просто из интереса, внезапно мне бросились в глаза команды WR_RANDOM_DATA_CMD и SETUP_FLASH_CMD. Про WR_RANDOM_DATA_CMD в документации сказано кратко: The procedure of writing a 32bit random number to bootloader. Зачем, куда? Не ясно, особенно много вопросов вызывает тот факт, что реально загрузчик пишет не 4 байта, а 12 байт присланные с этой командой, однако это снова отдельная тема. Вторая команда куда интереснее:
SPI-флешки имеют командный интерфейс, и хотя формат команд у разных флешек почти всегда одинаковый, то их код может сильно отличаться. Разработчики чипов QN902x приняли славное решение, позволив пользователю самому задавать код команд и тем самым сделав QN9022 почти универсальным чипом в плане совместимости с разными SPI-флешками. В том числе, внимание, код команды для стирания прошивки. И несмотря на слова When the internal Flash is not existent, очень похоже что у чипов с интегрированной флешой этот процесс ничем не отличается. А значит нужно просто-напросто отправить набор команд, в котором коды стирания будут подменена на что-то безобидное, вроде кода чтения или кода выведения флеши из режима сна.
Конец
И... Это работает!
Достаточно после установления связи с загрузчиком отправить первой командой альтернативный набор команд для работы с флешью, затем загрузить в ОЗУ прошивку с реализацией моста-считывателя, вернуть на законное место оригинальный набор команд и запустить прошивку из ОЗУ. После этого можно сдампить флешку, а после перезагрузки плата вернется в рабочее состояние. Разработчики не предусмотрели банальную верификацию очистки флеши, что заняло бы едва ли десяток инструкций и защитило от подобного рода атаки.
Отдельные вопросы вызвал алгоритм шифрования, подозрительно напоминающий XOR с меняющейся маской. А так же мне теперь предстоит длительный процесс разборки сдампленной прошивки, но и это совершенно другая история.
Мою реализацию вышеописанного метода можете посмотреть тут: ссылка на Github.
Комментарии (47)
r1000ru
27.04.2022 21:41Мечтаю о чайнике с ножками из тензодатчиков. Казалось бы элементарное решение - совместить чайник и весы, чтобы он мог не просто контролировать наличие воды, но и сообщать, сколько ее,и у владельца было понимание - включить или сходить долить.
philfreeeu
27.04.2022 23:02+1С тензодатчиками основная задача - ноль калибровать. Но по идее это может делать подставка в момент, когда с нее снят чайник. Но достаточно толстый провод питания будет давать погрешность. Но даже без погрешности пуской чайник с полотенчиком сверху будет думать, что стакан воды в нем есть.
Albert2009ru
27.04.2022 23:53+5CAD MS Paint - очень сильно ???????????? Как там с плагинами для высокочастотной разводки? А если серьёзно, очень хорошая статья. Большое спасибо ????????????
kulhaker478
28.04.2022 10:21Наглядная демонстрация того что, чтобы защищённого человек не создавал, оно так или иначе поддается обходу защиты, спасибо
m0tral
28.04.2022 11:38Все современное на нормальной защите на подписях, тут слишком примитивно все и судя по всему ещё проприетарщина
Tiriet
28.04.2022 12:21+2дожили. чайник на подписи. следующий шаг- унитаз с распознаванием сетчатки шоколадного глаза и уведомлением в случае неавторизованного доступа.
Tarakanator
28.04.2022 12:47-1В случае обнаружения неавторизованного доступа унитаз заякоривает шоколадный глаз и вызывает полицию.
Soarerru
28.04.2022 14:58+2Все же знают историю, как любовница в доме мужика взвесилась на умных весах, а измерение пришло на телефон жене?
m0tral
28.04.2022 11:41+2Вы SWD когда цеплялись, проц сбрасывали? Без RST по опыту заводится крайне мало процов, плюс у SWD должны быть подтяжки по 10-100к обычно, судя по тому что в схеме их нет, там GPIO, которое при старте релизной прошивки блочит SWD
aleaksah Автор
28.04.2022 11:49Конечно. Полный набор: SWDIO, SWCLK, RST, GND, VTref
m0tral
28.04.2022 11:54+1А сопротивления смотрели на IO/CLK? Вообще написали бы что это NXP, это хорошее железо, сейчас китайцы чаще свое говно вставляют, на которое доков днём с огнём не сыщешь..
aleaksah Автор
28.04.2022 12:01NXP они стали с 2015 года, когда NXP поглотила разработчиков серии QN* - Quintic. А зачем мне смотреть сопротивления, после того как я убедился что эти линии подключены только к нужным мне ногам? На моей практике подтяжки ни разу не были нужны, и в документации на QN902x о них ни слова
Ztare
28.04.2022 13:26Вы НЕ хотите включать чайник удаленно. Нагревательные приборы такого класса это не шутка. + непонятно есть ли там какая-то защита от несанкционированного использования. Тут цена безопасности и багов будет невероятно высокой
Dim2010
28.04.2022 13:30Есть предложение, у меня современный прибор для измерения давления, с памятью! А вывести на компьютер что бы анализировать и распечатать, невозможно, интерфейс не предусмотрер! Приходится часами на листочек по одной цифирке переписывать показания! Вы можете , будет время помогите разарботкой интерфейса! Спасибо!
Polaris99
28.04.2022 16:49Вот правда, включать удаленно чайник, в который не могу долить воды и проверить его состояние - это самое последнее, что я стал бы делать в умном доме. Хуже разве что удаленное открытие дверного замка через Интернет.
Sergey78
28.04.2022 17:01А как работает шифрование прошивки? Где хранится ключ, и где код, который занимается расшифровкой? Если в самом МК нет флеша и он стартует с spi-флешки.
alexzeed
28.04.2022 23:48+1В самом МК есть ROM. Код шифрования точно должен быть там (как часть бутлоадера). Расшифровка скорее аппаратная. Ключ либо в ROM, либо прямо в его шифровальном ускорителе может быть свое хранилище для ключа. Наверняка это точно и подробно описано в юзермануале, но он у голландцев под регистрацией.
Vladogor78
28.04.2022 22:25На али видел чайники с подставкой и поворачивающимся краником для воды. Он может сам доливать воду отключать краник и поворачивать краник в другую сторону, чтоб не мешал снимать с подставки. Не знаю как реализовано, но видимо датчики есть какие то, возможно через кольцевые контакты выведенные в подставку. Как минимум датчик, чтоб не перелить воду в чайник, те же герконы или оптические в трубке уровня воды и перекрывающий их шарик.
axe_chita
29.04.2022 16:17Теперь ждем обзор набора «Юный некромансер».
Если без шуток, то статья замечательная, прямо можно сказать пряморукая.
tvr
Невозможность проконтролировать наличие в оном воды и долить её при необходимости дистанционно :))
aleaksah Автор
Контроль наличия воды можно было бы решить сенсором воды или измерением скорости нагрева
tvr
Или весами, по старинке.
А долив чем?
Честно, я не придираюсь — но умные чайники в интерьер умного дома не слишком вписываются.
Tarakanator
весами плохо. Теоретчески на чайник могут что-то положить. Книгу к примеру.
ruomserg
Вот не рекомендовал бы я дорабатывать в таком направлении… Не рекомендовал бы. Потому что одна ситуация, когда чайник включается только в присутствии человека путем нажатия на механический выключатель. Другое — если допускается запуск без непосредственного присутствия. Это почти наверняка другие сертификационные требования, и нарушение инструкции по эксплуатации — а ее стоит читать, потому что многие электроприборы производитель допускает эксплуатировать только под присмотром. И если этот чайник все-таки сумеет загореться, когда вы его дистанционно включите — и спалит квартиру, то весь ущерб от пожара и его последствий будете возмещать вы. Даже если у вас есть страховка ответственности перед третьими лицами — страховая по итогам дознания МЧС может влепить регрессный иск со всеми вытекающими…
В общем, посыл такой: хотите включать чайник дистанционно — покупайте устройство, сертифицированное для этой функции. Во-избежание…
aleaksah Автор
С одной стороны вы действительно правы, с другой - а всегда ли после включения чайника вы держите его в пределах видимости в процессе закипания? Да, добавлением такой функции я сделаю его потенциально опасным обьектом, но вероятность пожара занчительно снижается, если держать это в голове и либо поддерживать его наполненным, либо снимать с подставки когда надолго ухожу. А еще в продолжении умного дома не лишним будет пожарный извеатель на кухне.
Soarerru
С механическим выключателем сейчас всё меньше чайников. У меня два, и оба на сенсорной кнопке. Теоретически - он может включиться "сам" даже без дистанционного управления.
ruomserg
Ну вот это, конечно, да — но теоретически сертификационный орган должен как-то проверять безопасность этой функции. Чисто технически, наверное, должно хватить нормально разомкнутого реле, и двойного резерва в цепи управления (одна нога МК, скажем нулем — запитывает цепь обмотки реле, а другая нога — единицей открывает транзистор управления обмоткой). Плюс WDT, плюс термопредохранитель — должно быть достаточно надежно для бытового применения. По крайней мере, конструкцию типа «симистор с оптроном» в цепи нагревателя с управлением от одной ноги МК — я бы лично не сертифицировал. Достаточно почитать о случаях самовозгорания фенов паяльных станций типа Lukey 8xx, чтобы понять что оно действительно умеет так делать. И это паяльные станции — которые заведомо разойдутся меньшим тиражом, чем чайник…
Vorber
Кстати, некоторые так и делают. У меня совершенно неумный тефаль, который легко заводится в ошибку если его включить неполным, подождать пока он наберёт градусов 60, долить пол литра (примерно) воды. Потом он успевает догреть только до 70-80 и выпадает в "ЕГГ", видимо решив, что расчётное время нагрева превышено и лучше бы выключится от греха подальше.
Fasterpast
А разве отсутствие воды не получится определить по превышению температуры ТЭНа? По идее, пока там есть вода, температура не должна превысить условные 100 градусов, как только до 120 поднялась, быстро все выключаем, значит воды нет. Если удачно датчик размещен, дополнительно никаких проверок и не надо делать...
DanilinS
Нет. При мощности ТЭНа в 1.5 кВт процесс идет очень быстро. Когда датчик увидит превышение температуры - ТЭН будет уже мертв. Да и в обычном электрочайнике ТЭН при работе имеет температуру выше 100 градусов. Примерно 150-200 ( цифры примерные).
zatim
С чего бы это ТЭНу помирать? Датчик не раз в 10 минут опрашивается, а, все-таки чаще. Да и у самого ТЭНа есть собственная теплоемкость.
kevin
У меня профикук именно по температуре в ошибку уходит при малом количестве воды. По wifi интегрирован в НА.
Maks_K2
Даже в обычном не умном чайнике есть механическая защита от перегрева, когда биометрическая пластина отключает тэн
zatim
* биметаллическая
Tiriet
а иногда даже две- биметалл и невосстанавливаемая плавкая- на случай, если биметалл не сработает.
Tarakanator
а я уж думал стоит чип, который смотрит данные с вебкамеры и проверяет наличие хозяина рядом.