Содержание статьи
![](/wp-content/themes/engine/img/info-icon.jpg)
INFO
Этот текст основан на моем докладе Oldschool Way of Hacking Microdigital IP-cameras, с которым я выступил на ZeroNights 2019. Многие просили меня прислать слайды, и я решил, что статья с разбором всех уязвимостей будет еще полезнее.
Итак, моей задачей было выбрать такого производителя, который, с одной стороны, давно присутствует на российском рынке, с другой — еще не привлекал внимание специалистов по безопасности. Мой выбор пал на корейскую фирму Microdigital, которая производит IP-камеры.
Сайт компании обещает нам широкий ассортимент: «свыше 30 моделей регистраторов, свыше 150 моделей видеокамер». Отлично!
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image1.jpg)
Компания существует на рынке (в том числе и российском) уже больше двенадцати лет, а это значит, что ее продукция распространена. Оказалось даже, что в 2011 году был заключен договор на оснащение более 30 тысяч российских автобусов камерами этой фирмы.
В первую очередь меня заинтересовали устройства серии N, они достаточно продвинутые, но при этом пока что не стали объектом тестирования кого-то из исследователей. Пора исправить это! Я выбрал модель MDC-N4090W, которая предназначена для использования внутри помещений. Подробную информацию об устройстве можно почерпнуть на сайте производителя.
![Картинки по запросу MDC-N4090W](https://xakep.ru/wp-content/uploads/2019/11/249353/image2.jpg)
Изучение камеры
Начинать любое исследование железа лучше всего с изучения доступной документации.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image3.jpg)
Открываем PDF, полученный на сайте Microdigital, и узнаем, что у камеры есть веб-интерфейс с пользователями root (пароль root) и anonymous.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image4.jpg)
Ну и раз уж мы на сайте компании, прихватим актуальную прошивку для камеры. Долго искать не пришлось, она доступна в соответствующем разделе.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image5.jpg)
Не факт, правда, что в прошивке содержится вся нужная для тестирования информация, поэтому смысл ее изучать будет, только если нет полноценного админского доступа в консоль устройства либо когда надо изучить апдейт. Поэтому не будем сейчас тратить время и вернемся к прошивке позже.
Подготовка устройства к тестированию
Приступим к изучению аппаратной составляющей. Для этого разбираем устройство (ничего сложного, четыре винта по периметру) и получаем печатную плату.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image6.jpg)
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image7.jpg)
Также видим следующее:
- память S34ML01G100TF100;
- чип DM368ZCE;
- интерфейсы: четыре пина UART, USB, MicroSD, Ethernet.
Пины, отмеченные как BLE, я не рассматриваю, так как это, скорее всего, контакты для подключения модуля Bluetooth. Нас это в данный момент не интересует.
Модуль S34ML01G100TF100 — энергонезависимая NAND-память в корпусе TSOP-48. Datasheet легко гуглится. Из него узнаем подробнее о типе корпуса (NAND08) и размере хранилища — 128 Мбайт.
Для дальнейшей работы потребуется сделать бэкап данных, чтобы в случае «окирпичивания» камеры можно было вернуть ее в изначальное состояние. Для этого идеально подходит программатор ProMan TL86 или TL866 с переходником NAND08 → DIP48.
Содержимое флеш-памяти сохраним в нашу рабочую директорию. Как и к прошивке, возвращаться к ней нужно будет только в том случае, если не выйдет дорваться до админской консоли.
![Картинки по запросу tl86](https://xakep.ru/wp-content/uploads/2019/11/249353/image8.jpg)
Для чипа DM368ZCE тоже не составило проблем нагуглить документацию (PDF). Оказывается, архитектура чипа — ARM. К тому же из документации можно достать его распиновку, но нам она не потребуется.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image9.jpg)
Пройдемся по интерфейсам. Из документации очевидно, что USB и MicroSD нужны в основном для того, чтобы подключать к устройству внешние носители и использовать их в качестве хранилища. Для полноты картины можем подключить к устройству USB-фаззер facedancer21 и, используя утилиту umap2scan, получить список поддерживаемых устройств.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image10.jpg)
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image11.jpg)
К сожалению, камера не поддерживает ни одно из известных нам устройств.
Как насчет UART? Тут предстоит определить, за что отвечает каждый пин и какова скорость передачи данных. Для этого воспользуемся логическим анализатором Saleae Logic. Для удобства я подключился через проводок, который соединяет плату устройства и инфракрасные лампочки.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image12.jpg)
Пронумеруем пины для удобства.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image13.jpg)
Прежде чем включать логический анализатор, подключаем заземление к пину GND интерфейса для подключения BLE.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image14.jpg)
Теперь включаем логический анализатор и само устройство и смотрим, что из этого выйдет.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image15.jpg)
После включения устройства на пине номер 3 (в программе отсчет идет с нуля и пин нумерован как 2) передаются бинарные данные. Этот пин интерфейса UART отвечает за передачу данных (TX). Просмотрев длину одного бита, получаем текущую скорость передачи — 115 200 бит/с. При корректных настройках мы даже можем разглядеть часть текста.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image16.jpg)
У пина под номером 1 постоянное напряжение 3 В — следовательно, он предназначен для питания. Пин номер 4 связан с пином GND интерфейса для подключения модуля BLE. Значит, этот пин тоже «земля». И остается последний пин под номером 2, он отвечает за прием байтов (RX). Теперь у нас есть вся информация для общения с камерой по UART. Для подключения я воспользуюсь Arduino UNO в режиме переходника TTL.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image17.jpg)
Начинаем мониторить порт UART и получаем следующее.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image18.jpg)
При старте устройства первым делом подгружается загрузчик системы U-Boot. К сожалению, на уровне загрузки пин TX отключен в настройках камеры, поэтому мы можем наблюдать только отладочный вывод. Через какое-то время подгружается основная система, позволяющая ввести логин и пароль для доступа в администраторскую консоль. Пара root/root (аналогичная той, что используется для веб-админки и указана в документации) прекрасно подошла.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image19.jpg)
Получив консоль, мы можем изучить все работающие сервисы. Но не забываем, что у нас есть еще один неизученный интерфейс — Ethernet. Для его исследования нужно будет подготовить систему мониторинга трафика. Причем важно отслеживать первое же подключение к сети.
![](/wp-content/themes/engine/img/info-icon.jpg)
INFO
Мы должны начать перехватывать трафик сразу, поскольку некоторые устройства при первом подключении начинают скачивать обновления. Не факт, что в следующие разы получится перехватить коммуникации.
Для перехвата трафика я буду пользоваться устройством Lan Tap Pro.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image20.jpg)
Никакой связанной с обновлениями активности мы, впрочем, не обнаруживаем. На этом разведка закончена, и мы полностью готовы к поиску уязвимостей!
Сетевая часть
Просканируем порты утилитой Nmap и получим список открытых портов.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image21.jpg)
Пройдемся вкратце по доступным нам сервисам.
FTP
При подключении сервис запрашивает логин и пароль. Анонимный вход отключен. Но и тут подошел вариант root/root!
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image22.jpg)
Теперь мы можем заходить в любую директорию и получили удобный способ закидывать файлы на удаленный хост.
Telnet
При подключении по Telnet опять же требуется логин и пароль одного из реальных аккаунтов и уже не в первый раз подходит пара root/root. Обрати внимание, что нам теперь не нужна консоль UART, так как все то же самое можно делать удаленно по Telnet.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image23.jpg)
RTSP
Для подключения к RTSP опять же нужно авторизоваться как root/root. Ссылка для подключения принимает вид rtsp://root:root@192.168.1.151:554/Primary
.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image24.jpg)
Веб
Изучив устройство веб-сервера камеры, я составил вот такую схему.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image25.jpg)
На сервере находятся скрипты на PHP и CGI-приложения, которые общаются с исполняемыми файлами из директории /usr/local/ipsca/
(преимущественно общение идет с MainProc
). Для хранения всех настроек используется база данных SQLite 3.
С нее-то мы и начнем искать уязвимости. База данных хранится в /usr/local/ipsca/mipsca.db
. В ней лежит все — от логов системы до настроек автоматической загрузки записей камеры на удаленный сервер. Структура базы данных видна на скрине ниже.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image26.jpg)
Мое внимание привлекла таблица User. Она отвечает за работу с данными пользователей: логин, пароль, привилегии.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image27.jpg)
Пароль пользователя хранится в колонке Password в незашифрованном виде, то есть, получив доступ к базе данных, злоумышленник может узнать пароль администратора и протестировать его на других доступных сервисах.
Переходим к скриптам на PHP. В веб-директории /root/httpd/htdocs/Web
лежит три скрипта: download.php
, login.php
, upload.php
.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image28.jpg)
Файл login.php
не особенно интересен, так как PHP тут используется только для настройки компонента ActiveX, нужного для браузерных дополнений, которые стримят видео на сайте.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image29.jpg)
Файл download.php
принимает на вход название файла для скачивания, проверяет его расширение и, если такой файл найдется в папке updownload
, отправляет в ответ его содержимое.
В скрипте нет проверки названия файла, так что если кто-то вдруг решит положить в этот каталог исполняемый скрипт на PHP, то его содержимое при запросе будет скачиваться (обрати внимание на переменную $file_type
, которая будет пустой в случае неизвестного расширения).
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image30.jpg)
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image31.jpg)
Последний файл — upload.php
тоже оказался не без багов: в нем есть возможность отправлять файлы не только с расширением из белого списка (.dat и .DAT), но и с пустым расширением.
Вайтлист расширений задается следующей строкой.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image32.jpg)
Теперь, если значение расширения не пустое, проводится проверка на наличие расширения в массиве, который получен из $allowExt
. В качестве разделителя используется запятая.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image33.jpg)
Но если расширение пустое, исполнение не дойдет до этого условия и проверка не выполнится. Однако для эксплуатации этот баг бесполезен.
А вот следующий случайно найденный баг этого скрипта уже стоит расценить как уязвимость: здесь отсутствует проверка на длину названия файла. Казалось бы, не очень серьезная проблема, но в начале программы запускается скрипт на Bash.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image34.jpg)
Он очищает директорию updownload
от ранее загруженных туда файлов, а в интерпретаторе Bash, который входит в BusyBox, стоит ограничение на длину названия файла в 256 символов. Получается, что скрипт не сможет удалить файлы, названия которых длиннее этого значения.
Так как у upload.php
нет никакой авторизации, любой пользователь может загрузить сколько угодно файлов с именем длиннее 256 символов, и это приведет к заполнению всей памяти устройства. Другими словами, Denial of Service.
Пример загрузки файла.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image35.jpg)
И получение списка файлов в директории /updownload/
через консоль Bash.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image36.jpg)
На этом мы можем завершить изучение скриптов на PHP и перейдем к самой большой части исследования — CGI-приложениям.
Приложения CGI на IP-камере отвечают чуть ли не за все действия в администраторской веб-панели, начиная с авторизации и заканчивая обновлением устройства.
Я разделю описание работы на тестирование «невооруженным глазом» (уязвимости, для нахождения которых не нужно реверсить исполняемые файлы) и собственно реверс этих самых бинарей.
При тестировании «невооруженным глазом» нашлись две уязвимости. Первая позволяет проводить атаки подделки межсайтовых запросов (то есть CSRF). Ее суть заключается в том, что можно применить социальную инженерию и заставить администратора перейти по вредоносной ссылке. Это дает возможность выполнить почти любую команду из админского интерфейса. Например, можно сделать вот такую ссылку:
/webparam?user&action=set¶m=add&id=tester&pass=cGFzc3dvcmQ=&authority=0&t=1552491782708
Она будет создавать пользователя tester с паролем password.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image37.jpg)
Когда я изучал трафик в Burp Suite, я долго не мог найти ответ сервера, где браузеру высылаются cookie с данными авторизации (username, auth и password). Оказалось, что искал зря: эти данные выставляются на стороне клиента через код на JavaScript в файле /inc/js/ui.js
.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image38.jpg)
То есть браузер сначала делает запрос на проверку логина и пароля и, если результат положительный, сохраняет значения логина, пароля и привилегий в соответствующие cookie. А дальше эти куки используются при отправке командных запросов, например при создании нового пользователя.
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image39.jpg)
Тут-то и появляется вторая уязвимость: даже если мы не отправим cookie-переменную password, сервер все равно успешно обработает наш запрос!
![](https://xakep.ru/wp-content/uploads/2019/11/249353/image40.jpg)
То есть достаточно знать логин админа (который по умолчанию — root), чтобы обойти авторизацию и совершать любые вызовы, доступные администратору в административной веб-консоли камеры! И это мы нашли, даже не изучая код приложения. Посмотрим, что же будет в самом коде.
Изучение бинарных приложений
Для изучения исполняемых файлов потребовались некоторые приготовления. А именно:
- установка статически скомпилированного отладчика GDB из публичных репозиториев на GitHub;
- установка карточки MicroSD с файловой системой VFAT (что позволяет получить дополнительное место).
Сам процесс исследования скомпилированных приложений выглядит так.
- Изучение приложения в IDA Pro.
- При необходимости — отладка приложения в GDB на самой камере через Telnet. Кстати, поскольку приложение многопоточное, пришлось каждый раз проверять нужный process id для взаимодействия с определенным потоком (поток создается до обработки запроса).
- Написание proof-of-concept для демонстрации уязвимости.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»