Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
ch55x_firmware_extractor — Экстрактор прошивки для микропроцессоров CH55x | Kitploit
Инструменты/GitHubGitHub/finngineering/ch55x_firmware_extractor
Безопасность встроенных системЭксплуатацияОбратная инженерияАппаратный ХакингАппаратная БезопасностьБезопасность оборудования и IoTАнализ Прошивок
GitHubfinngineering/ch55x_firmware_extractor

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

ch55x_firmware_extractor

Экстрактор прошивки для микропроцессоров CH55x

Репозиторий
128 месяцев назадЕщё не проверено

CH55x экстрактор прошивки

Экстрактор прошивки CH55x используется для чтения прошивки из интегральных схем CH55x. В устройствах нет встроенной поддержки для прямого чтения прошивки через загрузчик. Однако существует функция проверки содержимого прошивки по 8 байт за раз с предоставленными данными. Эта функция уязвима для классической атаки по времени, что и используется здесь для извлечения прошивки из этих устройств. Загрузчик можно получить через USB или UART. Этот экстрактор прошивки работает только через UART, потому что более высокая задержка USB сделала бы эту атаку сложной. Протестированные чипы: CH552 и CH554, версии загрузчика 2.4 и 2.5. Аппаратное решение для экстрактора прошивки основано на STM32 Blue Pill, поскольку они доступны, дешевы и обладают необходимой производительностью.

Анатомия эксплойта

Загрузчик ранее был прочитан из устройства, а его протокол связи был восстановлен. Ниже приведена приблизительно правильная команда проверки и функция проверки, используемая в загрузчике. Существуют некоторые ограничения, которые требуют, чтобы длина была кратна 8, адрес был выровнен по границе 8 байт, адрес был меньше 0x3800 и чтобы не было предыдущих ошибок проверки. Последнее ограничение означает, что после каждой неудачной проверки требуется перезапуск CH55x.

Мы видим, что функция проверки возвращается немедленно, если один байт проверки неверен. Это означает, что чем больше байтов верны, тем дольше будет выполняться функция проверки. Это классический пример атаки по времени, которую можно использовать.

root@kitploit:~
unsigned char verifycmd[] = {
//  0x57, 0xab, // UART magic not included to verify function
    0xa6,       // Verify command
    5 + len,    // Constant 5 plus length of data to verify
    0,          // Unused
    addr_low,   // Low byte of address
    addr_high,  // High byte of address
    0, 0, 0,    // Unused
    0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, // Data to verify against
    checksum
}

unsigned char verify(unsignec char *cmdbuffer)
{
    static char prev_verify_error;

    unsigned char len = cmdbuffer[1]-5
    unsigned short addr = cmdbuffer[3] + cmdbuffer[4] << 8;
    if (len & 0x07 || addr & 0x07 || addr > 0x3800 || prev_verify_error) {
        return 0xfe;
    }

    for (int i=0; i < len; i++) {
        // Key can be set through bootloader, and CBYTE[] means code memory
        if(key[i & 0x07] ^ cmdbuffer[8+i] ^ CBYTE[addr+i]) {
            prev_verify_error = 1;
            return 0xf5;
        }
    }
    return 0;
}

Путем проб и ошибок мы обнаружили, что каждый правильный байт увеличивает время выполнения функции проверки примерно на 4,2 мкс. Скорость передачи, используемая загрузчиком для связи UART, равна 57600 (независимо от того, что вы прочитаете в других местах), что означает, что передача одного бита занимает примерно 17,4 мкс. Соотношение между этими двумя временами важно, потому что, похоже, ответ отправляется с джиттером также около 17 мкс. Затем мы пытаемся различить ответы, время отклика которых отличается на 4,2 мкс от функции проверки, но может отличаться до 17 мкс из-за джиттера UART (тактовой синхронизации). Это кажется сложной задачей, но её можно решить с помощью статистических методов.

Мы можем определить, был ли байт правильным или нет, попробовав проверить его несколько раз и записывая результаты. Скажем, например, что минимально возможное время получения ответа, если первый байт неверен, составляет 30 мкс. Тогда с учетом джиттера UART мы можем ожидать максимальное время ответа 30 мкс + 17,4 мкс = 47,4 мкс для неверного первого байта. В то же время, верный первый байт и неверный второй байт сдвинут этот «диапазон» до 34,2 мкс – 51,6 мкс. Добавив некоторые запасы, мы можем заключить, что первый символ был неверным, если время ответа меньше ~33 мкс. Аналогично, мы можем сказать, что первый символ был верным, если время ответа больше 48 мкс. Это основа атаки по времени, используемой для извлечения прошивки.

