Автомобильные сигнализации РФ и их безопасность. Часть 1

Автомобильные сигнализации РФ и их безопасность. Часть 1

Всем привет. В этот раз я решил затронуть тему безопасности устройств, которыми пользуются большинство автовладельцев. Речь пойдёт о трёх самых популярных автомобильных сигнализациях (иммобилайзерах), представленных на российском рынке.

Забегая вперёд, скажу, что отчёты обо всех найденных недостатках были направлены производителям, а также во ФСТЭК России. Из ответа регулятора я узнал, что в качестве уязвимостей отчёты зарегистрированы не будут, так как « данное программно-аппаратное средство не используется на объектах ГИС и КИИ ». Производители же сообщили, что описанные недостатки устранят в новых моделях сигнализаций. За информацией о том, что делать с уже существующими моделями, я рекомендую обращаться к производителям.

О проекте

Исследования проводились с большим разбросом по времени. Первое я выполнил в конце 2022 года, два других — в 2024-м, с небольшим интервалом. Целью проекта был вовсе не поиск уязвимостей, а простой азарт: если что-то зашифровано, я хочу это расшифровать. Опыт получился достаточно интересный. О нём — в этой статье.

О первом исследованном устройстве

Что меня радует в моей работе, так это возможность уделять время собственным ресёрчам. Так, в поисках подопытного я решил посмотреть содержимое одной коробочки, которая лежала на полке с артефактами от предыдущих проектов. Описание на ней гласило: « Охранно-противоугонная микросигнализация — CAN иммобилайзер PANDECT X-1000 BT », а внутри коробки лежали какие-то проводки, инструкция, кнопка на шлейфе, основной модуль сигнализации, а также брелок и « верещалка ».

Первым делом нужно понять, что искать и куда копать. И проще всего начать с… запуска сигналки. А точнее — с банальной её настройки и подключения к ПК и смартфону. Читаю инструкцию, устанавливаю соответствующие приложения, втыкаю USB-шнурок и, конечно же, не забываю для всего этого добра собрать USB-трафик с помощью Wireshark для последующего анализа.

Так, например, одним из потенциальных векторов исследования может быть процесс обновления устройства по USB. По идее, если мне удастся разобраться, как он происходит, и найти в нём недостатки, я смогу самостоятельно формировать файлы обновления и загружать их в сигнализацию.

Процесс обновления

По утверждению Wireshark, подключенное USB-устройство распознаётся как HID, а всё общение в трафике выглядит как набор пакетов GET_REPORT / SET_REPORT . Если присмотреться к содержимому одного из первых пакетов, можно заметить, что отправляются байтики, идентичные байтам в хедере файла прошивки (его я нашёл на официальном сайте производителя). Почему я решил, что это именно хедер? Раз уж содержимое идёт отдельным пакетом, имеет совпадения с началом файла и содержит строку версии — это точно хедер!

Как можно заметить, начиная со следующего пакета отправляется уже само зашифрованное содержимое прошивки (тело) — по 64 байта (ограничение HID?). Можно ли уже попробовать что-то сделать, обладая этими знаниями?

Я решил поменять один единственный бит где-нибудь в хедере прошивки, не отправляя всё остальное (либо, если нужно, отправить первый блок тела), и посмотреть, что будет. Результат — ПО сигнализации перестало видеть устройство, хотя сам USB-девайс появляется, да и лампочки на сигналке говорят о том, что она что-то да запускает. Значит, нужно понять, что именно идёт не так и почему ПО перестало «видеть». Нормальный человек изучил бы USB-трафик, а я зачем-то полез изучать саму утилиту.

Утилита от производителя

Беглое изучение программы показало следующее:

Она точно использует JS.

Она точно использует JS.

Скомпилирована с использованием Awesomium SDK.

Скомпилирована с использованием Awesomium SDK.

Не содержит строк в читаемом виде.

Не содержит строк в читаемом виде.

Файл data.asr на деле оказывается запароленным ZIP-архивом.

Файл data.asr на деле оказывается запароленным ZIP-архивом.

Без отладки не разобраться.

Без отладки не разобраться.

После непродолжительной отладки приложения мне удалось выяснить пароль от архива: aoeuiqjkxb . Далее я добавил в js-файл (уже не помню какой) строчку, которая помогла бы понять различия между двумя сигналками: почти окирпиченной и нормальной.

Результат такой отладки показал различия в поле версии. В одном случае содержимое поля version было нормальным, а в другом — нечитаемым. Исходя из этого можно сделать следующие выводы:

Содержимое USB-пакета с модифицированным хедером сразу же записалось во внутреннюю память устройства.

Содержимое USB-пакета с модифицированным хедером сразу же записалось во внутреннюю память устройства.

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

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

Для дальнейших экспериментов мне хотелось восстановить работу сигналки, поэтому я поставил бряк на выход из ReadFile() и просто подменил нужные байтики в lpBuffer на корректные. Благодаря этому мне удалось запустить процесс обновления целиком и прошить нормальный хедер заново, после чего сигнализация ожила.

Продолжаем обновляться

Если позволить процессу обновления отработать полностью, при этом оставив модифицированный бит в заголовке, можно выяснить: какой бы ни была контрольная сумма (цифровая подпись), она проверяется в самом конце, после отправки всех байт. Об этом будет свидетельствовать сообщение об ошибке в программе (извините, но скрин у меня не сохранился за давностью лет).

Можно ли теперь собрать все полученные знания в скрипт и заменить прошивку сигнализации на свою? К сожалению, пока ещё нет. Играть в « раскирпичь меня » после каждой попытки мне не очень-то хотелось. Поэтому было решено наконец-таки разобрать девайс и посмотреть, что можно сделать, обладая, так сказать, некоторыми навыками пайки .

