[Перевод] Взлом ШГУ Hyundai Tucson
Вторая часть истории о том, как можно взломать официальную прошивку Hyundai Tucson 2020 года выпуска и напичкать её чем-нибудь не очень полезным. Начало можно прочитать тут.
Ранее вы узнали, как можно взломать официальную прошивку Hyundai Tucson 2020 и провести её реинжиниринг. Тогда мне казалось, что можно просто модифицировать файл с обновлениями, снова заархивировать его с тем же паролем и запихнуть в машину. Оказалось, что всё не так просто.
Пакет обновлений подписывается ключом RSA, соответствующим сертификату daudio.x509.pem
, и эта подпись проверяется во время обновления. Это часть процесса обновления Android OTA, который используется для обновления прошивки всего устройства (не только автомобильной навигации). В отличие от RSA ключа для Ioniq 2021, этот ключ нельзя найти в сети (по крайней мере, я его не нашёл).
Как в таком случае получить доступ к ШГУ (штатному головному устройству)? Я рассматривал два варианта:
найти уязвимость в одном из приложений;
найти уязвимость в ядре Linux. ШГУ работает под управлением Linux 3.1.10, так что это реальный вектор атаки.
Увы, ничего не получилось. Но я нашёл новую информацию, которая позволила мне рутировать ШГУ.
Новые идеи
Я узнал, что Hyundai поставляет одну и ту же прошивку на разные автомобили. В моей машине была так называемая «Standard-class Gen5 navigation», которая выглядит так:
Хотя в названии фигурирует слово «навигация», по факту это прошивка для всего головного устройства. Одна и та же прошивка поставляется на разные модели Hyundai, KIA и Genesis, выпущенные в период с 2018 по 2021 год.
Головное устройство работает на SoC Telechips TCC893X, а его SDK просочился в интернет. Существует секретный механизм запуска рекавери. Для этого нужно зажать кнопку POWER (это ручка слева) и кнопку MAP при запуске:
Я попробовал это на своём автомобиле, и на экране появилась вот такая ошибка:
Очевидно, что для запуска рекавери необходимы какие-то зашифрованные файлы на USB-носителе. Простой grep этих строк приводит к lk.rom
файлу из пакета обновлений, который я до сих пор игнорировал. Давайте загрузим его в Ghidra и посмотрим, что произойдёт.
Реверс lk.rom
LK означает «little kernel», небольшое ядро с открытым исходным кодом, которое используется во многих встраиваемых платформах. ШГУ загружает lk.rom с адреса 0×82000000. Установив правильный начальный адрес в Ghidra, мы можем задействовать printf и получить много полезной отладочной информации. Проверка »[DEBUG] U-Boot Recovery Button pushed .... \n
» приводит к:
Похоже, что рекавери является частью u-boot, а его точкой входа является функция 0x820589a8
:
Обратите внимание на строку 14. Из неё мы можем сделать вывод, что эта функция копирует код u-boot 0x80000000
и запускает его. PTR_DAT_82058a38
начало u-boot, а PTR_DAT_82058a3c —
адрес конца прошивки:
Используя эту информацию, мы можем извлечь код u-boot lk.rom
с помощью следующей команды:
$ dd if=lk.rom skip=$((0x1055c)) count=$((0x57894-0x1055c)) bs=1 of=uboot.rom
А затем проанализируем uboot.rom как отдельный бинарник с начальным адресом 0×80000000 в Ghidra.
Реверс uboot.rom (часть lk.rom)
Океюшки, мы видим много отладочных строк, которые помогают понять, что происходит. Рекавери ищет следующие файлы на USB-носителе:
security_force/encrypt_lk.rom
security_force/encrypt_boot.img
security_force/encrypt_system.img
security_force/encrypt_recovery.img
security_force/encrypt_splash.img
security_force/encrypt_partition.dat
Существует также security_force/file_info
, который содержит имя, размер и контрольную сумму CRC32 для каждого из перечисленных выше файлов. Эти файлы (за исключением encrypt_partition.data
) соответствуют файлам, которые мы нашли в пакете обновления:
Они должны быть зашифрованы по алгоритму AES-128-CBC, ключами =»)1Zorxo^fAhGlh$#» и IV=«aoAkfwk+#1.6G{dE». Только system.ext4
должен быть преобразован в sparse-образ перед шифрованием.
Патчим system.ext4
Если предположить, что при помощи рекавери мы можем прошить всё, что захотим, каким будет минимальный патч для официальной прошивки, который даст нам хоть какой-то доступ к ШГУ? При поиске уязвимостей в стандартных приложениях я обнаружил скрытое инженерное меню, которое включает ADB:
Флаг mDispAdb
можно переключить, если нажать 5 раз в правом нижнем углу 3-й страницы «Информация о модуле» (Module Info). Но если присутствует ADB_HIDE_FEATURE
, этот флаг игнорируется, и видимость всегда устанавливается равной 8, что означает GONE. Функция ADB_HIDE
установлена по умолчанию, как видно из system.ext4:
$ cat /tmp/car/etc/permissions/com.hkmc.software.engineermode.adb_hide.xml
Что ж, давайте удалим эту фичу, создадим файл рекавери и запихнём в машину.
Да, это сработало! С помощью этого простого изменения мы успешно включили ADB на Kia Stinger 2020 и подключились к нему через USB.
Получение root shell
Теперь, когда у нас есть оболочка ADB, как получить root? Оказывается, в стоковой прошивке есть удобный setuid-бинарник под названием «amossu»:
$ ls -la bin/amossu
-rwsr-sr-x 1 root root 37216 Oct 6 08:29 bin/amossu
Работает он просто
setgid(0);
setuid(0);
execv("/system/bin/sh",__argv);
Инструменты
Я выложил здесь программу и инструкции по созданию кастомных прошивок для автомобилей с прошивкой Gen5. На данный момент весь процесс успешно протестирован на Kia Stringer 2020.
Последние мысли
Я надеюсь, что этот хак позволит создать несколько интересных модов для автомобилей. Например, мне хотелось бы увидеть приложение, которое записывает видеопоток с камеры автомобиля и сохраняет его на флешке. Разумеется, моей конечной целью остаётся запуск Doom на экране ШГУ. Так что я не прощаюсь :).
Если у вас есть комментарии или отзывы, вы можете оставить их на Github.