В этой статье я хочу продемонстрировать извлечение прошивки из защищенного USB-устройства, работающего на микроконтроллере Cortex M0.
Кто взламывает игровые приставки?
Производство пиратских, нелицензированных изделий — многомиллиардная индустрия и на рынке можно найти аксессуары практически для всех когда-либо вышедших игровых приставок. Здесь и устройства, позволяющие воспроизведение копий лицензионных игр из «бэкапов» с произвольных носителей, и контрафактные геймпады, и различные адаптеры для игровых контроллеров (в том числе дающие преимущество перед другим игроками), и гаджеты для применения читов в офлайн- и онлайн-играх. Разумеется, все эти устройства продаются вопреки желанию производителей игровых приставок.
Игровые консоли, как и двадцать лет назад, представляют собой проприетарные системы, производители которых навязывают свои правила миллионам пользователей: приставка должна исполнять только подписанный код, на ней можно играть только в легально приобретенные (и лицензионные) игры, и только «официальными» аксессуарами. В некоторых странах, взлом собственной приставки является нарушением закона.
В тоже время большое количество используемых производителями консолей способов защиты является вызовом для энтузиастов в области информационной безопасности. Особенно, если они любят видеоигры. В конце концов, чем сложнее задача, тем интересней ее решить.
Защита геймпада DualShock 4
Те читатели, которые следят за моим аккаунтом в Twitter, знают, что я давно увлекаюсь игровыми приставками, их реверсом, а также всем, что связано с консолями, в том числе, неофициальными игровыми устройствами. В первые дни существования PlayStation 4 публично известная уязвимость в ядре FreeBSD, на котором основано ядро этой приставки, позволила мне (и многим другим исследователям) приобщиться к архитектуре и принципам работы консоли Sony. Я провел множество исследований, в том числе, изучил принципы аутентификации игровой периферии и то, как PS4 отличает лицензированные устройства от нелегальных. Ранее я проводил подобные исследования других приставок, и авторизация периферийных устройств у PS4 оказалась хоть и проще чем у Xbox 360, но не менее эффективна.
PS4 посылает 0x100 случайных данных, в ответ на которые DualShock 4 генерирует подпись RSASSA-PSS SHA-256 и присылает её вместе с криптографическими константами N и E (публичный ключ), которые нужны для верификации этой подписи. Эти константы уникальны для каждого выпущенного геймпада. Также геймпад посылает подпись для верификации N и E, алгоритм тот же — RSASSA-PSS SHA-256, но криптографические константы едины для всех приставок и хранятся в ядре приставки.
Таким образом, чтобы авторизовать свое устройство недостаточно взломать ядро приставки — нужно иметь приватный ключ геймпада. И если кто-то всё-таки взломает геймпад и получит его, то у Sony остается возможность заблокировать ключ с обновлением прошивки. Также, если в течении 8 минут приставка не получает авторизационное сообщение от геймпада, то она прекращает «общение» с ним, и чтобы продолжить использование устройства нужно отключить его от консоли и подключить заново. Симуляция этого процесса очень раздражала владельцев первых нелегальных геймпадов.
Слухи о суперподделке DualShock 4
Схему аутентификации DualShock 4 не могли взломать довольно долго. Но в какой-то момент я услышал, что на рынке появились поддельные геймпады, которые выглядят и работают в точности, как оригинальные. Мне захотелось посмотреть на них своими глазами и, оформив несколько заказов на китайских торговых площадках, я стал ждать.
Время ожидания было решено скрасить поиском подробной информации о подделках. После некоторого количества поисковых запросов, я наткнулся на контроллер Gator Claw.
Интересным в нем было то, что, судя по обсуждению контроллера на Reddit, сначала он работал, как и другие неавторизованные геймпады — по 8 минут, но разработчики смогли это исправить в обновлении прошивки. На сайте магазина была доступна ссылка на файл обновления и руководство по его установке, которые я и скачал.
Основы анализа embedded прошивок
Первым делом я решил взглянуть на секцию ресурсов программы, устанавливающей обновление прошивки и сразу сделал несколько интересных открытий.
Читатели, знакомые с программированием embedded-устройств, наверняка узнают этот формат. Это файловый формат Intel HEX который часто применяется для программирования микроконтроллеров и многие компиляторы, например, GNU Compiler, могут выводить скомпилированную программу в таком формате. Также мы можем видеть, что начало этой прошивки не имеет большой энтропии и последовательности байтов легко различимы, что означает отсутствие шифрования или сжатия. После декодирования Intel HEX стрима и загрузки в редактор (010 Editor умеет открывать файлы прямо в таком формате) мы можем взглянуть на прошивку. Что это за архитектура? ARM Cortex-M настолько распространен что я различаю его с первого взгляда.
Согласно спецификации первое двойное слово — это начальная вершина стека, после него идет таблица прерываний. Первое слово в этой таблице — Reset vector, служащий точкой входа. Также можно сразу обратить внимание на верхнюю часть адресов других обработчиков прерываний, что дает нам представление о базовом адресе прошивки.
Помимо этого, в ресурсах был найден файл конфигурации с описанием различных микроконтроллеров. Скорее всего, разработчики программы для обновления задействовали некий общедоступный код от производителя микроконтроллера и наиболее вероятно, что этот файл конфигурации шел вместе с этим публичным кодом.
После поиска идентификаторов из файла конфигурации мы находим сайт производителя этих микроконтроллеров – Nuvoton. Продуктовая линейка, техническая документация и SDK свободно доступны на сайте, и, более того, для их скачивания не нужно принимать какое-либо соглашение.
Благодаря этому у нас есть прошивка, мы знаем архитектуру и производителя микроконтроллера, у нас есть сведения о базовом адресе, вершине стека и точке входа. Доступной информации более чем достаточно, чтобы загрузить прошивку в IDA Pro и приступить к анализу.
В процессорах ARM поддерживаются два режима исполнения кода с различными инструкциями: ARM (32-битные инструкции) и Thumb (16-битные инструкции, дополненные Thumb-2 32-битными инструкциями). Cortex-M0 поддерживает только режим Thumb, поэтому мы установим переключатель в Processor options – Edit ARM architecture options – Set ARM instructions на NO во время загрузки прошивки.
Мы видим, что прошивка хорошо загрузилась по базовому адресу 0, автоматический анализ распознал практически все функции. И теперь встает вопрос – как правильно анализировать прошивки?
Если изучить эту прошивку, то мы увидим, что она совершает большое количество операций чтения и записи к памяти с базовым адресом 0x40000000. Это базовый адрес где находится память, отведенная под ввод-вывод (memory mapped input output — MMIO). Через эти адреса предоставляется доступ ко всем периферийным компонентам, которые есть у микроконтроллера. Все что делает прошивка происходит через доступ к MMIO-регистрам.
Найдя в документации адрес 0x40000000 мы узнаем, что этот микроконтроллер серии M451. Зная семейство микроконтроллера, можем скачать SDK и образцы кода для этой платформы. Внутри SDK мы находим заголовочный файл с объявлением всех MMIO-адресов, всех битовых полей и структур. Так же мы можем скомпилировать образцы кода и все библиотеки, а затем сравнить их с функциями в нашей IDB, или мы можем просто искать имена MMIO адресов в исходном коде и сравнивать их с нашим ассемблерным кодом. Это превращает процесс обратной разработки прошивки в простой и легкий процесс. Анализ был бы намного сложнее если бы у нас не было информации об архитектуре и модели микроконтроллера, и MMIO-регистрах. К слову, именно поэтому многие производители делятся SDK только после подписи NDA.
Но что по-настоящему заинтересовало меня в этой прошивке — одна неиспользуемая строка с именем крупного производителя электроники (наиболее известного своими логическими анализаторами, но, как оказалось, имеющего и игровое подразделение). Судя по всему, она должны была быть частью USB Device Descriptor, но этот дескриптор не был использован.
В тени гиганта
Мне удалось найти магазин с огромным ассортиментом игровых аксессуаров, продаваемых под единой торговой маркой. Среди продаваемых аксессуаров числились два десятка различных адаптеров для подключения геймпадов одной приставки к другой. К примеру, отдельный продукт для подключения геймпада Xbox 360 к приставке PS4, отдельный продукт для подключения геймпада PS3 к приставке Xbox One, и многие другие, включая «все в одном». Также ассортимент продукции включает адаптеры для подключения клавиатуры и мыши к консолям PS4, Xbox One и Nintendo Switch, различные игровые геймпады и печатные платы для создания своих аркадных контроллеров для приставок. Все продукты шли с обновлениями, аналогичными тому, которое шло с Gator Claw, но с существенным отличием – все прошивки были зашифрованы.
Теперь попробуем найти фотографии печатных плат аркадных контроллеров, что позволит оценить схему устройства, не покупая и не разбирая его. Скорее всего их дизайн идентичен дизайну Gator Claw. На найденных фотографиях мы можем видеть два микроконтроллера: один из них должен быть Nuvoton M451, а другой – вспомогательный, для секретов: производители понимают, что конкуренты могут изучить их прошивку, и чтобы предотвратить это используют второй микроконтроллер. Забегая вперед, скажу, что в нашем случае он тоже присутствовал. Данные для аутентификации передаются в него по протоколу I2C и после получения отправляются обратно на приставку.
Поскольку все дорожки идут к микроконтроллеру под черной эпоксидной смолой, мы можем заключить, что это главный микроконтроллер. А микроконтроллер с четырьмя желтыми ножками соответствует требованиям для работы по протоколу I2C и является вспомогательным.
Внутри контроллера
К этому моменту я наконец получил посылку из Шэньчжэня, и надо сказать, что контрафактный гаджет очень сложно отличить от оригинального DualShock 4: геймпад выполнен из качественных материалов, touchpad работает, динамик и гарнитура тоже.
С помощью комбинации клавиш из инструкции я проверил, что геймпад переходит в DFU-режим, и приступил к разборке. Отмечу, что при этом на ПК геймпад определился как другое устройство, с иными идентификаторами и характеристиками.
Я припаял провода к отладочным площадкам и подключил программатор. Программатор определил устройство, но security lock был установлен.
Метод взлома прошивок USB-устройств
Дизайн USB-протокола определяет две сущности — хост и остальные устройства, которые подключаются к нему. Они, в свою очередь, разделяются на классы: hub, human interface, printer, imaging, mass storage device и другие.
Общение между устройствами и хостом происходит посредством односторонних и двухсторонних каналов. Под каналом мы подразумеваем передачу данных между программой на хосте и конкретным «конечной точкой» на устройстве. Таких точек может быть несколько для передачи различных данных.
Существует четыре типа передачи данных:
- Control Transfers (используется для конфигурации)
- Bulk Data Transfers (большие количества последовательных данных)
- Interrupt Data Transfers (используются для своевременной и точной передачи данных)
- Isochronous Data Transfers (беспрерывный поток данных)
Все USB-устройства должны иметь особый канал на нулевой конечной точке, зарезервированный для конфигурации устройства.
Эти типы передачи данных осуществляются посредством пакетов, представленных на рисунке ниже:
По факту, USB-протокол — это машина состояния, и в этой статье мы не будем останавливаться на каждом из этих пакетов. Ниже представлен пример осуществления Control Transfer:
Устройства могут содержать уязвимости в каждом из четырех типов передачи данных, но эти типы опциональны, к тому же их наличие и применение будет сильно отличаться от устройства к устройству. Но все устройства поддерживают Control Transfers и формат, по большей части, един для всех устройств, что делает данный тип передачи данных наиболее интересным для анализа на наличие уязвимостей.
Диаграмма ниже изображает формат SETUP-пакета, который используется для выполнения Control Transfer.
SETUP-пакет занимает 8 байт и может предоставлять различные данные в зависимости от типа запроса. Некоторые из них едины для всех устройств (например, дескрипторы), другие зависят от класса устройства или желания производителя. Размер передаваемых/получаемых данных задается 16-битным словом и также передается в SETUP-пакете.
Подводя итог: Control Transfers используют простой протокол, поддерживаемый всеми USB-устройствами, которые могут иметь множество дополнительных команд, и мы контролируем размер данных. Все это делает Control Transfers идеальной целью для фаззинга и глитчинга.
Эксплуатация
Для взлома поддельного геймпада мне не пришлось прибегать к фаззингу т.к. я нашел баги еще во время просмотра кода прошивки Gator Claw.
Функция HID_ClassRequest() написана для симуляции работы оригинального геймпада DualShock 4, и поддерживает минимум необходимых запросов для работы с приставкой PlayStation 4. USBD_GetSetupPacket() получает SETUP-пакет и в зависимости от типа переданного репорта либо получит, либо отправит данные функциями USBD_PrepareCntrlIn() и USBD_PrepareCntrlOut(). Как можно заметить, запрошенный размер данных не проверяется и это должно дать нам возможность читать часть внутренней памяти, где хранится прошивка, а также читать и писать в начало SRAM-памяти.
Размер DATA-пакета задается в USB Device Descriptor (который также получается с помощью Control Transfer) но, похоже, что остается не учтен тот факт, что этот размер указывает на размер одного пакета, а их может быть сколько угодно в зависимости от размера, заданного в SETUP-пакете.
Примечательно, что образцы кода, размещенные на сайте Nuvoton, также не содержат проверок на размер и могут привести к большему количеству багов в различных проектах из-за копирования этого кода.
SRAM (Static random access memory) — это оперативная память, в которой помимо прочего находится стек. Очень часто SRAM также является исполняемой памятью (настраивается), обычно это делается для улучшения производительности – основная прошивка может скопировать в SRAM часто вызываемый код, например, код Real-Time Operating System. Нет гарантий, что вершина стека будет находиться в достижимых пределах переполнения буфера, но вероятность этого велика.
Неожиданно, но главным препятствием на пути к эксплуатации уязвимостей в прошивках USB-устройств являются операционные системы. Нижеперечисленное характерно для Windows, но думаю, что актуально и для Linux-based систем без специальных исправлений.
Во-первых, ОС не позволяет прочесть больше 4 килобайт во время передачи данных 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 без каких-либо вмешательств со стороны операционной системы.
Поддельный геймпад содержал те же уязвимости что и Gator Claw, и первое что я сделал — «сдампил» часть прошивки.
Для нахождения базового адреса дампа нашей прошивки достаточно найти структуру с указателями на известные данные. После этого мы можем посчитать дельту и загрузить полученную часть прошивки в IDA Pro.
Дамп прошивки позволил нам узнать адрес функции printf(), которая выводит в UART информацию, необходимую для контроля качества. Также анализ дампа позволили найти аналог функции hexdump(), что полностью освобождает нас от необходимости написания шеллкода.
После нахождения контактов UART на плате геймпада, припаивания проводов и подключения их к TTL2USB адаптеру мы видим вывод в терминале.
Стандартная библиотека для микроконтроллеров Nuvoton идет с очень удобным обработчиком Hard Fault исключений, который выводит дамп регистров. Это сильно облегчает эксплуатацию и позволяет отлаживать эксплойт.
Финальный эксплойт для дампа прошивки:
Но этот способ дампа нельзя считать полноценным, поскольку серия микроконтроллеров Nuvoton M451 позволяет использовать две различные прошивки: основную (APROM) и мини-прошивку для DFU-обновлений (LDROM).
Эти прошивки транслируются на одни и те же адреса памяти, поэтому в зависимости от текущего режима можно прочесть только одну из них. Для того, чтобы получить дамп прошивки LDROM, нам нужно отключить security lock и прочитать Flash-память с помощью программатора.
Криптофейл
Изучение прошивки обновлений (LDROM) показало, что это стандартный код от Nuvoton, но с добавленным шифрованием обновлений прошивок.
Шифрование представляет собой кастомный блочный алгоритм, выполненный в режиме сцепления блоков шифротекста, длина которых составляет всего 32 бита. В этот алгоритм предоставляются ключ, который является текстовым (ASCII) идентификатором продукта, и массив инструкций, которые определяют, какое преобразование сделать с текущим блоком. После достижения конца ключа и массива, их позиция устанавливается на начальную. Список преобразований включает в себя шесть операций: xor, subtraction, subtraction (reverse), и повтор этих преобразований с переустановкой байт. Так как в прошивках присутствуют большие области, состоящие из нулевых байт, это позволяет с легкостью посчитать секретные составляющие этого алгоритма.
Применение алгоритма, извлеченного из прошивки контрафактного геймпада, ко всем прошивкам аксессуаров, доступных на сайте OEM-производителя, показало, что они все используют этот алгоритм шифрования. Это позволяет высчитать ключи шифрования для всех устройств и расшифровать все представленные прошивки. Таким образом, алгоритм, вложенный в контрафактный продукт поставил под угрозу безопасность всех продуктов производителя.
Заключение
Пост получился очень большим, но я хотел подготовить его для наиболее широкой аудитории. В этой статье я продемонстрировал полный процесс анализа embedded-прошивок, поиска и эксплуатации уязвимости для получения дампа, исполнения произвольного кода на USB-устройстве. Хоть глитчинг-атаки не вошли в статью, они тоже очень эффективны при взломе USB-устройств. Для желающих узнать об этом больше рекомендую ознакомиться с этим видео. А тем, кто задался вопросом, как пираты получили ключи и алогритм из DualShock 4, советую почитать этот материал.
Что касается тайны со вспомогательным микроконтроллером, то оказалось, что, во-первых, он присутствует не во всех устройствах, а во-вторых, добавлен всего лишь для запутывания и не хранит никаких секретов, выполняя лишь операции SHA1 и SHA256. Контроллер Nuvoton M451, может быть объектом для дальнейших исследований т.к. во время этого исследования он продемонстрировал некоторые признаки, которые могут свидетельствовать о наличии архитектурных уязвимостей.
Покупателей контрафактных геймпадов не ждет ничего хорошего: Sony заблокирует нелегально используемые ключи, и пользователи останутся без рабочего контроллера.
Взлом прошивок USB-устройств
Борис
Здравствуйте.
Интересная статья.
Опыт в области USB особенно.
У меня есть желание оживить gsm камеру, которую дилер не поддерживает.
Устройство 2011 г. в.
Можете удалённо по сети , это попробовать сделать, используя удалённый рабочий стол?
Securelist
Добрый день!
Мы не занимаемся техподдержкой и ремонтом техники. С этим вопросом стоит обратиться в сервисный центр, который обслуживает разных поставщиков.