Внутренний мир

В основном блоке сигнализации обнаружились чипы с собственной прошивкой:

STM32 (уже не помню, какая именно).

STM32 (уже не помню, какая именно).

nRF52832 (основной модуль).

nRF52832 (основной модуль).

nRF51822 (брелок).

nRF51822 (брелок).

Также на основном модуле легко нашлись две гребёнки по пять выводов каждая: одна ближе к STM32, вторая — к nRF52. Прозвонка показала, что два вывода из пяти — земля и питание на обоих группах контактов. Остальные же (не помню почему, но, возможно, потому что на тот момент контакты чипов были жутко мелкими для меня) я не стал вызванивать, а сразу решил, что это SWD. В результате непродолжительного перебора различных вариантов так оно и оказалось.

Подключившись отладчиком JLink к STM32, мне удалось выяснить, что внутренняя память чипа не читается, а вот SRAM читать можно — это говорит о включенном режиме RDP1. В принципе, с этим уже можно работать. Идея была такая:

Запускаю режим обновления прошивки.

Запускаю режим обновления прошивки.

Отправляю первый блок.

Отправляю первый блок.

Подключаю отладчиком.

Подключаю отладчиком.

Читаю SRAM в файл dump1.bin .

Читаю SRAM в файл dump1.bin .

Отправляю второй блок.

Отправляю второй блок.

Читаю SRAM в файл dump2.bin .

Читаю SRAM в файл dump2.bin .

Сравниваю файлы и ищу закономерности.

Сравниваю файлы и ищу закономерности.

С этой последовательностью возникла проблема: после подключения отладчиком сигнализация не смогла принимать USB-пакеты — это связано с работой режима RDP1 , не позволяющего делать полноценную «паузу» на STM32. Пришлось адаптировать алгоритм: на этапе отправки второго блока сначала перезагружать устройство, отправлять первый блок, затем второй и уже после этого читать SRAM.

Чтобы автоматизировать процесс, я попросил коллегу написать небольшой «дропер» питания на Arduino, который бы ожидал на одном из GPIO-пинов команду ресета и при помощи MAX4619 (переключатель) на некоторое время обрывал линию 5V на USB-шнурке.

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

К сожалению, замеры продолжительности одной итерации, вкупе с арифметической прогрессией времени загрузки каждого последующего блока (напомню, что каждый новый блок требовал загрузки всех предыдущих), показали удручающую картину: на всю прошивку уйдёт месяца три, а на тысячу блоков — примерно неделя. Цифры приблизительные — за давностью проекта уже не смогу сказать точнее. Тем не менее с этим нужно было что-то делать.

К счастью, на полках с артефактами обнаружились ещё две сигнализации этой модели (итого — три). К тому же у нас на работе было целых два J-Link, и один EDU я притащил из дома. Что ещё может понадобиться для качественной автоматизации, кроме трёх препарированных USB-кабелей, как вы думаете?

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

После отладки этой конструкции я оставил её работать на целую неделю… Так думал я, пока не пришёл на работу на следующий день. Там меня ожидал сюрприз: окошко JLink с предложением принять условия использования EDU-версии. Многие, кто работают с этим отладчиком, видят окно постоянно, но наверняка, как и я, абсолютно машинально нажимают кнопку Accept и забывают о нём. Как оказалось, сам JLink вспоминает о нём ровно в полночь. Как я это обходил — отдельный вопрос и, пожалуй, не стоящий упоминания в этой статье.

Какие-то успехи

Спустя несколько дней набралось достаточно дампов SRAM, чтобы обнаружить и атрибутировать в них:

зашифрованные 8 байт текущего блока,

зашифрованные 8 байт текущего блока,

8 байт XOR-ключа для этого блока,

8 байт XOR-ключа для этого блока,

расшифрованные 8 байт.

расшифрованные 8 байт.

Таким образом, если набрать достаточное количество байт XOR-ключа для первых N-байт прошивки, можно зашифровать ими свою собственную, которая, например, блок за блоком сдампит туда же в SRAM содержимое загрузчика (который, предположительно, будет содержать и алгоритм шифрования целиком). Сказано — сделано! Детали будут в конце статьи, а пока перейдём ко второму чипу на плате сигнализации — nRF52.

nRF52 и nRF51

На момент работы над проектом у меня, к сожалению, не было опыта с глитчами по питанию (fault injection), а вот у моего коллеги, к счастью, он был. Поэтому с его помощью, а также опираясь на публично доступную статью с описанием уязвимости в чипе nRF52 (Wayback Machine), я получил на руки полный дамп прошивки беспроводной части сигнализации.

Что касается брелока: в нём установлен похожий чип nRF51, который не требует таких продвинутых техник обхода защиты. Ну и, конечно же, статья о том, как сдампить с него прошивку (Wayback Machine).

Вместо выводов

Алгоритмом, который использовался для шифрования прошивки, оказался ГОСТ 28147-89. Благодаря возможности пошагово получать содержимое SRAM и некорректному использованию алгоритма (промежуточные результаты работы оставались в памяти) мне удалось полностью восстановить прошивку основного блока и изучить механизм его обновления по USB. А ещё я написал скрипт, который позволяет полностью расшифровывать файлы обновлений и шифровать их обратно.

Взаимодействие с производителем

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

Что мы получаем в итоге:

Алгоритм шифрования ГОСТ используется некорректно (в памяти остаются следы применяемого ключа).

Алгоритм шифрования ГОСТ используется некорректно (в памяти остаются следы применяемого ключа).

Проверка подписи файлов не реализована.

Проверка подписи файлов не реализована.

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

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

P. S. Спасибо за внимание. Скоро опубликую статью о следующем производителе автомобильных сигнализаций — Starline. Остаёмся на связи!

← Cybersecurity