Привет Хабр! Меня зовут Алексей и я занимаюсь беспроводными технологиями. Не так давно вот в этой статье я рассказал как можно собрать свой кастомный sysupgrade образ имея только роутер с openwrt, а вот здесь о том как можно собрать новый образ для нестандартного оборудования на основе dts файла. Сегодня попробуем зайти с другой стороны и посмотрим какую информацию можно достать из существующего sysupgrade образа, и для того чтобы повысить уровень сложности работать мы будем с образом на основе UBIFS.

Итак в нашем распоряжении файл sysupgrade.bin - это специализированный формат упаковки OpenWrt, который содержит несколько компонентов и может различаться в зависимости от архитектуры устройства. Файл обычно состоит из:

  • Заголовка (metadata и проверочные суммы)

  • Kernel (ядро Linux)

  • Filesystem (файловая система, обычно UBIFS, JFFS2 или SquashFS)

  • Device tree (DTB файлы)

  • Дополнительные разделы (конфигурация, калибровка)

Лучше всего начинать анализ образов с использованием утилиты binwalk если у вас данной утилиты ещё нет - просто поставьте её выполнив:

sudo apt-get install binwalk

Вообще после прочтения этой статьи у вас должен будет выработаться устойчивый рефлекс - вижу образ запускаю binwalk.

Итак, давайте выполним binwalk sysupgrade.bin и посмотрим что находится внутри.

Давайте попорядку разберём все эти данные. Итак, в начале идёт заголовок, который содержит размер, проверочную сумму, размер ядра Linux, дату сборки прошивки, версию ядра Linux, определение операционной системы и архитектуры. Далее располагается само сжатое ядро Linux, потом идут какие-то неизвестные сжатые данные. На то что данные неизвестные как бы намекает сама формулировка XZ данные :) (надеюсь вы простите мне эту попытку юмора). А скорее всего это либо модули ядра, либо дополнительные компоненты, либо бэкап чего-то. Далее идёт описание DTB (device tree) в трёх частях. По всей видимости основная часть и два дополнения либо бэкапа. И завершает всё это UBI раздел, который содержит скорее всего корень файловой системы.

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

dd if=sysupgrade.bin of=device.dtb bs=1 skip=$((0x413880)) count=31872

dtc -I dtb -O dts -o output_1.dts device.dtb

Вот такой результат получился у меня:

Большого количества варнингов пугаться не нужно, главное файл dts успешно собрался. Если резюмировать содержимое dts файла то вот что там содержится:

├── Clock Management System
├── Reset Controllers
├── Interrupt Controllers
├── Memory Controllers
├── Serial/UART Interfaces
├── Ethernet Controllers (GEMAC x5)
├── GPIO Controllers (2 блока)
├── SPI Flash Controller
├── I2C Interface
├── PWM Controllers
├── PCIe Interfaces (2 линии)
└── Various Peripheral Controllers

Детально изучая этот файл, мы понимаем, что речь идёт о пятипортовом Wi-Fi 6 AX роутере. Мы видим производителя, марку и модель, но по вполне понятным причинам эти данные я упоминать не буду. Собственно, данный dts файл может стать отправной точкой для сборки своей собственной прошивки для данного устройства на основе исходников OpenWRT. Но поскольку это не тема нашей сегодняшней статьи, давайте продолжим ковырять sysupgrade.bin дальше. И следующим шагом давайте попробуем извлечь его содержимое, воспользовавшись опять же binwalk с флагом -e и при этом у меня попросили указать флаг --run-as=root.

Извлечение прошло успешно и мы видим вот такое вот содержимое:

Итак, 4 файла и одна папка. Каталог для нас интересного ничего не представляет - он содержит ещё пару вложенных папок и ни одного файла. Расковырять содержимое xz файлов у меня тоже не получилось: используя разные способы, я получал указание либо на неизвестный формат сжатия, либо на повреждённые данные. Но это и не так важно, так как самое интересное содержится наверняка в файле с расширением .ubi.

Давайте попробуем достать его содержимое. Скорее всего внутри содержится UBIFS, и воспользоваться binwalk уже не получится:

При попытке выполнить binwalk для этого файла он по сути извлечёт его ещё раз и вытащит ��ам то, что уже у нас и так есть. Для извлечения данных давайте воспользуемся специальной утилитой ubireader. Есть несколько способов установить эту утилиту. На мой взгляд, самый простой через pip:

# Установка Python пакета
sudo apt-get install python3 python3-pip

# Установка ubireader
pip3 install ubireader

В результате у нас появилась еще одна папка содержащая UBIFS, образ внутри которого, судя по названию, содержится файловая система squashFS:

Проанализируем новый образ binwalk

Наша догадка подтверждается внутри действительно squashFS и теперь ничего уже не мешает достать нам содержимое файловой системы:

Как обычно не пугаемся варнингов и проверяем что получилось:

Получив доступ к файловой системе мы можем выяснить все интересующую нас информацию начиная от версии openwrt и заканчивая, например, сетевыми интерфейсами:

# Проверить версию OpenWrt
cat _sysupgrade.bin.extracted/squashfs-root/etc/os-release

# Посмотреть конфигурацию сети
cat _sysupgrade.bin.extracted/squashfs-root/etc/config/network

Большое спасибо, что дочитали до конца. Рад буду ответить на вопросы и продолжить обсуждение в комментариях.