01 июля 2019

Как мы взломали умный дом нашего коллеги, или утренний Drum & Bass

В этой статье мы публикуем результаты исследования умного дома Fibaro Home Center: мы выявили уязвимости в оборудовании Fibaro Home Center 2 и Fibaro Home Center Lite версии 4.540, а также уязвимости доступного через интернет API.

Предложение, от которого нельзя отказаться

Костяк любой технологической компании составляют техноэнтузиасты — люди, которые не просто работают с 9 до 18, а даже в свободное от работы время любят ставить эксперименты, в т. ч. на личных устройствах, и получать интересные результаты. Это исследование нам предложил провести один из наших коллег, в далеком прошлом системный администратор, а сейчас — вице-президент компании. В его доме установлен Fibaro Home Center, который он был готов отдать на растерзание.

Компания Fibaro является в определенном смысле уникальной. Она начала свою деятельность в 2010 году, когда IoT-устройства еще не были широко распространены. На сегодняшний день ситуация изменилась. Согласно исследованию IDC, количество устройств «интернета вещей» всего через несколько лет достигнет почти одного миллиарда. Завод Fibaro Group в Польше производит уже около одного миллиона различных устройств в год, начиная с умных розеток, светильников, датчиков движения и датчиков затопления и заканчивая устройствами, которые прямо или косвенно влияют на безопасность оборудованных ими домов. Также стоит сказать, что продажи устройств компании Fibaro за 2018 год в российском регионе выросли почти в 10 раз в сравнении с 2017 годом. Так что компания играет немалую роль на рынке IoT-устройств, и проблема исследования безопасности умных домов Fibaro весьма актуальна. Именно поэтому, когда наш коллега предложил использовать его систему в качестве стенда для исследования, мы не могли не откликнуться на его предложение.

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

Итак, мы должны были атаковать систему знакомого нам человека. Это, с одной стороны, упрощало задачу, потому что нам не пришлось готовить стенд (система включает в себя достаточно большое количество разнообразных устройств). А с другой — усложняло, так как хозяин знал о готовящейся атаке, и у него была возможность подготовиться, чтобы защитить свой дом от «злоумышленника».

Возможные векторы атаки

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

Этап разведки

Как и настоящие злоумышленники, для начала мы провели небольшую разведку и собрали информацию из открытых источников.

Оборудование для умных домов довольно дорогое, но не нужно быть владельцем конкретного устройства, чтобы заполучить необходимую для начального этапа разведки информацию: компания Fibaro публикует подробные сведения о своих устройствах в интернете. На сайте компании в разделе FAQ мы можем узнать несколько интересных фактов. Например, что домашним центром можно управлять прямо с сайта home.fibaro.com или даже через SMS. Исходя из этой информации очевидно, что устройство при наличии доступа в интернет подключается к облаку, через которое им можно управлять.

Еще на сайте можно узнать, что домашний центр управляет устройствами Fibaro по протоколу Z-Wave. Этот протокол часто используется для автоматизации домашних процессов, так как имеет большую дальность действия по сравнению с Bluetooth и меньшее энергопотребление, чем Wi-Fi.

Также можно узнать, что если в сети уже есть какое-нибудь умное устройство, не принадлежащее Fibaro (например, IP-камера), то в Fibaro есть множество плагинов, которые позволят интегрировать это устройство в единый комплекс и управлять им из домашнего центра.

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

Форма входа в панель администратора

В результате сканирования мы выяснили, что по этому IP-адресу был открыт единственный порт, доступный извне, который на роутере был проброшен в панель администратора Fibaro Home Center. Все остальные порты были заблокированы. Наличие открытого порта противоречит рекомендациям Fibaro по безопасности (см. пункт 10). Однако если бы наш коллега использовал VPN для доступа к домашнему центру, то отсутствие каких-либо точек входа для анализа привело бы к тому, что наше исследование закончилось бы очень быстро и безрезультатно.

Обзор периметра

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

Атака через протокол Z-Wave

Эту атаку можно провести, находясь в непосредственной близости от устройства. Атакующим необходимо исследовать код телекоммуникационного модуля, отвечающего за Z-Wave, методами обратной разработки, — а для этого необходимо находиться в радиусе действия устройства, работающего на базе протокола Z-Wave. Мы таким путем не пошли.

Атака через веб-интерфейс панели администратора

Как мы уже знаем, в системе умного дома есть панель администратора, через которую можно управлять устройством. Это означает, что на этом устройстве есть какой-то бэкенд и хранилище данных. Чаще всего, в силу дефицита оперативной и постоянной памяти на встраиваемых и IoT-устройствах, в роли серверной части выступает PHP или CGI, которые идут вместе с легковесным веб-сервером, а в роли хранилища — файловая система или файловая база данных, например SQLite. Иногда серверная логика и вовсе обрабатывается веб-сервером, который представляет собой скомпилированный бинарный ELF-файл. В нашем случае программный стек состоял из PHP, Lua, nginx, сервера на С++ и lighttpd, а хранение данных происходило как в базе данных SQLite, так и в специальном разделе файловой системы.

Тот факт, что панель администратора работает через API на языке PHP, стало для нас признаком перспективного направления для исследования. На данном этапе для изучения панели администратора на предмет наличия уязвимостей методом «белого ящика» необходимо раздобыть исходный код панели администратора и прошивку самого умного дома в целом. Это дает возможность лучше понять его архитектуру и устройство в нем логических процессов, таких как проверка, загрузка и установка обновления.

Атака через облако

Такую атаку можно провести двумя способами:

  1. попытаться получить доступ к устройству через облако, имея доступ к такому же устройству Fibaro,
  2. попытаться получить доступ в облако, не имея доступа ни к одному устройству Fibaro.

Данный вектор подразумевает тестирование логики ПО, которая зачастую располагается на серверах производителя. Как мы уже выяснили на этапе разведки, домашним центром можно управлять через веб-сайт home.fibaro.com, мобильное приложение и SMS. Даже если вы не имеете статического IP-адреса, ваше устройство будет доступно из интернета. Это означает, что устройство присоединяется к какому-то серверу (скорее всего, это сервер производителя), что может позволить атакующему получить доступ к другому умному дому через общую сеть производителя.

Отличия пунктов a) и б) станут понятнее, когда мы подробнее рассмотрим архитектуру устройства. На данном этапе нам достаточно знать, что так или иначе необходимо собрать данные об общей функциональности устройств, затрагивающей облако.

Анализ образа файловой системы

Опустим описание того, как мы нашли образ файловой системы для нужного нам устройства (о том, как различными способами получить прошивку устройства, мы на примерах рассказываем на тренинге по поиску уязвимостей в IoT и встраиваемых устройствах).

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

Web API

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

Единственная информация, которую можно получить без авторизации, — это серийный номер устройства.

Доступ к документированному API через web-интерфейс

Также в файле конфигурации веб-сервера nginx можно увидеть, что одна часть запросов проксируется на локальный сервер, написанный на C++, а другая часть – на lighttpd, который исполняет код на языке PHP при помощи mod_cgi. Эти обработчики запросов на языке PHP называются сервисами.

Упрощенная конфигурация сервера nginx

Сервисы

Как уже было сказано, обработкой большинства запросов к API занимается бинарный сервер на С++. Однако по необъяснимым причинам разработчики выделили часть логики — перезагрузку устройства, восстановление заводских настроек, создание резервной копии и многое другое — и написали ее на языке PHP.

Веб-сервер, написанный на C++, принимает все запросы от nginx, и обратиться к нему напрямую у нас нет возможности. Это значительно сужает поверхность для атаки на этот веб-сервер — мы не сможем отправить на него произвольно сформированный HTTP-запрос.

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

Серийный номер и аппаратный ключ

У каждого устройства есть серийный номер (serial number) и аппаратный ключ (hardware key), которые служат для авторизации устройства в облаке. Каждый раз, когда устройство хочет осуществить действие, которое так или иначе связано с облаком (например, послать SMS или электронное письмо владельцу устройства, загрузить резервную копию в облако, скачать резервную копию), устройство посылает на сервер HTTP-запрос, в котором в качестве параметров передает серийный и аппаратный ключи. В облаке ключи должны пройти проверку на соответствие в базе. Если авторизация прошла успешно, действие будет выполнено.

Как мы уже знаем, серийный номер не является секретным значением: его довольно легко получить, сделав соответствующий запрос к API. Кроме того, этот номер имеет небольшую длину. Те серийные номера, что встречались нам, соответствуют регулярному выражению (HCL|HC2)-(\d{6}), что является достаточно маленьким пространством для перебора.

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

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

Угроза похищения аппаратного ключа

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

Оба подхода имеют свои достоинства и недостатки, и вопрос «какой из подходов лучше?» является хорошей темой для дебатов — здесь мы его обсуждать не будем.

Разработчики Fibaro решили не наделять владельцев Fibaro Home Center правами суперпользователя и лишней ответственностью. Поэтому мы рассматривали возможности повышения привилегий в системе из панели администратора как полноценные уязвимости.

В модели угроз, которую мы построили для устройства Fibaro Home Center, приоритетной является задача защиты аппаратного ключа. На устройстве есть функция отправки сообщений владельцу умного дома в случае, когда требуется его участие в устранении проблем, о которых сообщает оборудование умного дома. Письмо может отправить любой человек, владеющий аппаратным ключом; список адресатов, которым владелец конкретного аппаратного ключа может отправить письмо, никак не контролируется.

