
Newbie's approach to firmware hacking
Этот документ — мой личный опыт как новичка в реверс-инжиниринге и эксплуатации прошивок.

Для демонстрации мы проанализируем и воспроизведем CVE-2023-27216.
Для эксплуатации прошивок необходимо выполнить следующие шаги:
gdbserver статически для отладки.Обычно бинарный файл прошивки содержит загрузчик (uBoot), файл ядра, заголовок ядра для загрузчика (uImage), сжатую файловую систему (как правило, в формате SquashFS), таблицу CRC/MD5 (для проверки целостности файла) и другие вспомогательные файлы.
Сначала найдите способ анализа прошивки, проведите небольшое исследование, нашел несколько ресурсов:

Извлечение прошивки с помощью binwalk: binwalk -Me DSL-3782_A1_EU_1.01_07282016.bin

Получена извлеченная папка squashfs-root и несколько странных файлов.

Бонус: Если вы не видите папку squashfs-root, используйте unsquashfs на любых файлах .squashfs, которые вы видите. Они как zip-файлы 😅.
Проверьте архитектуру прошивки и порядок байтов (endianness). Это можно сделать, проверив некоторые бинарные файлы, извлеченные из прошивки. Проверьте архитектуру и прошивку: file <binary>

Здесь мы почти можем подтвердить, что прошивка работает на архитектуре MIPS 32-bit MSB. Причина «почти» в том, что некоторые прошивки могут работать на другой архитектуре с MIPS Compatible, такой как Lexra.
Проверяем папку squashfs-root и находим несколько интересных файлов:
usr/etc/init.d/rcS => Это скрипт, который выполняется при загрузке прошивкиusr/etc/passwd => Это файл, содержащий информацию о пользователяхuserfs/romfile.cfg => Там есть учетные данные admin:adminПроверяем файл rcS и находим интересный код:
echo "admin:$1$$iC.dUsGpxNNJGeOm1dFio/:0:0:root:/:/bin/sh" > /usr/etc/passwd
passwdBoa — это древний веб-сервер, в основном использовавшийся во встраиваемых устройствах, таких как маршрутизаторы, в 2000-х годах. Однако разработка boa server была прекращена еще в 2005 году! Несмотря на то, что сервер Boa мертв уже почти 20 лет, он живет и по сей день благодаря нашему вендору.

Рекомендую использовать ОС на основе Debian для процесса эмуляции, например Ubuntu или Kali. Существует еще одна ОС, ориентированная на взлом прошивок, под названием AttifyOS. В этом документе я использовал Kali Linux. Начнем с процесса эмуляции, для этого есть 2 инструмента:

Давайте рассмотрим, как использовать FAT для полной эмуляции прошивки. Сначала клонируем репозиторий с github на вашу машину Kali. И проходим процесс настройки. Также нужно изменить файл fat.config, иначе он не будет работать.
git clone https://github.com/attify/firmware-analysis-toolkit.git
cd firmware-analysis-toolkit
./setup.sh
vi fat.config # Modify to your sudo password.
Затем копируем бинарный файл прошивки (тот, который мы скачали с сайта производителя) в папку FAT на нашей машине Kali и запускаем его.
./fat.py DSL-3782_A1_EU_1.01_07282016.bin
Примечание: В процессе настройки FAT могут возникать ошибки. Может появиться сообщение об отсутствии libmagic.

Просто выполните
pip unistall python-magic
pip install python-magic
Это должно исправить проблему, затем снова запускаем команду сборки. Теперь всё должно работать отлично.

Нажмите Enter для запуска. Процесс эмуляции должен работать хорошо, и вы сможете перейти по адресу http://192.168.1.1 (на машине Kali), чтобы проверить, работает ли он.

Вы также можете войти в консоль, если у вас есть учетные данные. Здесь admin:admin.

Если вы решите выключить эмулированную прошивку, просто нажмите Ctrl+A X. Когда потребуется запустить снова, не запускайте fat.py снова, так как прошивка уже собрана в образ. Вам нужно только запустить уже сгенерированный скрипт.
cd firmadyne/scratch/<Image-ID>
./run.sh

