...

среда, 19 февраля 2014 г.

[Перевод] Исследуем обфускацию прошивки Linksys WRT120N

Недавно мое внимание привлек факт, что в обновлениях прошивок для Linksys WRT120N используют какую-то обфускацию. Мне показалось, что будет интересно порыться в ней, и я решил взглянуть.

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

image


Как вы можете видеть, есть небольшой блок данных, сжатых LZMA — это просто HTML-файлы для веб-интерфейса роутера. Большая часть прошивки состоит из каких-то странных, случайных данных. Т.к. мне больше ничего с ней не сделать, а любопытство все сильнее пыталось одолеть меня, я купил эту модель роутера себе (как они стоимость Amazon Prime-то взвинтили!).


Анализ железа



При первом же взгляде на железо стало видно, что WRT120N работает на Atheros AR7240 SoC, имеет 2MB SPI флеша, 32MB RAM и что-то похожее на Serial и JTAG-разводку:

image

Для того, чтобы поглубже взглянуть на процесс загрузки, я решил начать с последовательного порта.

image


Я уже ранее рассказывал про последовательные порты, поэтому не буду заострять внимание на методы нахождения пинов и скорости в этой статье. Было легко найти выводы порта с использованием мультиметра и визуального осмотра платы:



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-кода, но сама прошивка все еще нехорошая:

image

Два первых LZMA-блока — часть recovery image, а MIPS-код это сам загрузчик. Все остальное место занимает обфусцированный файл прошивки, кроме нулей и каких-то данных в конце.


Анализ загрузчика



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

Сначала, на раннем этапе загрузки, загрузчик проверяет, не нажата ли кнопка reset. Если она нажата, то он загружает образ “Tiny_ETCPIP_Kernel” — маленький recovery image, с веб-интерфейсом.

image


Это хорошая новость. Теперь мы знаем, что если что-то пойдет не так в процессе обновления прошивки, то можно будет нажать reset и оживить устройство.

А есть еще и скрытый режим администратора в меню загрузчика:

image


Нажатие "!" приведет к включению режима администратора, который разблокирует некоторые опции, включая чтение и запись в память.



[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, которой передается указатель на обфусцированный образ и адрес, куда следует поместить распакованный образ:

image

Сама распаковка не особо сложная:

image


В общем, если прошивка начинается с 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!




image

Анализ распакованной, но не разжатой прошивки

Если кому-то интересно, можете скачать утилиту для распаковки.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий