Jump to content
Sign in to follow this  
mr.save

Вскрытая камера. Как искать уязвимости в «умных» гаджетах на примере популярной IP-камеры

Recommended Posts

За последние несколько лет все чаще обсуждается проблема безопасности домашних гаджетов. На слуху атаки ботнетов типа Mirai, которые поражают миллионы устройств и вредят как домашним пользователям, так и бизнесу. Этичные хакеры тоже исследуют все больше девайсов — обычно с неутешительными выводами. В этой статье я покажу все этапы проверки хардверной безопасности на примере распространенной в России модели IP-камеры. Спойлер: уязвимостей будет много.

Итак, моей задачей было выбрать такого производителя, который, с одной стороны, давно присутствует на российском рынке, с другой — еще не привлекал внимание специалистов по безопасности. Мой выбор пал на корейскую фирму Microdigital, которая производит IP-камеры.

Сайт компании обещает нам широкий ассортимент: «свыше 30 моделей регистраторов, свыше 150 моделей видеокамер». Отлично!

211503260_image1(1).thumb.jpg.197307ca1e5f27df8e066abe09f57fad.jpg

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

В первую очередь меня заинтересовали устройства серии N, они достаточно продвинутые, но при этом пока что не стали объектом тестирования кого-то из исследователей. Пора исправить это! Я выбрал модель MDC-N4090W, которая предназначена для использования внутри помещений. Подробную информацию об устройстве можно почерпнуть на сайте производителя.

575625817_image2(1).jpg.8c03547f140d1fb3b27626e17047f494.jpg

Изучение камеры

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

image3.thumb.jpg.6ea451c7fbbcc6915a0c9915dc564b28.jpg

Открываем PDF, полученный на сайте Microdigital, и узнаем, что у камеры есть веб-интерфейс с пользователями root (пароль root) и anonymous.

image4.jpg.0aa1e02190354d9beb775bd6fc2f0fca.jpg

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

image5.thumb.jpg.e26c5c31988db17517bc59548f05a5b6.jpg

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

 

Подготовка устройства к тестированию

Приступим к изучению аппаратной составляющей. Для этого разбираем устройство (ничего сложного, четыре винта по периметру) и получаем печатную плату.

image6.thumb.jpg.a442a57e7a40e99649c0e116d8c21bbf.jpg

image7.thumb.jpg.362d322210095d6b236ba8d9edea7b3f.jpg

Также видим следующее:

  • память S34ML01G100TF100;
  • чип DM368ZCE;
  • интерфейсы: четыре пина UART, USB, MicroSD, Ethernet.

Пины, отмеченные как BLE, я не рассматриваю, так как это, скорее всего, контакты для подключения модуля Bluetooth. Нас это в данный момент не интересует.

Модуль S34ML01G100TF100 — энергонезависимая NAND-память в корпусе TSOP-48. Datasheet легко гуглится. Из него узнаем подробнее о типе корпуса (NAND08) и размере хранилища — 128 Мбайт.

Для дальнейшей работы потребуется сделать бэкап данных, чтобы в случае «окирпичивания» камеры можно было вернуть ее в изначальное состояние. Для этого идеально подходит программатор ProMan TL86 или TL866 с переходником NAND08 → DIP48.

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

image8.jpg.b97ddfaa9cf15aeed7b8c5d4cdb13b6e.jpg

Для чипа DM368ZCE тоже не составило проблем нагуглить документацию (PDF). Оказывается, архитектура чипа — ARM. К тому же из документации можно достать его распиновку, но нам она не потребуется.

image9.thumb.jpg.e81ff8c56eb02f225b11816d72036997.jpg

Пройдемся по интерфейсам. Из документации очевидно, что USB и MicroSD нужны в основном для того, чтобы подключать к устройству внешние носители и использовать их в качестве хранилища. Для полноты картины можем подключить к устройству USB-фаззер facedancer21 и, используя утилиту umap2scan, получить список поддерживаемых устройств.