Соберите gdbserver для целей отладки. Есть много способов собрать gdbserver. Вы также можете скачать статически собранный сервер. Есть репозиторий, в котором хранятся некоторые статические сборки. Однако я предпочитаю собирать gdbserver самостоятельно, так как те, что в репозитории github, довольно старые и могут иметь проблемы совместимости.
Обратитесь к этой записи в блоге для справки: https://sheran.sg/blog/cross-compile-gdb-for-mips/. Блог был опубликован 30 июля 2024 года, как раз перед этим проектом, так что всё работает отлично.
Примечание: В блоге сборка для MIPS x32 LSB, но нам нужен MIPS x32 MSB. Нужно изменить mipsel-linux-gnu на mips-linux-gnu.
Нам нужно установить цепочку инструментов для MIPS. К счастью, в пакетах Debian она уже есть.
**apt update && apt upgrade -y
apt install -y build-essential m4 gcc-mips-linux-gnu g++-mips-linux-gnu**
Чтобы собрать gdbserver для MIPS, нужно собрать и установить несколько пакетов. Вот откуда я беру исходники.
Получение исходников
wget https://sourceware.org/pub/gdb/releases/gdb-15.1.tar.xz
wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz
wget https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.xz
Сборка библиотек с помощью toolchain Крайне важно иметь права root при сборке этих библиотек. Сначала нужно собрать GMP, так как он требуется для сборки MPFR.
tar xvf gmp-6.3.0.tar.xz && cd gmp-6.3.0
./configure --host=mips-linux-gnu
make -j$((`nproc`+1))
make install
cd ..
Затем собираем MPFR:
tar xvf mpfr-4.2.1.tar.xz && cd mpfr-4.2.1
./configure --host=mipsel-linux-gnu --with-gmp-build=<YOUR-FOLDER>/gmp-6.3.0
make -j$((`nproc`+1))
make install
cd ..
Теперь мы можем наконец собрать gdbserver:
tar xvf gdb-15.1.tar.xz && cd gdb-15.1
./configure --host=mipsel-linux-gnu --with-gmp-lib=/usr/local/lib --with-mpfr-lib=/usr/local/lib --with-gmp-include=<YOUR-FOLDER>/gmp-6.3.0 --with-mpfr-include=<YOUR-FOLDER>/mpfr-4.2.1/src
make -j$((`nproc`+1)) LDFLAGS=-static
Собранный бинарный файл gdbserver должен находиться в папке gdb-15.1/gdbserver.
Эмулированная прошивка не имеет wget, nc, curl, /dev/tcp, ... Мы не можем запустить Python HTTP-сервер для передачи файлов. Также нет ssh. Однако мы всё равно можем поместить наш gdbserver в эмулированную машину, смонтировав образ.
sudo ./scripts/mount.sh 1gdbserver в любое место смонтированной папки.sudo ./scripts/umount.sh 1./run.sh еще раз для уверенности).

Теперь вы можете выполнять отладку и взлом внутри машины Kali. Однако мы можем пойти дальше и выполнить проброс портов эмулированной машины на хост-машину (Windows или Mac).
Давайте сначала проверим сеть с помощью ifconfig.

Результат показывает, что есть два интерфейса: eth0 и tap1_0. Насколько нам известно, eth0 — это интерфейс общей сети с хостом, а tap1_0 — интерфейс эмулированной машины с прошивкой.
Для более простого понимания: сеть eth0 подобна публичной сети, через которую мы можем получить доступ к машине Kali с хост-машины. tap1_0 — это частная сеть, доступ к которой возможен только с машины Kali. Нам нужно перенаправить соединение с eth0 на порт 192.168.1.1:80 на интерфейсе tap1_0.
Есть много инструментов, которые могут нам в этом помочь. Однако iptables, похоже, работает лучше всего, если, конечно, вы знаете, как его настроить.
Сначала нужно разрешить проброс портов. Выполните эту команду:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
Это действует только на одну сессию. Если вы хотите применить это постоянно, измените содержимое /etc/sysctl.conf.
net.ipv4.ip_forward=1 # Find this line, uncomment it.
Сохраните и закройте файл, когда закончите.
Затем примените настройки из этого файла. Выполните следующую команду:
sudo sysctl -p
sudo sysctl --system
Обычно мы можем выполнить кучу команд iptables. Но это будет слишком утомительно 😵💫. Мы можем установить инструмент iptables-persistent. Он позволяет записать конфигурационный файл, загрузить его в файл или извлечь цепочки в файл. Всё делается быстро.
apt install iptables-persistent
Файл конфигурации, который мы хотим изменить, — /etc/iptables/rules.v4. Меняем содержимое файла на приведенное ниже.
*filter
:INPUT ACCEPT [37:22880]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [35:2330]
# Forward HTTP Port
-A FORWARD -i eth0 -o tap1_0 -p tcp --dport 80 -d 192.168.1.1 -j ACCEPT
-A FORWARD -i tap1_0 -o eth0 -p tcp --sport 80 -s 192.168.1.1 -j ACCEPT
# Forward Debugger port
-A FORWARD -i eth0 -o tap1_0 -p tcp --dport 31337 -d 192.168.1.1 -j ACCEPT
-A FORWARD -i tap1_0 -o eth0 -p tcp --sport 31337 -s 192.168.1.1 -j ACCEPT
COMMIT
# Completed on Wed Aug 7 09:32:11 2024
# Generated by iptables-save v1.8.10 (nf_tables) on Wed Aug 7 09:32:11 2024
*nat
:PREROUTING ACCEPT [60:5405]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [1096:50947]
-A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 192.168.1.1
-A POSTROUTING -o tap1_0 -p tcp -d 192.168.1.1 -j MASQUERADE
Внимание: Разрешение всех портов порождает кучу проблем с безопасностью. Рекомендуется
DROP(заблокировать) все порты, а затемFORWARD(перенаправить) только некоторые по вашему усмотрению.
Сохраните и обновите цепочку iptables.
service netfilter-persistent reload
Теперь вы можете получить доступ к этому из-за пределов хоста.

Несколько конечных точек для эксплуатации. Две из них находятся внутри бинарного файла cfg_manager. Я продемонстрирую только одну из них, другую предлагаю вам разобрать самостоятельно.
Загрузите бинарный файл в ваш любимый декомпилятор, проверьте все команды system, вы можете увидеть это. Команда запускает файл с именем /etc/lanconfig.sh.

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

Объяснение того, что он делает:
/etc/lanconfig.shmxmlElementGetAttr, которая, как я предполагаю, находит атрибут из объекта, возможно, прямо или косвенно из HTTP-запроса, возможно, XML.sprintf для создания строки из атрибутов, полученных от mxmlElementGetAttr.fputs для записи в файл.Сразу же я поискал что-либо в веб-папке boaroot, связанное с IP, netmask и нашел это. Документация по веб-серверу boa крайне ограничена, я могу только предположить, что он помещает POST-параметр lan_ip1 в параметры IP в XML, который вызывается из бинарного файла.

В интерфейсе мы можем найти запрос, который вызывает ошибку. Он находится в Settings > Network (Настройки > Сеть).

Перехватите запрос с помощью Burpsuite, когда нажимаем Save (Сохранить).

Полезная нагрузка 192.168.1.1;utelnetd -p 8090 -l /bin/sh; — это reverse shell. Мы можем подключиться к нему.

Аналогичный, возможно, лучше, чем FAT, не пробовал -> FirmAE.
Binary Ninja стоит всего 74$ при наличии студенческого статуса. Лицензию можно передавать кому угодно.
Другие ошибки, связанные с CVE:

Это также может привести к RCE, я оставлю это вам для самостоятельного выполнения. Память по адресу data_4c0160 может быть внедрена куда-нибудь 🫡.

