Закрыть
В мире Обзоры Технологии Угрозы

Анализ встроенного ПО маршрутизаторов: Эмуляция прошивки TP-Link, Часть 3

Анализ встроенного ПО маршрутизаторов: Эмуляция прошивки TP-Link, Часть 3

Корневая файловая система

Если вы скачали прошивку с официального сайта производителя или вы получили из способа, который показан во второй части нашего блога,и в целом, то ее легко извлечь командой binwalk -e firmware.bin, в качестве примера мы берем прошивку TP-Link WR841N V14 250328 US, чтобы наглядно показать, как она работает на самом деле.

После разархивирования и рекурсивного извлечения в файле firmware.bin.extracted мы видим несколько файлов ядра

ls
100200.squashfs  10400  10400.7z  squashfs-root  squashfs-root-0

Это извлеченная корневая файловая система из образа SquashFS. Инструмент unsquashfs создает этот каталог по умолчанию. Он содержит фактическое дерево корневой файловой системы Linux:/bin, /sbin, /etc, /www, /usr и т. д. Это та часть, которую вы анализируете для проверки скриптов, кода веб-интерфейса, двоичных файлов, конфигураций, паролей и т. д.

У нас есть несколько мест, которые мы должны пороверить: /usr/bin/httpd Этот двоичный файл соответствует внутренней работе с веб-сервисом, который дает администратору контроль, а также /etc/init.d/rcS начальный скрипт, который запускает скрипты и инициализирует маршрутизатор для правильной работы.

Эмуляция прошивки с помощью QEMU

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

Что такое QEMU?

QEMU (Quick Emulator) — это эмулятор машины с открытым исходным кодом, который запускает программное обеспечение, разработанное для одной аппаратной архитектуры, на совершенно другой системе. В отличие от традиционных виртуальных машин, которые полагаются на собственные инструкции центрального процессора, QEMU может полностью эмулировать такие процессоры, как ARM, MIPS, PowerPC, x86, RISC-V и другие. Это делает его бесценным при анализе встраиваемых устройств, прошивки которых часто ориентированы на архитектуры, которые ваш ноутбук или сервер не поддерживает изначально.

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

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

Как определить версию и архитектуру ядра?

strings 10400 | grep Linux 
Linux version 2.6.36 (jenkins@sohoicilinux4) (gcc version 4.6.3 (Buildroot 2012.11.1) )

С помощью strings и grep мы получим точную версию Linux. Следующий шаг — определение архитектуры для точной эмуляции.

С помощью команды file мы получаем всю информацию о файле.

file bin/busybox 
bin/busybox: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped
file usr/bin/httpd 
usr/bin/httpd: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped

Вы можете загрузить все необходимые образы из этих источников:

wget https://people.debian.org/~aurel32/qemu/mipsel/debian_wheezy_mipsel_standard.qcow2
wget https://people.debian.org/~aurel32/qemu/mipsel/vmlinux-2.6.32-5-4kc-malta
wget https://people.debian.org/~aurel32/qemu/mipsel/vmlinux-3.2.0-4-4kc-malta

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

sudo qemu-system-mipsel \
    -M malta \
    -kernel vmlinux-2.6.32-5-4kc-malta \
    -hda debian_squeeze_mipsel_standard.qcow2 \
    -append "root=/dev/sda1 console=ttyS0 nokaslr" \
    -net nic,model=e1000 \
    -net user,hostfwd=tcp::8080-:80,hostfwd=tcp::8443-:443,hostfwd=tcp::2222-:22 \
    -nographic \
    -m 256M

И так, эта команда указывает QEMU на загрузку little-endian MIPS-системы с использованием платы Malta— платформы, которую ядра Linux поддерживают очень хорошо. Поставляемый файл vmlinux* — это скомпилированное ядро, которое будет работать внутри эмулятора, а образ диска QCOW2 выступает в качестве хранилища виртуальной машины. От него зависит и начальный образ RAM-диска (initrd).

Аргументы загрузки определяют, как стартует система:

  • root=/dev/sda1 указывает ядру на корневую файловую систему,
  • console=ttyS0 обеспечивает вывод всех данных на последовательную консоль,
  • nokaslr отключает рандомизацию памяти для облегчения отладки.

Работа с сетью осуществляется через виртуальную сетевую карту Intel e1000, сопряженную с сетевым стеком QEMU, работающим в пользовательском режиме. Перенаправление портов обеспечивает удобный доступ к сервисам внутри виртуальной машины с вашего хоста: HTTP на порту 8080, HTTPS на 8443 (как пример) и SSH на 2222. Запуск с параметром -nographic полностью исключает графическое окно и предоставляет чистый последовательный терминал, именно так общаются большинство встраиваемых систем. Память ограничена небольшим объемом в 256 МБ, что делает среду реалистичной для оборудования класса маршрутизаторов.