image10.thumb.jpg.6c73db260fcc3a0fccba7eca678d835a.jpg

image11.jpg.e31bafef3be3be96e8af705258e17a6c.jpg

К сожалению, камера не поддерживает ни одно из известных нам устройств.

Как насчет UART? Тут предстоит определить, за что отвечает каждый пин и какова скорость передачи данных. Для этого воспользуемся логическим анализатором Saleae Logic. Для удобства я подключился через проводок, который соединяет плату устройства и инфракрасные лампочки.

image12.thumb.jpg.8de010315df624c96c67d626b9e9dbff.jpg

Пронумеруем пины для удобства.

image13.thumb.jpg.98cceb67bb8c17fdfd7ad8aea46bc5db.jpg

Прежде чем включать логический анализатор, подключаем заземление к пину GND интерфейса для подключения BLE.

image14.thumb.jpg.06e25d887363e4d515a7b5ea6bdaef09.jpg

Теперь включаем логический анализатор и само устройство и смотрим, что из этого выйдет.

image15.thumb.jpg.4a25c89e18fcbd59ff6687f2af124c8e.jpg

После включения устройства на пине номер 3 (в программе отсчет идет с нуля и пин нумерован как 2) передаются бинарные данные. Этот пин интерфейса UART отвечает за передачу данных (TX). Просмотрев длину одного бита, получаем текущую скорость передачи — 115 200 бит/с. При корректных настройках мы даже можем разглядеть часть текста.

image16.thumb.jpg.6fdc19eb9dd00acd1a21a7771da761c8.jpg

У пина под номером 1 постоянное напряжение 3 В — следовательно, он предназначен для питания. Пин номер 4 связан с пином GND интерфейса для подключения модуля BLE. Значит, этот пин тоже «земля». И остается последний пин под номером 2, он отвечает за прием байтов (RX). Теперь у нас есть вся информация для общения с камерой по UART. Для подключения я воспользуюсь Arduino UNO в режиме переходника TTL.

image17.thumb.jpg.39550f7ce820f32c8152cd02f37ad122.jpg

Начинаем мониторить порт UART и получаем следующее.

image18.thumb.jpg.f0c43ac66537e290f48500006e642169.jpg

При старте устройства первым делом подгружается загрузчик системы U-Boot. К сожалению, на уровне загрузки пин TX отключен в настройках камеры, поэтому мы можем наблюдать только отладочный вывод. Через какое-то время подгружается основная система, позволяющая ввести логин и пароль для доступа в администраторскую консоль. Пара root/root (аналогичная той, что используется для веб-админки и указана в документации) прекрасно подошла.

image19.jpg.ce625231f6fb1250044b67c462848f4c.jpg

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

Для перехвата трафика я буду пользоваться устройством Lan Tap Pro.

image20.thumb.jpg.e0023f2b1ee2475a41466c1988cf9774.jpg

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

 

Сетевая часть

Просканируем порты утилитой Nmap и получим список открытых портов.

image21.jpg.c13608703b58679e0098a256eb349118.jpg

Пройдемся вкратце по доступным нам сервисам.

 

FTP

При подключении сервис запрашивает логин и пароль. Анонимный вход отключен. Но и тут подошел вариант root/root!

image22.thumb.jpg.3bd0b40f0ecc72e36084d25c099377a7.jpg

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

 

Telnet

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

image23.jpg.1c2f8803396c0de1c11f14cf5c95b691.jpg

RTSP

Для подключения к RTSP опять же нужно авторизоваться как root/root. Ссылка для подключения принимает вид rtsp://root:root@192.168.1.151:554/Primary.

image24.thumb.jpg.68bca17791fd230858b869a34dc31e64.jpg

Веб

Изучив устройство веб-сервера камеры, я составил вот такую схему.

image25.jpg.9f62352cd287dafb6d7ace5b041b5679.jpg