Письма из облака приходят с адреса SERIAL_NUMBER@fibaro.com, где SERIAL_NUMBER — серийный номер устройства владельца. Можно предположить, что не все владельцы устройств помнят серийные номера своих домашних центров и при этом недостаточно бдительны, чтобы их проверять. Вероятно, они могут не заметить подмены серийного номера в адресе отправителя, им будет достаточно, что письмо действительно было прислано с сервера @fibaro.com. И они выполнят действия, которые будут рекомендованы в письме.

Так как проблема изъятия аппаратного ключа из постоянной памяти устройства в большинстве случаев является проблемой времени, то, возможно, разработчикам следует поменять механизм отправки писем и SMS-сообщений.

Сцены

В панели администратора Fibaro Home Center есть возможность создавать «сцены» — сложенные из блоков сценарии поведения или написанные на языке программирования Lua скрипты, которые исполняются при заданных условиях.

Язык Lua известен тем, что имеет возможность создавать изолированное окружение, в котором программист может исполнять произвольные скрипты на языке Lua, не выходя при этом за его пределы. Этот язык известен также различными уязвимостями, которые дают возможность побега из этого изолированного окружения. Хорошим примером может служить не так давно найденная уязвимость в Lua 5.0.3, в модуле bytecode verifier, которая легла в основу CTF-задания. В описании указано, что изначально данная уязвимость была проэксплуатирована автором на «VPN SSL-устройстве», которое он исследовал в рамках своей работы.

К сожалению, нам не повезло: на устройстве, которое мы исследовали, установлен интерпретатор Lua более новой версии (5.2) без модуля bytecode verifier, а все известные простые методы побега из песочницы на Lua были недоступны. В нашем случае задача поиска уязвимостей в изолированном окружении сводилась к поиску уязвимостей непосредственно в интерпретаторе Lua. Это задача трудоемкая и требует времени, поэтому мы решили, что продолжать расходовать ресурсы на работу над этим вектором нерационально.

Изолированное окружение на Lua

Плагины

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

Связь с облаком

Для связи с облаком устройство делает несколько шагов:

  • получает IP-адрес и порт, на который ему следует присоединиться,
  • устанавливает по протоколу SSH соединение c сервером,
  • прокидывает на указанный ему порт 22-й SSH-порт.

Таким образом, управляющий центр Fibaro может присоединиться к домашнему центру через облачный сервер при помощи приватного SSH-ключа, чтобы выполнить какую-либо команду, которую отправит владелец дома, например при помощи SMS или через веб-сайт.

Особенности аутентификации

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

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

Поиск уязвимостей

Первое, с чего мы начали наше исследование, — часть API, которая реализована на PHP.

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

Мы исследовали практически единственную доступную нам входную точку и ничего не нашли. Казалось, что исследование зашло в тупик, но мы решили попытаться изучить вектор атаки через облако.

Доступ в облако, через которое управляется умный дом, у нас тоже отсутствовал (имеется в виду home.fibaro.com), поэтому мы могли собрать информацию об облаке только из скриптов на устройстве, которые к нему обращаются. Как правило, запросы к облаку осуществлялись с устройства при помощи запуска командной утилиты curl. Среди всех запросов особенно интересными оказались те, которые занимаются загрузкой резервных копий в облако и их скачиванием из облака на устройство.

AUTH BYPASS

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

Данная проблема возникала в PHP-коде, вероятнее всего, в результате неправильной обработки сценария, при котором переданное значение аппаратного ключа принимает значение null, то есть параметр был задан, но принимал нулевое значение.

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

Remote code execution

Несколько уязвимостей удаленного исполнения кода были связаны со слабой неявной типизацией языка PHP. Рассмотрим упрощенный фрагмент кода на языке PHP, в котором нами была найдена уязвимость:

Упрощенный фрагмент кода на языке PHP

На устройствах Fibaro значительная часть управления устройством реализована на bash-скриптах, которые в свою очередь вызывают командные утилиты для непосредственного выполнения необходимых действий в системе. Часть этих исполняемых сценариев вызывается прямиком из кода на языке PHP при помощи команды exec. Так как в рассмотренном выше фрагменте кода параметр, который контролирует пользователь, впоследствии попадает в аргументы командной строки, то его необходимо отфильтровать. Если же отказаться от выполнения bash-скриптов невозможно, то лучшим выходом из данной ситуации было бы избежать интерпретации данной строки командной оболочкой bash и запустить эту команду в execve()-подобном виде через функцию pcntl_exec. Однако в силу слабой типизации в языке PHP, а также в силу того, что $_GET['parameter_name'] будет обязательно строковым значением, этот параметр может быть равен 1234some_data_here_or_may_be_code_injection и в этом случае пройдет проверку if($parameter_value > 0). Таким образом, эксплуатация этой уязвимости давала возможность осуществить удаленное исполнение кода из панели администратора и получить доступ с правами root на устройстве.

Возможность проведения SQL-инъекции

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

С развитием программного обеспечения умного дома привнесение новых компонентов и зависимостей неизбежно. Но при этом они должны помещаться в память весьма ограниченного размера. Как следствие, разработчикам должны ставить под сомнение необходимость каждого нового файла в системе, чтобы в дальнейшем избавиться от лишних затрат на память большего размера для каждого устройства. Поэтому разработчики встраиваемых устройств зачастую стараются, насколько это возможно, уменьшить количество исполняемых файлов и библиотек, которые они привносят на устройство. Вероятно, именно поэтому в домашнем центре не было библиотеки для взаимодействия SQLite и PHP, которая при помощи подготавливаемых запросов (prepared statement) могла бы избавить от ошибок вида SQL-injection by design.

Упрощенный пример кода, в котором была допущена ошибка

Как можно видеть на скриншоте, разработчики системы хотели избежать SQL-инъекций при помощи очень интересной фильтрации — путем дублирования кавычек в запросе, и не менее необычного способа обращения к базе данных при помощи запуска из командной строки утилиты sqlite3. Однако такая фильтрация оказалась недостаточной в связи с тем, что кавычки по-прежнему можно экранировать при помощи обратного слэша в первом параметре. Если злоумышленник поставит такой слэш, то это приведет к выходу из контекста строки во втором параметре и к возможности SQL-инъекции в запрос к базе данных.

В версиях старше 4.540 все запросы в базу данных были изменены и безопасно переписаны при помощи подготавливаемых запросов.

«Атака»

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

  1. Пароль нашего коллеги в захэшированном виде с добавлением соли.
  2. Точные координаты дома, в котором находилось устройство.
  3. Геолокация со смартфона нашего коллеги.
  4. Электронные адреса нашего коллеги, с которых он зарегистрировался в системе Fibaro.
  5. Все сведения об IoT-устройствах, в т. ч. не принадлежащих Fibaro, которые были установлены у нашего коллеги дома, включая модель устройства, связку логин-пароль в текстовом виде, IP-адреса устройств во внутренней сети и прочее.

Отметим, что хранение паролей от интегрированных с домашним центром Fibaro IoT-устройств в текстовом виде позволяет атакующему при наличии доступа к домашнему центру и базе SQLite получить доступ на все остальные устройства в доме.

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

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

Мы сформировали специальную резервную копию, в которую поместили защищенный паролем скрипт на языке PHP, который мог исполнить любую нашу команду. После этого мы при помощи соответствующей функциональности облака отправили нашему коллеге письмо и SMS-сообщение, чтобы он обновил ПО на устройстве, загрузив из облака подготовленную нами резервную копию.

Наш коллега сразу понял, что эти сообщения были посланы нами. Во-первых, он ожидал «атаку», во-вторых, формат нашего письма не соответствовал стандартному формату, который использует Fibaro при рассылке. Однако обычный пользователь, не знающий наверняка, что его умный дом пытаются взломать, мог бы и не обратить внимания на разный формат писем. Поэтому наш коллега решил продолжить эксперимент и установил резервную копию.

Веб-сервер, который исполняет PHP-скрипты, запущен на устройстве с правами супер-пользователя. Поэтому после того, как резервная копия была установлена хозяином устройства, мы получили доступ к умному дому с максимальными привилегиями.

Естественно, мы, как порядочные и ответственные люди, не стали совершать никаких зловредных действий в доме нашего коллеги, за одним исключением: чтобы обозначить наше присутствие в системе, мы поменяли ему мелодию на будильнике. На следующий день нашего коллегу разбудила музыка в стиле drum & bass.

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

Итоги

В ходе исследования нам удалось получить потенциальный доступ через облако ко всем домашним центрам компании Fibaro через загрузку и скачивание резервных копий, а также полный доступ с правами root к умному дому нашего коллеги.

Мы обнаружили критические уязвимости на самом устройстве и в облачном сервисе. Мы сообщили о находках компании Fibaro Group, после чего все уязвимости были успешно устранены.

Мы благодарим компанию Fibaro Group за успешное сотрудничество и надеемся, что способствовали повышению уровня безопасности их флагманского продукта.

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

Авторы
  • Павел Черемушкин

    Исследователь безопасности, Kaspersky ICS CERT