Приветствую вас, дорогие читатели! Сегодня хочу рассказать вам о том, как я получил интерфейс командной оболочки Linux у wi-fi роутера Mi Router 4A Giga Version:
Разбор роутера и подключение к ноутбуку
Для начала я разберу роутер, чтобы определить какие порты, чипы и т. д. расположены на его плате:
Из интересного было обнаружено:
После внимательного изучения платы я подключил роутер к ноутбуку, используя UART порт, чтобы определить, какая информация по нему передается. Для этого я припаял провода к UART порту:
а другой конец подключил к PL2303:
Затем установил на Windows 7 драйвер PL2303 и Putty:
Далее подключился к wi-fi роутеру с помощью Putty. Для этого необходимо проделать следующие шаги:
Включить wi-fi роутер.
Подключить PL2303 к ноутбуку:
Выбрать параметры в Putty и нажать "Open":
После нажатия кнопки "Open" в Putty, можно увидеть процесс загрузки прошивки wi-fi роутера но есть проблема - нет возможности передать информацию с помощью Putty. В следствие чего я не могу повлиять на процесс загрузки прошивки, выбрав один из пунктов меню (Рисунок 10), а также нет интерфейса командной оболочки после завершения загрузки прошивки (Рисунок 11).
Дамп прошивки
Чтобы решить проблему передачи информации с помощью Putty и последующего выбора одного из пунктов меню, я сделал дамп прошивки и изучил его. Итак, для дампа прошивки я подключил прищепку-коннектор к чипу 25Q127CSIG (SPI), как изображено на рисунке, красный провод к первой ноге чипа. Первая нога чипа там, где изображен круг на чипе 25Q127CSIG (SPI):
а другой конец прищепки-коннектора подключил к программатору EZP2019+ через переходник:
а сам EZP2019+ к ноутбуку:
Далее установил на Windows 7 драйвер для EZP2019+ и EZP2019+.exe:
Затем запустил EZP2019+.exe и выбрал чип 25Q127C. Но так как его нет в списке, я взял ближайший к нему по характеристикам, под номером 25Q128C:
Потом нажал на кнопку "READ" в программе EZP2019+.exe, дождался, когда прошивка считается, и сохранил в файл spi.bin.
Исследование прошивки
После получения дампа прошивки, я приступил к его исследованию. Начал с поиска места проверки вводимого через консоль числа, так как есть предположение, что пункт “3: Boot system code via Flash (default)” имеет константное значение, из-за чего я не могу выбрать любой другой пункт меню (Рисунок 17).
Когда я открыл файл spi.bin с помощью binwalk, меня заинтересовала строка “U-Boot version string, ‘U-Boot 1.1.3 (Aug 18 2020 – 11:10:29)’” (Рисунок 18) по смещению 0x17DA0 от начала файла spi.bin. Эта строка указывает на то, что секция загрузчика в этой прошивке U-Boot.
Далее нашел начало секции загрузчика U-Boot в файле spi.bin. Эту информацию я узнал, посмотрев на процессе загрузки прошивки wi-fi роутера в Putty. В момент загрузки прошивки wi-fi роутера, я увидел, что U-Boot от компании Ralink версии 5.0.0.0 (Ralink UBoot Version: 5.0.0.0). Поискав в интернете данную версию, я нашел проект на github (https://github.com/cidermole/ralink-uboot), в котором есть описание начала секции загрузчика U-Boot. Сверив свое начало файла с проектом на github, я пришел к выводу, что они совпадают (Рисунок 19). Значит это — начало секции загрузчика U-Boot в файле spi.bin по смещению 0x00000000.
Следом я открыл файл spi.bin в IDA Pro, но перед тем, как это сделать, определил архитектуру (x86, x64, ARM, MIPS) файла spi.bin. Это можно сделать, взяв любой бинарный файл из файла spi.bin. Для этого воспользовался binwalk с параметрами –Me:
-M - рекурсивное сканирование извлеченных файлов.
-e - автоматическое извлечение известных типов файлов.
После выполнения команды binwalk –Me создается директория _spi.bin.extracted, в которой можно найти исполняемые файлы операционной системы Linux, одним из которых является wpad:
Этот файл я открыл с помощью IDA Pro x86 и посмотрел, какие параметры выбирает IDA Pro:
Узнав, какие параметры выбирает IDA Pro в момент открытия файла wpad, я могу открыть файл spi.bin в IDA Pro x86 с такими же параметрами (Рисунок 23).
После того как я открыл файл spi.bin в IDA Pro, его необходимо разметить (преобразовать из байт кода в читабельный ассемблерный (assembler) код). Во-первых, я отсчитал от начала файла 0x1000 байт, чтобы не наткнуться на служебную область. Во-вторых, выделил несколько тысяч байт, например, с 0x1000 до 0x4000. Это необходимо для того, чтобы IDA Pro могла автоматически преобразовать из байт кода в ассемблерный код (Рисунок 24):
И нажал на клавиатуре “C”, чтобы появилось диалоговое окно, и следом нажал на кнопку “Analyze”:
В результате получил ассемблерный код:
Дальше необходимо понять, какой Imagebase (это базовый адрес загрузки программы) для того, чтобы IDA Pro могла создать перекрёстные ссылки (это информация о том, где в коде используется функция или строка), относящиеся к строкам и функциям. Это можно сделать, посмотрев на dword (Рисунок 27) или посмотреть в hex-rays (это функциональная возможность IDA Pro, позволяющая конвертировать assembler code в псевдо-код, наподобие языка программирования С) (Рисунок 28). Чтобы перейти в hex-rays, необходимо нажать на клавиатуре "F5".
Из вышесказанного (Рисунок 27, Рисунок 28), можно сделать вывод, что Imagebase начинается с 0xBFC*, а вот четвертый байт я нашел перебором от 0 до 9. Правильный байт можно определить, посмотрев на строки, они должны преобразоваться в следующий вид и иметь перекрестные ссылки (Рисунок 29).
Теперь необходимо изменить Imagebase в IDA Pro. Для этого я перешёл в Edit -> Segments -> Rebase program... и изменил Imagebase на 0xBFC10000:
Далее приступил к решению проблемы в передаче информации с помощью Putty и последующем выборе одного из пунктов меню. Начал я с поиска строки “3: Boot system code via Flash (default)” в файле spi.bin с помощью IDA Pro:
Затем я нажал на aDBootSystemCod (Рисунок 32).
и следом нажал на клавиатуре "X", затем появляется окно, в котором можно увидеть, где используется данная строка.
Потом нажал на строчку sub_BFC028C0+6C (Рисунок 33) и провалился в функцию sub_BFC028C0:
Дальше нажал на функцию sub_BFC028C0 (Рисунок 34), затем на клавиатуре “X” и посмотрел, куда ведёт эта функция. Она привела в место проверки введённого числа (Рисунок 35). Также из документации по U-Boot следует, что bootdelay – это количество секунд, данное на ввод числа, для выбора одного из пунктов. А вот описания boot_wait в документации не обнаружено.
Вернемся к проблеме, описанной выше. Я не мог передать информацию с помощью Putty и выбрать пункт меню, так как в коде есть константное значение (Рисунок 35 – строка 259) и нет возможности передачи информации роутеру с помощью Putty, потому что переменная v33 равна “off” (Рисунок 35 – строка 239). Исходя из этого есть два варианта: изменить константное значение на необходимое мне, или удалить “off”. Я выбрал второй вариант, так как он позволит более гибко выбирать пункты меню (Рисунок 10) и удалил “off” в файле spi.bin:
Перепрошивка роутера и получение командной оболочки Linux
Следом перепрошил wi-fi роутер полученным дампом прошивки. Для этого подключил прищепку-коннектор к чипу 25Q127CSIG (SPI), как было описано выше. Затем запустил EZP2019+.exe и выбрал чип 25Q128C. Потом нажал на кнопку "OPEN", выбрал файл spi_fix.bin. Далее нажал на кнопку “WRITE” и дождался, когда прошивка загрузится:
После загрузки прошивки я подключился к wi-fi роутеру с помощью Putty.exe и выбрал пункт “4: Entr boot command line interface” (Рисунок 38). Пункт 4 позволяет зайти в интерфейс командной оболочки загрузчика и используя командную оболочку загрузчика попасть в интерфейс командной оболочки Linux.
Теперь необходимо разобраться, как из командной оболочки U-Boot, получить командную оболочку Linux. Я начал с чтения документации по U-Boot, поскольку в ней есть описание переменной bootargs. В документации сказано, что содержимое этой переменной передается ядру Linux в качестве параметра загрузки. Далее я посмотрю в IDA Pro, где используется эта переменная:
После изучения кода, отвечающего за содержимое переменной bootargs, меня заинтересовали переменные (Рисунок 40), описание которых я не обнаружил в документации.
Названия этих переменных наталкнули меня на мысль, что они отвечают за включение и отключение определенного функционала у роутера. Чтобы проверить эту гипотезу, я зашёл в командную оболочку U-Boot и посмотрел, чему равняются эти переменные (Рисунок 41), и поменял содержимое этих переменных на противоположные (Рисунок 42). Затем перезагрузил роутер командой “bootm”.
При загрузке прошивки wi-fi роутера я выбрал пункт “3: Boot system code via Flash (default)” и после окончания загрузки прошивки получил командную оболочку Linux:
Если кому-то стала интересна данная тема, то предлагайте свои идеи в комментариях, что можно посмотреть в прошивке или сделать с ней. Например, я мог бы посмотреть какую информацию отправляет роутер на сервера производителя, поискать бинарные уязвимости или уязвимости, связанные с web частью.