На сервере находятся скрипты на PHP и CGI-приложения, которые общаются с исполняемыми файлами из директории /usr/local/ipsca/ (преимущественно общение идет с MainProc). Для хранения всех настроек используется база данных SQLite 3.

С нее-то мы и начнем искать уязвимости. База данных хранится в /usr/local/ipsca/mipsca.db. В ней лежит все — от логов системы до настроек автоматической загрузки записей камеры на удаленный сервер. Структура базы данных видна на скрине ниже.

image26.thumb.jpg.0e8679e8447d59e5d8e16b429576c1bd.jpg

Мое внимание привлекла таблица User. Она отвечает за работу с данными пользователей: логин, пароль, привилегии.

image27.jpg.b1c604dc65c53cb2346fd8d9abf9aa8a.jpg

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

Переходим к скриптам на PHP. В веб-директории /root/httpd/htdocs/Web лежит три скрипта: download.php, login.php, upload.php.

image28.jpg.b4323d2f737e4ff8d23974547ccc67d6.jpg

Файл login.php не особенно интересен, так как PHP тут используется только для настройки компонента ActiveX, нужного для браузерных дополнений, которые стримят видео на сайте.

image29.jpg.e05e71f09dcff1a91296282ac8590617.jpg

Файл download.php принимает на вход название файла для скачивания, проверяет его расширение и, если такой файл найдется в папке updownload, отправляет в ответ его содержимое.

В скрипте нет проверки названия файла, так что если кто-то вдруг решит положить в этот каталог исполняемый скрипт на PHP, то его содержимое при запросе будет скачиваться (обрати внимание на переменную $file_type, которая будет пустой в случае неизвестного расширения).

image30.thumb.jpg.86c2cbbcb3f9b6bd9a29ae68e6625d4d.jpg

image31.thumb.jpg.9721304c015187fcbe88174cfc4e32ae.jpg

Последний файл — upload.php тоже оказался не без багов: в нем есть возможность отправлять файлы не только с расширением из белого списка (.dat и .DAT), но и с пустым расширением.

Вайтлист расширений задается следующей строкой.

image32.jpg.1af820712425b53c2de5e68b21cfc444.jpg

Теперь, если значение расширения не пустое, проводится проверка на наличие расширения в массиве, который получен из $allowExt. В качестве разделителя используется запятая.

image33.jpg.5fd33be7570f8286ca3b549708578281.jpg

Но если расширение пустое, исполнение не дойдет до этого условия и проверка не выполнится. Однако для эксплуатации этот баг бесполезен.

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

image34.jpg.85dce55e92a583998488b0653779e3d3.jpg

Он очищает директорию updownload от ранее загруженных туда файлов, а в интерпретаторе Bash, который входит в BusyBox, стоит ограничение на длину названия файла в 256 символов. Получается, что скрипт не сможет удалить файлы, названия которых длиннее этого значения.

Так как у upload.php нет никакой авторизации, любой пользователь может загрузить сколько угодно файлов с именем длиннее 256 символов, и это приведет к заполнению всей памяти устройства. Другими словами, Denial of Service.

Пример загрузки файла.

image35.thumb.jpg.930eedf383bb444075fb5fb2755844af.jpg

И получение списка файлов в директории /updownload/ через консоль Bash.

image36.jpg.5f5d753b8d5d2ba19d68a82f0c3cc3c7.jpg

На этом мы можем завершить изучение скриптов на PHP и перейдем к самой большой части исследования — CGI-приложениям.

Приложения CGI на IP-камере отвечают чуть ли не за все действия в администраторской веб-панели, начиная с авторизации и заканчивая обновлением устройства.

Я разделю описание работы на тестирование «невооруженным глазом» (уязвимости, для нахождения которых не нужно реверсить исполняемые файлы) и собственно реверс этих самых бинарей.

При тестировании «невооруженным глазом» нашлись две уязвимости. Первая позволяет проводить атаки подделки межсайтовых запросов (то есть CSRF). Ее суть заключается в том, что можно применить социальную инженерию и заставить администратора перейти по вредоносной ссылке. Это дает возможность выполнить почти любую команду из админского интерфейса. Например, можно сделать вот такую ссылку:

/webparam?user&action=set&param=add&id=tester&pass=cGFzc3dvcmQ=&authority=0&t=1552491782708

Она будет создавать пользователя tester с паролем password.

image37.jpg.a098f2e21e978ad5667a9dc08946aad2.jpg

Когда я изучал трафик в Burp Suite, я долго не мог найти ответ сервера, где браузеру высылаются cookie с данными авторизации (username, auth и password). Оказалось, что искал зря: эти данные выставляются на стороне клиента через код на JavaScript в файле /inc/js/ui.js.

image38.jpg.820669218dbb9b7c2a650355585a22d5.jpg

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

image39.jpg.e468c79694cb950fbc81da5b9f7d7c0d.jpg

Тут-то и появляется вторая уязвимость: даже если мы не отправим cookie-переменную password, сервер все равно успешно обработает наш запрос!

image40.jpg.4122bdba6bbfd16ea5c3767e53a9cb89.jpg

То есть достаточно знать логин админа (который по умолчанию — root), чтобы обойти авторизацию и совершать любые вызовы, доступные администратору в административной веб-консоли камеры! И это мы нашли, даже не изучая код приложения. Посмотрим, что же будет в самом коде.

 

Изучение бинарных приложений

Для изучения исполняемых файлов потребовались некоторые приготовления. А именно:

  • установка статически скомпилированного отладчика GDB из публичных репозиториев на GitHub;
  • установка карточки MicroSD с файловой системой VFAT (что позволяет получить дополнительное место).

Сам процесс исследования скомпилированных приложений выглядит так.

  • Изучение приложения в IDA Pro.
  • При необходимости — отладка приложения в GDB на самой камере через Telnet. Кстати, поскольку приложение многопоточное, пришлось каждый раз проверять нужный process id для взаимодействия с определенным потоком (поток создается до обработки запроса).
  • Написание proof-of-concept для демонстрации уязвимости.

Почти все командные веб-запросы отправлялись по адресу /webparams. Изучив настройки httpd, которые хранятся в файле /usr/local/httpd/conf/httpd.conf, определяем, что все запросы на /webparam перенаправляются в исполняемый файл FCGI по пути /usr/local/httpd/fcgi/webparams.fcgi.

image41.jpg.3b1af92fcd5f2447ec5754ce87a09650.jpg

Это исполняемый файл для 32-битного ARM. На нем-то я и решил сконцентрироваться.

1235197219_image42(1).jpg.0ead48ca40ed52a1dffb0322b033e7f1.jpg

Произвольные команды FTP

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

image43.thumb.jpg.a1844ac1930b0874f7582ac34196d16a.jpg

Далее можно нажать на кнопку Test и проверить соединение. Будет вызвана функция по адресу 0xaeb0. Для удобства будем изучать псевдокод функции, полученный при помощи Hex-Rays Decompiler.

Создание подключения.

image44.jpg.da78a38f3b20ad6832ba85f204a58dc5.jpg

Авторизация на FTP-сервере.

image45.jpg.16f93e483f7e626047a22cc43340b51f.jpg

Смена текущей директории значением, переданным аргументом.

image46.jpg.a783161b75916f286a11f90a1bf2a9e1.jpg

Создание временного файла.

image47.thumb.jpg.9c086550f1ebd8adc8cc45f27ca2570b.jpg

Проблема безопасности обнаружилась уже на третьем пункте. Функция ftp_CWD, находящаяся по сдвигу 0xA9F0, не проверяет наличие в строке-пути некорректных символов, таких как перенос строки.

image48.jpg.f3713e4fbc53dd9306412834e33c24dc.jpg

Это позволяет отправлять произвольные команды FTP — достаточно добавить байты \r\n в значение директории для загрузки файлов. Значит, мы нашли SSRF.

Например, можно сделать запрос к FTP-серверу камеры и добавить к нему команду, которая создает директорию /tmp/123 (GET-переменная uploadpath как раз отвечает за путь до требуемой директории).

image49.jpg.36475e91424794a96a427d4ce29c98ee.jpg

Переходим в /tmp/ на камере и видим созданную папку 123.

image50.jpg.b0a37d3f6e9c47b34d0cb81689b9146f.jpg

Path Traversal и проверка наличия файлов

Следующая интересующая нас возможность веб-сервера — синхронизации часов по протоколу NTP.

image51.thumb.jpg.a64fcec1e0ad4a6060ee7ec730db20b5.jpg

За изменение параметров отвечает функция по сдвигу 0x12564. Не будем вдаваться детально в принцип ее работы, обратим лишь внимание на переменную TZ (Time Zone).

Первые 32 байта GET-параметра TZ заносятся в переменную get_TZ_32b.

image52.jpg.5f8a07dd14cdf76c39bdb6bc01ae7833.jpg

Значение конкатенируется с путем до директории, где хранятся настройки временных зон, и проверяется наличие такой директории (или файла) в файловой системе устройства.

image53.jpg.85e055a48bc88f887fa7d71ba63a0c8e.jpg

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

image54.jpg.b19c23f35c3955f69fbfdaaa887eaff9.jpg

Если объединить все три пункта, то получится, что мы можем не только манипулировать полным адресом директории (Path Traversal), но и определять по ответу от сервера наличие файла в файловой системе. Чтобы удостовериться в этом, отправляем запрос, который проверит, существует ли файл /etc/passwd.

image55.jpg.8f63672a36219c7ac2dd6ed2e99c81eb.jpg

И посмотрим, что будет, если файла нет.

image56.jpg.d89afb270762ab422d0bb566b3e6b6de.jpg

SQL-инъекция

Переходим к более серьезным уязвимостям. Конфиги камеры хранятся в базе SQLite 3, и почти все действия на веб-сервере приводят к взаимодействию с ней. Так вот, оказалось, что почти все запросы к базе данных со строковыми параметрами могут проходить с некорректно форматированным вводом. А это, как ты мог догадаться, SQL injection! Для примера разберем одну из уязвимых форм — форму редактирования настроек DNS.

image57.thumb.jpg.118cbbebce1f56e5ba1fc9a0a715a0b4.jpg

При редактировании этих параметров отправляются два запроса на сервер — запрос на модификацию информации и запрос на получение текущих настроек.

Пример запроса на модификацию информации.

image58.jpg.7d1a0f949a9143dcaee0ffead3c25651.jpg

За обработку такого запроса отвечает функция по сдвигу 0x18374. В начале идет считывание GET-параметров запроса (до 32 байт каждый) и проверка того, заполнены ли они.

image59.jpg.fc853cf006fa182a195162be939d9d2f.jpg

Далее — вызов функции strip, которая убирает символы «пробел» и «табуляция» в начале и в конце строк.

image60.jpg.52d2fea00806b680d290a5234e415ca8.jpg

Теперь полученные строки отправляются в функцию, которая делает SQL-запрос Update к базе данных SQLite 3.

image61.thumb.jpg.9363c19796d6b461dbbfd52c7957aee0.jpg

Проблема в том, что при передаче строк используется не %q (безопасный вариант), а %s, в связи с чем мы можем выйти за пределы строки и добавить свои SQL-инструкции в запрос (кстати, если отправляется целочисленный параметр, то лучше всего использовать %d).

Ниже — пример эксплуатации.

image62.jpg.5c44605bb740e1f70d58d0c20bfeb26a.jpg

Во время обработки этого запроса создается следующая команда SQL.

