Последняя версия прошивки не выглядит как прошивка, с которой можно сразу работать
Как вы можете видеть, есть небольшой блок данных, сжатых LZMA — это просто HTML-файлы для веб-интерфейса роутера. Большая часть прошивки состоит из каких-то странных, случайных данных. Т.к. мне больше ничего с ней не сделать, а любопытство все сильнее пыталось одолеть меня, я купил эту модель роутера себе (как они стоимость Amazon Prime-то взвинтили!).
Анализ железа
При первом же взгляде на железо стало видно, что WRT120N работает на Atheros AR7240 SoC, имеет 2MB SPI флеша, 32MB RAM и что-то похожее на Serial и JTAG-разводку:
Для того, чтобы поглубже взглянуть на процесс загрузки, я решил начать с последовательного порта.
Я уже ранее рассказывал про последовательные порты, поэтому не буду заострять внимание на методы нахождения пинов и скорости в этой статье. Было легко найти выводы порта с использованием мультиметра и визуального осмотра платы:
Pin 2 – RX Pin 3 – TX Pin 5 – Ground
Порт работает на скорости 115200 бод и выдает интересную загрузочную информацию:
$ sudo miniterm.py /dev/ttyUSB0 115200 --- Miniterm on /dev/ttyUSB0: 115200,8,N,1 --- --- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H --- ======================================================================= Wireless Router WG7005G11-LF-88 Loader v0.03 build Feb 5 2009 15:59:08 Arcadyan Technology Corporation ======================================================================= flash MX25L1605D found. Copying boot params.....DONE Press Space Bar 3 times to enter command mode ... Flash Checking Passed. Unzipping firmware at 0x80002000 ... [ZIP 3] [ZIP 1] done In c_entry() function ... install_exception install exception handler ... install interrupt handler ... ulVal: 0x484fb Set GPIO #11 to OUTPUT Set GPIO #1 to OUTPUT Set GPIO #0 to OUTPUT Set GPIO #6 to INPUT Set GPIO #12 to INPUT Timer 0 is requested ##### _ftext = 0x80002000 ##### _fdata = 0x80447420 ##### __bss_start = 0x804D5B04 ##### end = 0x81869518 ##### Backup Data from 0x80447420 to 0x81871518~0x818FFBFC len 583396 ##### Backup Data completed ##### Backup Data verified [INIT] HardwareStartup .. [INIT] System Log Pool startup ... [INIT] MTinitialize .. CPU Clock 350000000 Hz init_US_counter : time1 = 270713 , time2 = 40272580, diff 40001867 US_counter = 70 cnt1 41254774 cnt2 41256561, diff 1787 Runtime code version: v1.0.04 System startup... [INIT] Memory COLOR 0, 1600000 bytes .. [INIT] Memory COLOR 1, 1048576 bytes .. [INIT] Memory COLOR 2, 2089200 bytes .. [INIT] tcpip_startup .. Data size: 1248266 e89754967e337d9f35e8290e231c9f92 Set flash memory layout to Boot Parameters found !!! Bootcode version: v0.03 Serial number: JUT00L602233 Hardware version: 01A ...
Похоже, прошивка сделана компанией Arcadyan, особенно интересно было сообщение ‘Unzipping firmware…’, быстрый гуглёж привел меня к посту про деобфускацию прошивок от Arcadyan, но тут, похоже, применяется немного другой метод.
Через последовательный порт можно только использовать меню загрузчика. Во время загрузки можно в него залезть, если нажать три раза пробел, и выполнить некоторые действия, такие как очистка флеша и установка настроек платы:
Press Space Bar 3 times to enter command mode ...123 Yes, Enter command mode ... [WG7005G11-LF-88 Boot]:? ====================== [U] Upload to Flash [E] Erase Flash [G] Run Runtime Code [A] Set MAC Address [#] Set Serial Number [V] Set Board Version [H] Set Options [P] Print Boot Params [I] Load ART From TFTP [1] Set SKU Number [2] Set PIN Number ======================
К сожалению, загрузчик не позволял сдампить содержимое RAM или флеша. Хоть на плате и есть JTAG-разводка, я решил сдампить флеш напрямую, т.к. процесс дампа через JTAG, как правило, не быстрый, а подключение SPI очень простое.
Наверное любое устройство, которое поддерживает протокол SPI, может читать флеш. Я использовал кабель FTDI C232HM и программку spiflash.py из состава libmpsse
$ sudo spiflash --read=flash.bin --size=$((0x200000)) --verify FT232H Future Technology Devices International, Ltd initialized at 15000000 hertz Reading 2097152 bytes starting at address 0x0...saved to flash.bin. Verifying...success.
Флеш состоит из трех LZMA-блоков и небольшого количества MIPS-кода, но сама прошивка все еще нехорошая:
Два первых LZMA-блока — часть recovery image, а MIPS-код это сам загрузчик. Все остальное место занимает обфусцированный файл прошивки, кроме нулей и каких-то данных в конце.
Анализ загрузчика
Загрузчик, помимо того, что он расшифровывает прошивку и загружает ее по адресу в память, содержит некоторые интересные штучки. Я пропущу скучные вещи, вроде того как я искал адрес загрузки загрузчика, вручную определял функции стандартной библиотеки C, находил таблицу смещения JUMP-ов и т.д., а сразу перейду к интересному.
Сначала, на раннем этапе загрузки, загрузчик проверяет, не нажата ли кнопка reset. Если она нажата, то он загружает образ “Tiny_ETCPIP_Kernel” — маленький recovery image, с веб-интерфейсом.
Это хорошая новость. Теперь мы знаем, что если что-то пойдет не так в процессе обновления прошивки, то можно будет нажать reset и оживить устройство.
А есть еще и скрытый режим администратора в меню загрузчика:
Нажатие "!" приведет к включению режима администратора, который разблокирует некоторые опции, включая чтение и запись в память.
[WG7005G11-LF-88 Boot]:! Enter Administrator Mode ! ====================== [U] Upload to Flash [E] Erase Flash [G] Run Runtime Code [M] Upload to Memory [R] Read from Memory [W] Write to Memory [Y] Go to Memory [A] Set MAC Address [#] Set Serial Number [V] Set Board Version [H] Set Options [P] Print Boot Params [I] Load ART From TFTP [1] Set SKU Number [2] Set PIN Number ====================== [WG7005G11-LF-88 Boot]:
Самая интересная часть загрузчика, конечно же, та, которая загружает обфусцированную прошивку в память.
Анализ обфускации
Деобфускация выполняется в функции load_os, которой передается указатель на обфусцированный образ и адрес, куда следует поместить распакованный образ:
Сама распаковка не особо сложная:
В общем, если прошивка начинается с 04 01 09 20 (а наша именно с этих байт и начинается), то выполняется алгоритм расшифровки, который:
- Переставляет два 32-байтных блока данных по адресам 0×04 и 0×68
- Переставляет 4 бита у первых 32 байт, начиная с адреса 0×04
- Побайтно переставляет смежные 32 байта, начиная с 0×04
После этого всего, данные по адресу 0×04 содержат верный LZMA-заголовок, которые потом разжимаются.
Реализовать утилиту деобфускации было просто, и прошивка WRT120N теперь может быть распакована и разжата.
$ ./wrt120n ./firmware/FW_WRT120N_1.0.07.002_US.bin ./deobfuscated.bin Doing block swap... Doing nibble-swap... Doing byte-swap... Saving data to ./deobfuscated.bin... Done!
Анализ распакованной, но не разжатой прошивки
Если кому-то интересно, можете скачать утилиту для распаковки.
ссылка на оригинал статьи http://habrahabr.ru/post/213191/
Добавить комментарий