Встроенные устройства часто служат входной дверью при атаке на частную или корпоративную сеть. Скандально известная атака на компанию HackingTeam была реализована в точности таким же способом. Хотя подобные деяния могут делаться исходя из благих побуждений (см. также еще одну прекрасную статью), сам факт возникновения данных случаев наводит на мысль о необходимости правильной защиты встроенных устройств.
В этой статье внимание будет уделено главным образом тому, как начать анализ конкретной модели. Однако представленные техники и утилиты можно также использовать и для анализа других устройств. В частности, я покажу пошаговую инструкцию, в которой описывается:
- Как добраться до прошивки и использовать ее для получения информации.
- Как получить доступ к системе.
- Как установить на устройстве gdbserver.
Я не буду раскрывать «изощренные» уязвимости, но упомяну те из брешей, которые помогают в анализе устройства. В частности, расскажу об уязвимости, при помощи которой можно удаленно выполнять код в административном интерфейсе. Об этой проблеме уже сообщено разработчику (хронология событий указана в конце статьи).
Анализ устройства. Пошаговый подход
Далее я покажу различные шаги, позволяющие настроить рабочую среду для тестирования камеры. В моем случае первоначальная стадия ничем не отличается от любой другой процедуры, связанной с пентестом веб-приложения. В начале собиралась информация о камере из внешних источников (веб-сайт производителя, поисковая система, … ) или посредством сканирования внешних служб (в частности, административного интерфейса) при помощи сподручных инструментов (Burp Suite, nmap, …). Далее наступала стадия эксплуатации, по результатам которой к устройству получался доступ. Наконец, в последней стадии на камере устанавливаются утилиты для отладки/анализа.
Шаг 1: Сбор информации
При анализе устройства жизненно важно собрать как можно больше информации. В нашем случае задача облегчается за счет того, что компания Edimax предоставляет множество даташитов, мануалов, прошивку и набор утилит toolchain (+ файлы для сборки образа) для камеры (хотя, исходный код к некоторым интересным бинарным файлам был утерян).
Уже при исследовании прошивки можно узнать много интересного о внутреннем устройстве камеры. При помощи bindwalk извлекаем из прошивки структуру файловой системы:
$ binwalk -e IC3116W_v2.10.bin
DECIMAL HEX DESCRIPTION
——————————————————————————————————-
605 0x25D LZMA compressed data, properties: 0×88, dictionary size: 1048576 bytes, uncompressed size: 65535 bytes
10392 0×2898 LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 3735204 bytes
1245312 0×130080 Squashfs filesystem, little endian, version 4.0, compression: lzma, size: 4072088 bytes, 907 inodes, blocksize: 131072 bytes, created: Mon Feb 22 11:50:40 2038
По результатам отработки bindwalk выясняется, что разработчики используют файловую систему SquashFS. Для анализа данной файловой системы я воспользовался утилитой unsquashfs (с поддержкой LZMA):
$ unsquashfs -d filesystem 130080.squashf
На выходе получаем распакованную файловую систему, сохраненную в папке filesystem:
$ ls -a filesystem
. ... bin dev etc home init lib mnt proc sys test tmp usr var web www
После распаковки файловой системы приступаем к исследованию файлов. Например, нашлись некоторые интересные бинарники: telnetd, wget, ftp и многие другие. В процессе сканирования при помощи nmap (стандартный IP-адрес напечатан на задней стенке устройства) выяснилось, что демон telnet по умолчанию не запущен (но, тем не менее, на будущее следует держать эту информацию в голове).
$ nmap -sS -p0- —reason -v -T3 -Pn 192.168.2.3
[…]
Nmap scan report for 192.168.2.3
Host is up, received arp-response (0.00065s latency).
Not shown: 65534 closed ports
Reason: 65534 resets
PORT STATE SERVICE REASON
80/tcp open http syn-ack
554/tcp open rtsp syn-ack
MAC Address: 74:DA:38:34:AA:75 (Unknown)
[…]
Корневая директория веб-сервера находится в папке www. Исследуя данную папку, находим несколько интересных cgi файлов, доступ к которым доступен всем желающим без авторизации:
- /www/camera-cgi/public/anonymous.cgi
- /www/camera-cgi/public/getSysteminfo.cgi
- /www/camera-cgi/public/supportiPhoneAppVersion.cgi
В частности, при помощи файла anonymous.cgi и getSysteminfo.cgi можно получить множество сведений относительно настроек IP-камеры (внутренние IP-адреса, версию прошивки и т. д.).
Рисунок 1: Информация о камере, полученная после запуска скрипта getSysteminfo.cgi
Следующий шаг – автоматическое сканирование и ручное тестирование запущенных служб для того, чтобы выяснить внутренне устройство камеры. По результатам сканирования при помощи nmap (см. выше) выяснилось, что на порту 80 запущен веб-сервер, используемый для административного интерфейса. Стандартная учетная запись администратора: admin с паролем 1234 (обычно для удобства напечатана на задней стенке камеры).
Рисунок 2: Задняя стенка веб-камеры с напечатанной учетной записью
И здесь мы переходим ко второй стадии, связанной с получением доступа к системе.
Шаг 2: Получение доступа к системе
После автоматического сканирования и ручного тестирования веб-интерфейса выяснилось, что Системный Журнал (System Log) дает возможность удаленного выполнения кода. Используя путь к telnetd, можно запустить службу telnet следующим образом:
Рисунок 3: Методика запуска telnetd через SystemLog
Теперь мы можем подключиться к камере через telnet:
$ telnet 192.168.2.3
Trying 192.168.2.3…
Connected to 192.168.2.3.
Escape character is ‘^]’.
IC-34AA75 login: admin
Password:
RLX Linux version 2.0
_ _ _
| | | ||_|
_ _ | | _ _ | | _ ____ _ _ _ _
| |/ || |\ \/ / | || | _ \| | | |\ \/ /
| |_/ | |/ \ | || | | | | |_| |/ \
|_| |_|\_/\_/ |_||_|_| |_|\____|\_/\_/
For further information check:
http://processor.realtek.com/
BusyBox v1.13.4 (2015-02-25 18:14:22 CST) built-in shell (ash)
Enter ‘help’ for a list of built-in commands.
# cat /etc/passwd
admin:$1$yAn92Ld/$u5nHFH9nLds0naDaLuK1d/:0:0:System Administrator,,,:/:/bin/sh
Учетная запись для доступа через telnet та же самая, что и для административного интерфейса (пользователь: admin, пароль: 1234). После анализа файла /etc/passwd выясняется, что в системе только один пользователь: admin (c uid 0 и gid 0), следовательно, мы имеем полный доступ к системе.
Следует отметить, что есть возможность получить shell-доступ через UART-порт. Данный порт указан на плате на рисунке ниже (изначально соответствующие пины были удалены и запаяны).
Рисунок 4: Плата IP-камеры с отмеченным UART-портом
Для работы с UART-портом потребуется отдельное устройство, например, JTAGulator. Теперь, когда мы получили полный доступ к системе, то можем приступить к установке утилит, помогающих при анализе.
Шаг 3: Настройка рабочей среды
Существует несколько утилит, помогающих анализировать на камере запущенные процессы. Задача осложняется тем, что на камере отсутствует отладчик и компилятор. Наша задача – запустить на камере gdbserver, а локально – gdb.
Использование gdbserver на камере (вместо gdb) дает несколько преимуществ. Во-первых, размер бинарного файла gdbserver намного меньше, чем gdb. Дисковое пространство на встроенных устройствах часто может быть ограниченно и зачастую gdbserver – единственный выбор. Во-вторых, gdbserver имеет меньше зависимостей, чем gdb, и, следовательно, облегчается кросс-компиляция. Конечно, при использовании gdbserver есть и свои минусы. Например, могут возникнуть сложности в случае, если размеры регистров хоста (где установлен gdb), и целевой системы (где установлен gdbserver) различаются. Именно поэтому я запускаю gdb на машине с архитектурой x86.
Чтобы облегчить установку бинарных файлов на камеру, желательно найти способ быстрой транспортировки туда и обратно. Для закачки файлов на камеру можно использовать утилиту wget (хотя файловая система filesystem работает в режиме «только чтение», флеш-память смонтирована в папку /var, и мы можем записать туда). Чтобы скачать файла с камеры, подойдет утилита lighttpd (веб-сервер камеры). Посредством запуска еще одного экземпляра данного сервера с корневой директорией “/” мы можем скачать с камеры все файлы.
После настройки системы транспортировки файлов между камерой и хостом настало время кросс-компиляции gdbserver’а. Вначале выясним, какой процессор используется на камере:
# cat /proc/cpuinfo
system type : RTL819xD
processor : 0
cpu model : 56322
BogoMIPS : 658.63
tlb_entries : 32
mips16 implemented : yes
Как видно из листинга выше, на камере используется система RTL819xD на базе архитектуры MIPS. Вначале я попробовал использовать стандартный кросс-компилятор под эту архитектуру. На ресурсе Aboriginal Linux, помимо различных кросс-компиляторов, присутствуют shell-скрипты, позволяющие настроить полноценную систему сборки под конкретную архитектуру (на базе эмулятора qemu).
Однако в Realtek CPU используется модифицированный набор инструкций, и лишь малое количество обычных бинарных файлов, скомпилированных для архитектуры MIPS, может запуститься в этой системе. Хотя, как упоминалось ранее, компания Edimax предоставляет набор утилит toolchain, используя которые в операционной системе CentOS 7.3, я смог настроить среду для сборки. Инструкции по настройке данной среды даны в файле pdf, который идет в комплекте с toolchain. Суть настройки сводится к следующим шагам:
- Шаг 1 1: cd TARGET_DIR
- Шаг 2: bzip2 -cd rsdk-{VERSION}-{LIBRARY}-{PLATFORM}.tar.bz2 | tar xvf –
- Шаг 3: ln -s rsdk-{VERSION}/{PLATFORM}/{LIBRARY} rsdk
- Шаг 4: export PATH=TARGET_DIR/rsdk/bin:$PATH
Теперь в системе CentOS я могу скомпилировать бинарные файлы для камеры. Для кросс-компиляции gdbserver используем следующий набор команд:
$ cd gdbserver_src
$ ./configure —host=mips-linux CC=rsdk-linux-gcc
$ ./make CC=rsdk-linux-gcc AS=rsdk-linux-as LD=rsdk-linux-ld
При помощи переменных окружения CC, AS и LD компилятор, ассемблер и загрузчик могут быть настроены для компиляции и загрузки. В конце концов, мы получаем бинарный файл gdbserver, который подходит для запуска на камере.
Соответствующий бинарный файл gdb можно получить схожим образом. Но здесь задача облегчается тем, что уже есть скомпилированные версия для систем x86 (которые могут взаимодействовать с gdbserver в MIPS-системах). Если же вы хотите скомпилировать бинарный файл с нуля, то можно использовать различные параметры в процессе компиляции.
$ cd gdb_src
$ ./configure —target=mips-linux
$ ./make
Во время сборки мы должны указать целевую систему (то есть ту систему, где будет запускаться gdbserver). Я протестировал различные версии gdb/gdbserver и выяснил, что в случае с моей камерой работает версия gdb-6.8.
В конце я бы хотел показать, как можно использовать связку gdb/gdbserver для анализа процессов, запущенных на камере. Но вначале скопируем бинарный файл gdbserver на камеру в директорию /var и выставим права на запуск при помощи chmod. Теперь, чтобы подключиться к процессу, используем следующую команду:
# /var/gdbserver ip:port —attach pid
Здесь в качестве IP-адреса выступает адрес хоста, где запущен gdb. Порт, указанный в команде, будет открыт на целевой системе. PID – идентификатор процесса, к которому мы хотим подключиться. Естественно, мы также можем запустить новый процесс на камере (без подключения к существующему) посредством указания пути к исполняемому файлу вместо аргумента –attach.
В качестве примера подцепляемся к запущенному процессу /bin/ipcam:
# /var/gdbserver 192.168.2.10:1234 —attach 9266
Attached; pid = 9266
Listening on port 1234
После запуска команды gdbserver ожидает входящие соединения на определенному порту (в данном случае -1234). На хосте мы запускаем исполняемый файл gdb и подсоединяемся к целевой системе при помощи следующей команды:
$ rsdk-mips-gdb -q
(gdb) target remote 192.168.2.3:1234
Remote debugging using 192.168.2.3:1234
[New Thread 9266]
0x2ab6b89c in ?? ()
(gdb)
Однако, как видно из листинга выше, gdb не находится в контексте функции или, другими словами, «не понимает», где находится. Подобное происходит потому, что gdb должен загрузить таблицу символов для бинарного файла, который будет отлаживаться на целевом сервере. Таким образом, необходимо использовать файловую команду (в gdb) внутри бинарного файла после локальной загрузки таблицы символов. Более того, для отладки библиотечных вызовов должна быть сохранена локальная копия файловой система камеры, и gdb должен запускаться из корневой директории (что гарантирует нахождение библиотек в системе x86).
$ cd cam_root_dir
$ rsdk-mips-gdb -q
(gdb) file cam_root_dir/bin/ipcam
Reading symbols from cam_root_dir/bin/ipcam…(no debugging symbols found)…done.
(gdb) target remote 192.168.2.3:1234
Remote debugging using 192.168.2.3:1234
[New Thread 9266]
0x2aaa8a40 in _start () from cam_root_dir/lib/ld-uClibc.so.0
(gdb)
Теперь вы можете использовать gdb, как будто отладчик запущен прямо на камере (доступна установка точек останова, анализ регистров и т. д.). Таким образом, у нас есть рабочая среда для анализа процессов, запущенных на камере.
Как было упомянуто в начале статьи, о найденных уязвимостях было сообщено производителю.
Чтобы предотвратить утечку информации через файлы anonymous.cgi, getSysteminfo.cgi и supportiPhoneAppVersion.cgi, необходимо ограничить доступ другими средствами (например, при помощи отдельного фаервола). Конечно, вы также можете получить доступ к системе, как описывалось выше, и переконфигурировать камеру.
Кроме того, необходимо ограничить доступ к той области, откуда запускается удаленный код. Для начала следует изменить стандартную учетную запись камеры (но сменить учетную запись нужно в любом случае). Кроме того, в зависимости от ситуации, в которой используется камера, возможно, следует полностью заблокировать доступ к веб-интерфейсу через интернет.
Редакция: Труш Борис Викторович
Если Вам понравилась статья, то нажмите кнопку социальной сети — Поделитесь с друзьями