
Приветствую! Меня зовут Владимир, и я работаю реверс-инженером в BI.ZONE Hardware Lab или просто — в «Лабе». Объектом моего очередного исследования стал необычный девайс — видеодомофон.
Я привык к домофону как к висящей на стене трубке с кнопкой, открывающей дверь. Конечно, мне были знакомы и варианты с маленьким экранчиком, на котором видно ровным счётом ничего: чёрно-белую картинку, зернистую и с едва распознаваемыми силуэтами. Но однажды в мои руки попало продвинутое устройство: с сенсорным экраном и подключением по Wi-Fi. Не буду называть конкретный бренд, поэтому просто представим, что подобными видеодомофонами решили оборудовать ЖК, в котором я живу. Меня хлебом не корми — дай поковыряться в железках, поэтому я его разобрал и... нашёл уязвимости.
Я руководствовался мыслью: а могут ли меня подслушивать? Такой же мотив сработал в истории с саундбаром Yamaha, о которой я писал ранее. Эта статья — о том, как я исследовал видеодомофон и какие недостатки мне удалось обнаружить.
Внутри домофона: как работает прошивка
Для начала покажу, как выглядит это чудо:

На обратной стороне — клеммы для подключения питания, сигнализации, звонка и Ethernet-шнурка, который по факту оказался разъёмом PoE (можно питать домофон сразу от локальной сети). Торчащие провода — это уже мои доработки, и о них я расскажу ниже.

При запуске аппарата первым делом пошёл в настройки, поискать что-нибудь про Telnet/SSH/FTP, но ничего полезного не нашёл. Поковырявшись в веб-интерфейсе, я обнаружил возможность обновлять прошивку — это могло пригодиться в будущем.
После этого я пошёл гуглить обновления, однако файлов прошивок найти не удалось. Обнаружилась только вендорская утилита, общая для всех произведённых устройств, которая упрощает работу сервисных инженеров по настройке и раскатке инфраструктуры. Правда, по серийному номеру моего экземпляра в ней ничего не нашлось.
Тогда я принял волевое решение — разобрать девайс, понимая, что в случае неудачи придётся раскошелиться на новый дорогостоящий аппарат. Сказано — сделано.

Судя по начинке, основная плата домофона — это, по сути, контроллер дисплея, Wi-Fi и PoE. Отдельная оранжевая платка на фото ниже — ничто иное, как съёмным CPU с оперативкой и флешкой. Похоже, так сделано для удобства обслуживания.

Что интересно, рядом с маленькой платой расположен странный нераспаянный разъём CN2
(на фото я к нему уже припаялся), на двух выводах которого есть резисторы — верный знак чего-то важного (например, UART-консоли). К нему бы и подключиться, но сначала нужно осмотреть съёмную плату: снять прошивку и изучить содержимое.

Правда, BGA-чипы я на тот момент запаивать обратно (реболить) не умел, так что оставил этот вариант ребятам из «Лабы», а с UART можно было поработать и самому.

Увидеть лог загрузки — это, конечно, круто! Но куда круче — увидеть заветное: «Hit any key to stop autoboot». Активно жму Enter и попадаю в меню U-Boot. В очередной раз напоминаю себе — пора научиться реболить BGA, после чего набираю команду help
и ищу среди доступных команд что-то для работы с eMMC. Судя по всему, mmc read
сгодится. Опыт получения дампа флешек через UART у меня уже был, поэтому я просто адаптировал старый Python-скрипт под имеющийся вывод.

Дампятся такие штуки обычно ооочень долго (за это время проще научиться паять BGA), но я парень упёртый — оставил читалку на ночь. К утру скрипт всё ещё работал, так что я прервал чтение и поправил его так, чтобы он дампил только нужные файлы. Например, /etc/shadow
пригодился бы для брута учёток и входа по SSH (telnet на домофоне был выключен). Увы, ничего набрутить не удалось.
Что ж, оставался вариант дампить все исполняемые файлы и искать в них механизм обновления, про который писал выше. Так, под подозрение попали каталоги /sbin
и /usr/sbin
— там было больше всего интересного, вроде xxxx-upgrade
, xxxxManager.py
(имена файлов не настоящие). Дождавшись окончания дампа, я запустил поиск строки с ошибкой обновления, что-то вроде Upgrade failed. Error code 123 (точную формулировку я забыл, а скрина не осталось). Нужный файл нашёлся.
Дальше начался долгий и нудный процесс изучения механизма обновления, запуска всех связанных скриптов и файлов у себя на системе для отладки, и, конечно, написание своего скрипта для создания файлов обновлений.
Если кратко, структура файла такая:
tar-файл с
uImage
иuImage.dtb
bz2-файл с
rootfs
Файлы из п.1 и п.2 упакованы в структуру с особым заголовком и зашифрованы захардкоженным 3DES-ключом
На основе MAC-адреса домофона, захардкоженного массива из 16 байт под названием
license number
и версии прошивки формируется файл лицензииФайлы из п.3 и п.4 упаковываются в .tar.gz архив — это и есть файл обновления
Ниже показан кусок функции проверки файла обновления.