Update Network set DDNSUsage=1, DDNSHostname='', DDNSName=(select/*', DDNSName='*/Password from/*', DDNSUserName='*/User limit 1) -- ', DDNSPassword='***'

Этот запрос запишет пароль открытым текстом в поле DDNSName первого аккаунта из таблицы User. Остается запросить текущие настройки DDNS.

image63.jpg.1e0a1b2874fd1de82fc5a08def4d6c65.jpg

В результате мы получили значение пароля первого пользователя из таблицы User — в нашем случае это root/root. Если учесть, что до этого мы нашли способ обхода авторизации, получается, пароль админа может узнать любой неавторизованный пользователь.

Аналогичную проблему можно наблюдать еще у 25 различных GET-параметров, разбросанных по всему веб-серверу (часть параметров требуется предварительно кодировать в Base64).

 

Переполнение стека

Когда я перебирал параметры, подверженные атакам типа SQL injection, мое внимание привлекла функция, которая обрабатывает переменную action, расположенную по смещению 0x155D0. Начало псевдокода функции — на скриншоте.

image64.thumb.jpg.48c73f3afe8ab74c483498654fba5bc9.jpg

На 78-й строке вызывается функция GET_val. Она в качестве аргумента принимает строку — название GET-переменной и возвращает строку — значение этой переменной.

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

Первый аргумент функции был объявлен на 53-й строке.

image65.jpg.192f6e120ca8484f648f8ad133d27aee.jpg

Для этой строки выделяется четыре байта, а потом в первую ячейку помещается нулевой байт, обозначающий ее окончание.

image66.jpg.6754498e41f3270ce780b3259f9dd0e4.jpg

Выходит, что для переполнения стека потребуется в аргументы функции strcat отправить две строки. Тогда длина второй строки будет больше трех байт (четвертый байт нулевой и выставляется автоматически).

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

image67.jpg.8bd48acc6cf1b898ff3bdf80e1781a4d.jpg

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

Также проверим, включена ли в системе технология рандомизации адресного пространства.

image68.jpg.ff88d8256545b97646586be54cbb6381.jpg

Флаг 1 означает, что адрес стека будет случайным при каждом запуске. Но изначально второй аргумент функции strcat (то есть аргумент GET-переменной action) записывается в кучу, а значит, мы можем им воспользоваться.

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

Удостовериться в этом можно, отправив следующий запрос.

image69.jpg.de376a4fbf1840195009b66621c4ed2f.jpg

При отладке процесса исполняемого файла webparam.fcgi получаем ошибку программы, которая пытается перейти по адресу BBBB.

image70.jpg.3492bb80df84e3bd8cf95a6348037bb7.jpg

Теперь остается дописать исполняемый код (шелл-код) после адреса возврата и перезаписать адрес возврата на адрес нашего вредоносного кода, который хранится на куче. В примере используется исполняемый код, который открывает порт 10240 и дает доступ в командную оболочку без авторизации (Bind Shell).

image71.jpg.18d80f85376b9e53e099e5d39821d25e.jpg

Проверяем сетевую активность на устройстве.

image72.jpg.eff814fd51aa9023d3e5ac2b36fbca42.jpg

Процесс 1263 программы webparam.fcgi начал прослушивать порт 10240 на всех интерфейсах. Подключимся к нему через netcat.

image73.jpg.8be3c071cd58aea7a7e29c4f93148314.jpg

Нам доступен шелл с привилегиями пользователя nobody.

Аналогичная проблема переполнения буфера и у переменной params. Способ эксплуатации не сильно отличается от описанного, поэтому не будем на нем останавливаться.

 

Подмена файла прошивки

Одна из самых популярных проблем у устройств IoT — это отсутствие подписи у файла прошивки. Конечно же, она не обошла и эту камеру. Что это нам дает? Все просто: мы можем добавить свой код в прошивку устройства и таким образом заразить его, причем так, что восстановление будет возможно, только если имеется дамп памяти, а есть он (и необходимые навыки) далеко не у любого владельца.

