Интересно Взлом прошивок USB-устройств: Часть 2

Takeshi

Перо Дьявола
Команда форума
PR-group
CPA & Трафик
Регистрация
23 Янв 2019
Сообщения
1,351
Баллы
0
Общие продажи
0$
Общие покупки
0$
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Для взлома поддельного геймпада мне не пришлось прибегать к фаззингу т.к. я нашел баги еще во время просмотра кода прошивки Gator Claw.


Уязвимый код в обработчике HID реквестов
Функция HID_ClassRequest() написана для симуляции работы оригинального геймпада DualShock 4, и поддерживает минимум необходимых запросов для работы с приставкой PlayStation 4. USBD_GetSetupPacket() получает SETUP-пакет и в зависимости от типа переданного репорта либо получит, либо отправит данные функциями USBD_PrepareCntrlIn() и USBD_PrepareCntrlOut(). Как можно заметить, запрошенный размер данных не проверяется и это должно дать нам возможность читать часть внутренней памяти, где хранится прошивка, а также читать и писать в начало SRAM-памяти.


Переполнение буфера в процессе Control Transfer
Размер DATA-пакета задается в USB Device Descriptor (который также получается с помощью Control Transfer) но, похоже, что остается не учтен тот факт, что этот размер указывает на размер одного пакета, а их может быть сколько угодно в зависимости от размера, заданного в SETUP-пакете.

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


Эксплуатация переполнения буфера в SRAM памяти
SRAM (Static random access memory) — это оперативная память, в которой помимо прочего находится стек. Очень часто SRAM также является исполняемой памятью (настраивается), обычно это делается для улучшения производительности – основная прошивка может скопировать в SRAM часто вызываемый код, например, код Real-Time Operating System. Нет гарантий, что вершина стека будет находиться в достижимых пределах переполнения буфера, но вероятность этого велика.

Неожиданно, но главным препятствием на пути к эксплуатации уязвимостей в прошивках USB-устройств являются операционные системы. Нижеперечисленное характерно для Windows, но думаю, что актуально и для Linux-based систем без специальных исправлений.

Во-первых, ОС не позволяет прочесть больше

Please Login or Register to view hidden text.

айт во время передачи данных Control Transfer. Во-вторых, по моему опыту ОС не позволяет записать больше одного пакета с данными во время Control Transfer. В-третьих, USB-устройство может использовать «скрытые» запросы, которые ОС откажется посылать.

Это легко продемонстрировать на примере устройств HID (Human Interface Device), к которым относится геймпад. У них есть дополнительные дескрипторы: HID Descriptor, Report Descriptor, Physical Descriptor. Второй из списка отличается от каких-либо других дескрипторов и состоит из программных единиц, описывающих доступные репорты. Если запрос не описан в Report Descriptor, то в таком случае ОС откажется его выполнить даже если он обрабатывается в устройстве. Все это противодействует нахождению и эксплуатации уязвимостей.

Чтобы решить эту проблему без необходимости разбираться и перекомпилировать ядро Linux, я воспользовался low end инструментами которые были у меня под рукой: плата Arduino Mega + USB Host Shield (общая стоимость — менее 30 $).


Схема подключения устройств
После подключения устройств по представленной выше схеме, я воспользовался Arduino для выполнения Control Transfer без каких-либо вмешательств со стороны операционной системы.


Arduino Mega + USB Host Shield
Поддельный геймпад содержал те же уязвимости что и Gator Claw, и первое что я сделал — «сдампил» часть прошивки.


«Сдампленная» часть прошивки
Для нахождения базового адреса дампа нашей прошивки достаточно найти структуру с указателями на известные данные. После этого мы можем посчитать дельту и загрузить полученную часть прошивки в IDA Pro.


Структура с указателями на известные данные
Дамп прошивки позволил нам узнать адрес функции printf(), которая выводит в UART информацию, необходимую для контроля качества. Также анализ дампа позволили найти аналог функции hexdump(), что полностью освобождает нас от необходимости написания шеллкода.


Нахождение функций, облегчающих эксплуатацию
После нахождения контактов UART на плате геймпада, припаивания проводов и подключения их к TTL2USB адаптеру мы видим вывод в терминале.


Стандартный UART вывод при включении геймпада
Стандартная библиотека для микроконтроллеров Nuvoton идет с очень удобным обработчиком Hard Fault исключений, который выводит дамп регистров. Это сильно облегчает эксплуатацию и позволяет отлаживать эксплойт.


Вывод в UART при Hard Fault исключении, вызванным перезаписью стека
Финальный эксплойт для дампа прошивки:


Эксплойт и шеллкод для получения дампа прошивки по UART
Но этот способ дампа нельзя считать полноценным, поскольку серия микроконтроллеров Nuvoton M451 позволяет использовать две различные прошивки: основную (APROM) и мини-прошивку для DFU-обновлений (LDROM).


Схема Flash и системной памяти Nuvoton M451 в различных режимах исполнения
Эти прошивки транслируются на одни и те же адреса памяти, поэтому в зависимости от текущего режима можно прочесть только одну из них. Для того, чтобы получить дамп прошивки LDROM, нам нужно отключить security lock и прочитать Flash-память с помощью программатора.


Шеллкод, снимающий security lockКриптофейл
Изучение прошивки обновлений (LDROM) показало, что это стандартный код от Nuvoton, но с добавленным шифрованием обновлений прошивок.


Схема криптографического алгоритма шифрования обновлений прошивок
Шифрование представляет собой кастомный блочный алгоритм, выполненный в режиме сцепления блоков шифротекста, длина которых составляет всего 32 бита. В этот алгоритм предоставляются ключ, который является текстовым (ASCII) идентификатором продукта, и массив инструкций, которые определяют, какое преобразование сделать с текущим блоком. После достижения конца ключа и массива, их позиция устанавливается на начальную. Список преобразований включает в себя шесть операций: xor, subtraction, subtraction (reverse), и повтор этих преобразований с переустановкой байт. Так как в прошивках присутствуют большие области, состоящие из нулевых байт, это позволяет с легкостью посчитать секретные составляющие этого алгоритма.


Раскрытие ключа шифрования обновления прошивки
Применение алгоритма, извлеченного из прошивки контрафактного геймпада, ко всем прошивкам аксессуаров, доступных на сайте OEM-производителя, показало, что они все используют этот алгоритм шифрования. Это позволяет высчитать ключи шифрования для всех устройств и расшифровать все представленные прошивки. Таким образом, алгоритм, вложенный в контрафактный продукт поставил под угрозу безопасность всех продуктов производителя.

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

Please Login or Register to view hidden text.

. А тем, кто задался вопросом, как пираты получили ключи и алогритм из DualShock 4, советую почитать

Please Login or Register to view hidden text.

.

Что касается тайны со вспомогательным микроконтроллером, то оказалось, что, во-первых, он присутствует не во всех устройствах, а во-вторых, добавлен всего лишь для запутывания и не хранит никаких секретов, выполняя лишь операции SHA1 и SHA256. Контроллер Nuvoton M451, может быть объектом для дальнейших исследований т.к. во время этого исследования он продемонстрировал некоторые признаки, которые могут свидетельствовать о наличии архитектурных уязвимостей.

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