Сказать, что алгоритм обновления сложный, — ничего не сказать. Со стороны, без знаний о структуре прошивки, даже имея на руках файлы, взломать алгоритм нереально. Но, как говорится, есть нюанс.
Описание уязвимости
Пока разбирался с механизмом обновления, а именно с тем, кто и в какой последовательности обрабатывает файл, загруженный через веб-интерфейс, я заметил следующее:
Сначала распаковывается
.tar.gz
вызовомgunzip
, который убирает суффикс.gz
, оставляя.tar
, и передаёт результат в вызов следующей командыВызывается команда
tar -x -C /tmp/upgrade
, которая принимает tar-архив черезstdin
; на выходе — файл лицензии и зашифрованный файл сrootfs
иuImage
Команда
tar
— это не отдельный бинарь, а симлинк наbusybox
, что для embedded-устройств в порядке вещей
Не зная, как ещё подступиться к домофону, я залез в исходник команды tar
в самом busybox
. Тамошнее описание меня не просто удивило, а конкретно подзадорило. Если грубо, оно звучало так: тут есть уязвимость, попробуй ею не воспользоваться. Ну я и попробовал.

Сделал всё, как там написано, только в качестве файла, который должен оказаться на устройстве, я подсунул PDF-файл с какой-то справкой. Протестировал обновление — и... через веб-интерфейс я получил доступ к своему PDF!
Что ж, нужно было закреплять успех — самое время подменить /etc/shadow
. Нехитрые манипуляции с содержимым tar
— и вот он, доступ на устройство по SSH, готов.
Примечание: на домофоне за SSH отвечает
dropbear
, а в его конфиге разрешена только авторизация по ключу, так что для получения SSH пришлось ещё и патчить конфиг.
Что же получается? Если в мой подъезд проникнет кто-то нехороший, он сможет подключиться к домовой сети и закрепиться на местных домофонах? И да и нет. Дело в том, что по умолчанию вход в веб-интерфейс защищён паролем, и этот пароль — 112233
— указан во всех руководствах к устройству. Так что, зная пароль, можно обновить прошивку и, например, через встроенный микрофон подслушивать, что происходит в квартире — без ведома жильцов. А если к домофону подключены IP-камеры, можно получить и видео с них.
К сожалению, в моём случае на домофоне стоял именно дефолтный пароль — так (не)настроила управляющая компания.
Митигация рисков
Есть плохие и хорошие новости. Начнем с плохих:
Попав в консоль, можно включать запись с микрофона и смотреть видео с IP-камер
Производитель больше не обслуживает клиентов из РФ, а выпустить обновление может только он
Через веб-интерфейс можно сделать сброс до заводских настроек, что вернёт дефолтный пароль
Изначально присутствующий беспарольный SSH-доступ по неизвестному публичному ключу предоставляет доступ неизвестно кому (вендору или УК)
Но хорошая новость в том, что решение есть: чтобы устранить уязвимость, достаточно обновить busybox
до последней версии и не использовать пароль по умолчанию.
Тем не менее моя паранойя не позволила мне пользоваться устройством или рекомендовать его знакомым.
Вишенка на торте: запуск DOOM II
Ну и по традиции я решил запустить на домофоне DOOM Ⅱ. Основные сложности: нужно было собирать игру под не самое шустрое устройство, а главное — под сенсорный экран. Подключить клавиатуру не вариант, пришлось выкручиваться.
Хотелось сделать всё красиво, чтобы можно было не просто посмотреть на картинки, а нормально поиграть. Пришлось разбираться, как хранятся ресурсы игры, как вывести нужные картинки на экран, как обрабатывать касания и много чего ещё. Главной головной болью стал SDL2, потому что все современные форки DOOM завязаны на этом фреймворке, а в дефолтной прошивке его не было. Собирать его с нуля — плохая затея (я, конечно, попытался, но ничего не вышло).
Но процесс оказался крайне увлекательным. Я нашёл форк под названием fbDoom
, заставил его работать с ALSA Audio и, конечно же, реагировать на нажатия по сенсорному экрану. Результат — в этом видео.
P.S. У нашей Лабы теперь тоже есть свой бложик. Всё, что не под NDA, и может быть полезно реверс-инженерам, работающим с железками, но по формату не подходит Хабру — там.
DrMefistO Автор
Я не стал рассказывать в тексте, но пришлось очень долго мучиться с отрисовкой сенсорных кнопок на экран, чтобы было понятно, куда жать. На видео видно результат:)