Использование экстрактора прошивки

Это не полностью автоматический инструмент для извлечения прошивки — потребуется модификация исходного кода и перекомпиляция (с использованием VS Code и PlatformIO). Основная причина в том, что точные временные характеристики для каждого байта различаются в зависимости от конфигурации и требуют настройки. Процесс настройки можно было бы автоматизировать, но это не было целью данного проекта. Основная настройка выполняется через переменную prober_limits. Например, prober_limits[0] содержит ограничения для байта 0 из 8 проверяемых байтов. Если время ответа меньше .invalid_under_time, мы знаем, что байт был неверным. Если оно больше .valid_over_time, мы знаем, что байт правильный. Также есть .min_delta, позволяющий перейти к следующему байту до того, как мы точно узнаем, правильный байт или нет.

root@kitploit:~
struct ProberByteLimits prober_limits[8] = {
    {
        // Byte 0
        .invalid_under_time = 33,
        .valid_over_time = 50,
        .min_delta = 30
    }, // ...

Чтобы найти подходящие значения, рекомендуется установить .invalid_under_time в 0, .valid_over_time в, например, 100, а .min_delta можно оставить равным 30. Это означает, что пробник не сможет найти первый правильный байт, но прогресс будет выводиться на UART хост-ПК. Вы увидите что-то вроде:

root@kitploit:~
[0x0000]=0x01? min=31 max=47 tries=63
               min=31 max=48 tries=127
               min=31 max=48 tries=191
               min=30 max=48 tries=255
               min=30 max=48 tries=319

При условии, что первый проверяемый символ неверен, мы можем использовать эти минимальные/максимальные значения со смещением 1 или 2, чтобы определить подходящие ограничения. Например, выше мы могли бы установить .invalid_under_time в 33 и .valid_over_time в 50. Затем пробник будет пробовать разные значения, пока не найдет правильное, что будет выглядеть примерно так:

root@kitploit:~
...
[0x0000]=0x7d? min=31 max=39 tries= 7
[0x0000]=0x02? min=40 max=56 tries= 7
[0x0001]=0x01? min=35 max=52 tries=34

Мы видим, что последняя попытка по адресу 0x0000 имела максимальное время ответа 56 мкс, что означает, что это был правильный байт. Затем пробник переходит к следующему байту и продолжает процесс. Обратите внимание, что все 8 ограничений для байтов должны быть настроены отдельно, но после настройки они будут работать для всей памяти. Когда будут найдены 8 правильных байтов, они будут выведены в формате ihex:

root@kitploit:~
:0800000002002932ffffffff9f

Запись вывода UART в текстовый файл позволяет использовать grep для ^:, чтобы извлечь полное содержимое памяти в формате ihex.

Схема

Пример схемы для извлечения прошивки показан ниже. Два транзистора позволяют отключать питание CH55x от Blue Pill. Это рекомендуется по сравнению с использованием только программного сброса, поскольку программный сброс работает только когда CH55x находится в режиме загрузчика (а загрузчик имеет тайм-аут, после которого запускает код приложения). Резисторы на UART к CH55x включены, потому что есть подозрение, что внутренние подтягивающие резисторы на CH55x могут запитывать его от UART даже при отключенном питании. Резистор 10 кОм между V33 и P3.6 необходим для перевода CH55x в режим загрузчика. На Blue Pill вывод PA11 подключен к выводу RX UART, чтобы иметь возможность измерять время ответа с помощью таймера 1.

Схема экстрактора прошивки CH55x

Заключение

С помощью настройки и использования этого инструмента можно извлечь прошивку устройств CH55X. Процесс извлечения не быстрый, но позволяет извлечь 14 кб за один-два дня. Это немного зависит от настройки и того, насколько хорошо используемая таблица частот соответствует реальному ассемблеру прошивки. К сожалению, исходный код немного запутан. Я создал этот инструмент, потому что мне понадобилась прошивка от устройства CH554, и теперь, когда я её получил, нет реальной причины дорабатывать сам инструмент. Тем не менее, он должен оказаться полезным, если кому-то понадобится извлечь прошивку из устройств CH55x.

Скачать инструмент