Администраторам устройства доступен интерфейс для обновления прошивки (внизу страницы).

image74.thumb.jpg.3694e651e1abea96011b051358c69803.jpg

Тут самое время вспомнить про файл прошивки, который мы скачивали с официального сайта в самом начале статьи.

image75.jpg.d76a4328c73a7f524318c3f3c63eba49.jpg

Это .tar, в котором лежат файлы PackageInfo.txt и UpdatePackage_6400.0.8.5.bin. Второй, в свою очередь, оказался архивом.

image76.jpg.747cc70e770ef90ad2db81a578a953de.jpg

После распаковки нам стала доступна следующая файловая иерархия.

image77.thumb.jpg.ba11c41a10dfa6cbfbbc36c33f89d528.jpg

В директориях хранятся все те же файлы, что и в файловой системе камеры. То есть мы можем подменить один из них, упаковать прошивку и отправить в качестве обновления. Но нужно еще заглянуть в файл PackageInfo.txt, доступный после первого разархивирования.

image78.thumb.jpg.ec14ba8e2087f69d1593edd48685a8eb.jpg

На восьмой строке указывается контрольная сумма файла .bin. То есть это поле тоже потребуется отредактировать при отправке кастомной прошивки, иначе камера посчитает файл поврежденным и система обновлений проигнорирует его. Эту уязвимость можно отнести к типу RCE — удаленное исполнение произвольных системных команд.

 

Повышение привилегий

Напоследок — еще одна уязвимость того же типа, но уже с повышением привилегий до root! Если вставить в камеру карточку MicroSD, то из веб-интерфейса можно удалять файлы с нее.

image79.thumb.jpg.b60a95486595798444e8523ae53d7c89.jpg

При удалении файла браузер отправляет по HTTP вот такой запрос.

image80.jpg.2b63674b64e4e1e47798b37d29045bab.jpg

За обработку запроса на стороне сервера отвечает все то же приложение webparam.fcgi, но в данном случае оно передает его в другую программу — MainProc. Это тоже бинарное приложение.

Изучив MainProc, я определил, что GET-переменная filename объединяется со строкой и передается в функцию system без какой-либо фильтрации. А это означает, что можно исполнять произвольный код от имени пользователя, который запустил MainProc, то есть root.

image81.jpg.60c4ffcebebda991b39ff2a483e5b13b.jpg

Proof-of-concept: создаем файл /tmp/test.txt со строкой hacking.

image82.jpg.9e6121cb25f59db6b3fdf2803305eca3.jpg

image83.jpg.5a7aff572dc88a817fa00bd74940ae85.jpg

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

 

Подводим итоги

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

Важный момент в том, что файл прошивки, предоставленный производителем на сайте, общий для всех шести IP-камер серии N. И вероятнее всего, часть найденных уязвимостей присутствуют и в других устройствах Microdigital, которых, как говорилось в начале статьи, «свыше 150 моделей»!

Также стоит упомянуть, что на конференции Positive Hack Days 8 был конкурс на взлом IP-камер — CAMBreaker. Среди подопытных числилась и эта модель. Одним из призеров конкурса был Иван Анисеня, который, как оказалось, еще в прошлом году нашел уязвимость внедрения произвольных SQL-запросов и с ее помощью обошел авторизацию на этой камере.

Остается животрепещущий вопрос: как защитить периметр от злоумышленников, если в нем есть подобная камера? Для обеспечения безопасности нужно:

  • установить камеру в физически недоступном для злоумышленника месте;
  • внимательно изучить документацию;
  • отключить невостребованные сервисы, например FTP;
  • сменить все пароли и, желательно, имена пользователей устройства;
  • закрыть на стороне шлюза (чаще всего в роли шлюза выступает роутер) port-forwarding до IP-камеры.

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

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...