С помощью этих флагов QEMU превращается в полнофункциональный тестовый стенд MIPS, идеально подходящий для анализа прошивки, эмуляции сервисов и контролируемых экспериментов, не прикасаясь к реальному устройству.

Анализ встроенного ПО маршрутизаторов: Эмуляция прошивки TP-Link, Часть 3

Как показано на скриншоте, мы входим в систему с учетными данными root:root

Конечно, на файловой системе ничего нет, потому что мы не переносили никаких файлов из нашего пользовательского squashedfs в QEMU.

Прямая эмуляция отдельных частей прошивки

В редких случаях можно эмулировать командой бинарник (извлеченную прошивку), если он не имеет зависимостей, требующих уникальных библиотек или окружения:

Запуск бинарных файлов напрямую с помощью qemu-mipsel-static

qemu-mipsel-static -L squashfs-root/ squashfs-root/bin/sh
$ echo "worked" # worked

Или для конкретных программ, в редких случаях работает, в нашем случае нет

qemu-mips-static -L squashfs-root/ squashfs-root/usr/sbin/httpd

Способы перемещения файлов с хоста на VM.

К сожалению, вы не можете перетаскивать файлы, как в VirtualBox или VMware. В QEMU есть несколько безопасных способов перемещения файлов в VM.

SSH с переадресацией портов

Один из самых безопасных и простых способов перемещения файлов — это SSH.

Во-первых, убедитесь, что вы пробросили порт с VM на HOST с правильным флагом:

-net user ... hostfwd=tcp::2222-:22

И с помощью этой команды вы сможете подключиться к SSH:

ssh -p 2222 root@localhost -o HostKeyAlgorithms=+ssh-rsa

И с помощью команды перемещаем все файлы:

scp -r -P 2222 -o HostKeyAlgorithms=+ssh-rsa /home/somename/Projects/router/tplink/_firmware.bin.extracted/squashfs-root     root@localhost:/root/firmware/

Использование файловой системы 9p (общая папка)

Вот конфигурация скрипта.

qemu-system-mipsel \
    -M malta \
    -kernel vmlinux-3.2.0-4-4kc-malta \
    -append "nokaslr root=/dev/sda1" \
    -hda debian_wheezy_mipsel_standard.qcow2 \
    -virtfs local,path=/path/to/squashfs-root,mount_tag=host0,security_model=passthrough,id=host0 \
    -net nic -net user \
    -nographic

Взгляните на важную часть конфигурации файловой системы qemu 9p.

-virtfs local,path=/path/to/squashfs-root,mount_tag=host0,security_model=passthrough,id=host0 \

И заходим в QEMU:

mkdir /mnt/host
mount -t 9p -o trans=virtio,version=9p2000.L host0 /mnt/host
cp -r /mnt/host/* /tmp/firmware/

Примечание: Этот метод не поддерживается версией ядра, используемой в нашем тестовом примере; он предназначен для более современной версии ядра.

Прикрепление прошивки в качестве второго диска

Создайте образ диска с вашей прошивкой

dd if=/dev/zero of=firmware.img bs=1M count=200
mkfs.ext4 firmware.img

Смонтируйте и скопируйте прошивку

sudo mkdir -p /mnt/firmware-disk
sudo mount firmware.img /mnt/firmware-disk
sudo cp -r squashfs-root/* /mnt/firmware-disk/
sudo umount /mnt/firmware-disk

Запустите QEMU с подключенным диском с прошивкой

sudo qemu-system-mipsel \
    -M malta \
    -kernel vmlinux-3.2.0-4-4kc-malta \
    -append "nokaslr root=/dev/sda1" \
    -hda debian_wheezy_mipsel_standard.qcow2 \
    -hdb firmware.img \
    -net nic -net user \
    -nographic

Подготовка среды для эмуляции

Перед запуском виртуальной машины мы должны подготовить сетевое окружение хоста, чтобы QEMU мог взаимодействовать с локальной машиной. QEMU взаимодействует с хостом через интерфейсы TUN/TAP, где /dev/net/tun отображается как дескриптор файла, а tap0 ведет себя как виртуальная сетевая карта, подключенная к сетевому стеку хоста. Чтобы поддержать это, мы создаем интерфейс моста (br0) на хосте, а затем подключаем к нему сетевую карту хоста и интерфейс TAP.

sudo apt-get install bridge-utils
sudo apt-get install uml-utilities

Настройте мост и подключите физический интерфейс (замените eno2 на реальную сетевую карту):

ifconfig eno2 down
brctl addbr br0
brctl addif br0 eno2
brctl stp br0 on
brctl setfd br0 2
brctl sethello br0 1
ifconfig br0 0.0.0.0 promisc up
ifconfig eno2 0.0.0.0 promisc up
dhclient br0

Вы можете проверить работу моста с помощью:

brctl show br0
brctl showstp br0

Далее создайте и настройте интерфейс TAP:

tunctl -t tap0
brctl addif br0 tap0
ifconfig tap0 0.0.0.0 promisc up
ifconfig tap0 192.168.1.1/24 up  # subnet    

Проверьте состояние моста:

brctl showstp br0

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

А внутри виртуальной машины вам нужно назначить IP-адрес вручную, если DHCP его не присвоил.

brctl addbr br0                       
ifconfig br0 192.168.1.x/24 up # x должен принадлежать к подсети     

Если мы откроем папку с прошивкой, которая была перенесена в /root/firmware в VM. Мы увидим, что все папки были полностью перенесены. Далее мы должны привязать каталоги VM /proc, /dev и /sys к файловой системе извлеченной прошивки.

mount -o bind /proc proc/
mount -o bind /sys sys/
mount -o bind /dev dev/

Как только эти системные пути будут правильно отображены, мы сможем переключиться в среду прошивки с помощью chroot

chroot squashfs-root/ /bin/sh

Вы, вероятно, думаете, что все хорошо, и мы готовы запустить скрипт из /etc/init.d/rcS и вручную запустить соответствующие сценарии запуска, чтобы вызвать службы пользовательского окружения. НО это не удастся. Так как каждая прошивка ведет себя по-разному; эти сценарии часто требуют корректировки для учета отсутствующих сетевых устройств, неработающих с вызововоми NVRAM и других причуд. Иногда на правильную эмуляцию уходят недели. И в процессе поиска решений для своих ошибок вы попадаете на GitHub Issues, где те баги, которык вы искали, они уже там обсуждались и были решены. А для себя вы открываете пару отличных инструментов, которые могут частично эмулировать вашу прошивку.

Firmadyne

Анализ встроенного ПО маршрутизаторов: Эмуляция прошивки TP-Link, Часть 3

Firmadyne может быть невероятно полезен. Это автоматизированный фреймворк, предназначенный для эмуляции прошивки устройств на базе Linux и поддерживающий архитектуры MIPS и ARM. Инструмент справляется с извлечением корневой файловой системы, угадывает сетевые интерфейсы, создает образ диска QEMU и даже эмулирует поведение NVRAM.

Если вы подбираете новую прошивку и хотите получить полную эмуляцию системы, стоит сначала попробовать Firmadyne. Вы сможете исправить некоторые ее причуды или ошибки, прежде чем прибегать к ручным методам эмуляции. Следует отметить, что новые версии QEMU иногда вызывают непредсказуемые проблемы. Запуск Firmadyne внутри Docker обычно позволяет обойти эти проблемы совместимости.

ARM-X

Анализ встроенного ПО маршрутизаторов: Эмуляция прошивки TP-Link, Часть 3

ARM-X — это еще один набор инструментов для эмуляции прошивки, но ориентированный на устройства на базе ARM. Он содержит набор ядер, скриптов и подготовленных файловых систем для загрузки ARM-прошивок в QEMU. Фреймворк также включает несколько примеров конфигураций, которые можно использовать в качестве стартовых шаблонов для различных устройств.

Эмуляция прошивки маршрутизатора TP-Link с помощью Firmadyne

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

Быстрая настройка

Установка зависимостей и клонирование Firmadyne

sudo apt-get update
sudo apt-get install -y busybox-static fakeroot git dmsetup kpartx netcat-openbsd \
    nmap python3-psycopg2 python3-pip snmp uml-utilities util-linux vlan \
    qemu-system-arm qemu-system-mips qemu-system-x86 qemu-utils postgresql

cd ~
git clone --recursive https://github.com/firmadyne/firmadyne.git
cd firmadyne

Конфигурация базы данных

Создайте пользователя PostgreSQL и базу данных (пароль: firmadyn).

sudo -u postgres createuser -P firmady
sudo -u postgres createdb -O firmadyne firmware
sudo -u postgres psql -d firmware < ./database/schema

Настройте пути к Firmadyne:

nano firmadyne.config
FIRMWARE_DIR=/home/yourusername/firmadyne/

Скачать готовые ядра

cd ~/firmadyne
./download.sh

Извлечение и эмуляция прошивки

Извлеките файловую систему прошивки:

python3 ./sources/extractor/extractor.py -b Netgear -sql 127.0.0.1 -np -nk \
    "TL-WR841Nv14.bin" images

Определите архитектуру

./scripts/getArch.sh ./images/1.tar.gz

Сохранение файловой системы в базе данных

./scripts/tar2db.py -i 1 -f ./images/1.tar.gz

Создание образа диска QEMU:

sudo ./scripts/makeImage.sh 1

Определите конфигурацию сети и запустите эмуляцию

./scripts/inferNetwork.sh 1
sudo ./scratch/1/run.sh

Понимание каталога Scratch

После запуска makeImage.sh Firmadyne создает каталог scratch с идентификатором вашего образа. Структура выглядит следующим образом:

firmadyne/
├── scratch/
│   └── 1/              # ID образа
│       ├── run.sh      # Скрипт для запуска эмуляции
│       ├── image.raw   # Образ диска QEMU
│       └── ...

Доступ к эмулируемому маршрутизатору

После запуска sudo ./scratch/1/run.sh в выводе отображается конфигурация сети:

IP Address: 192.168.0.1
Web Interface: http://192.168.0.1

С другого терминала проверьте, доступен ли он:

ping 192.168.0.1
curl http://192.168.0.1

Альтернативный вариант в случае неудачи: Использование FirmAE

FirmAE — это улучшенная версия, которая лучше работает с современными прошивками:

git clone --recursive https://github.com/pr0v3rbs/FirmAE.git
cd FirmAE

# Установить ( устанавливает все зависимости)
./install.sh

# Запустить прошивку (одна команда выполняет все задачи)
./run.sh -r ~/TL-WR841Nv14_US_0.9.1_4.19_up_boot[250328-rel51324]_2025-03-28_14.16.58.bin

Если каталог не создан, проверьте, удалось ли выполнить makeImage.sh:

ls -la scratch/

Если извлечение не удалось, вручную извлеките с помощью binwalk:

binwalk -e TL-WR841Nv14*.bin

cd _TL-WR841Nv14*.extracted
tar -czf ../manual.tar.gz squashfs-root/

mv manual.tar.gz ~/firmadyne/images/1.tar.gz

Пример полного рабочего процесса

cd ~/firmadyne

# Извлеките ( обратите внимание на ID в выводе)
python3 sources/extractor/extractor.py -b TPLink -sql 127.0.0.1 -np -nk \
    "TL-WR841Nv14.bin" images

# ID: 2
./scripts/getArch.sh ./images/2.tar.gz
./scripts/tar2db.py -i 2 -f ./images/2.tar.gz
sudo ./scripts/makeImage.sh 2
./scripts/inferNetwork.sh 2

# Запустите эмуляцию
sudo ./scratch/2/run.sh

firefox http://192.168.0.1
  • extractor.py: Извлекает файловую систему с помощью binwalk и создает tarball в images/
  • getArch.sh: Определяет архитектуру процессора (mips, mipsel, armel)
  • tar2db.py: Загружает метаданные файловой системы в базу данных PostgreSQL
  • makeImage.sh: Создает загрузочный образ диска QEMU в scratch/ID/
  • inferNetwork.sh: Анализирует конфигурацию сети и создает сетевую настройку
  • run.sh: Запускает QEMU с правильной конфигурацией ядра, сети и диска.

Ключевое отличие от ручной настройки QEMU заключается в том, что Firmadyne автоматизирует выбор ядра, создание сетевого моста и генерирует полную команду QEMU на основе обнаруженных характеристик прошивки. И вот, наконец, мы получили нашу эмуляцию:

Анализ встроенного ПО маршрутизаторов: Эмуляция прошивки TP-Link, Часть 3

А еще в Ghidra мы можем свободно реверсировать двоичные файлы из прошивки.

Анализ встроенного ПО маршрутизаторов: Эмуляция прошивки TP-Link, Часть 3

Заключение

В этой работе мы рассмотрели несколько подходов к эмуляции прошивок: от полностью ручных методов до частично автоматизированных решений. Мы прошли через настройку окружения, подготовку сетевой конфигурации, запуск системы через QEMU и разбор особенностей загрузочных скриптов. Также были показаны инструменты, такие как Firmadyne и ARM-X, которые могут упростить процесс и взять на себя часть рутинных задач.

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

Анализ встроенного ПО маршрутизаторов: Введение, Часть 1
Анализ встроенного ПО маршрутизаторов: Способы извлечения прошивки из маршрутизатора, Часть 2

Оставить Комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *