[Перевод] Как я хакнул свой автомобиль

image


Прошлым летом я купил Hyundai Ioniq SEL 2021 года. Это хороший экономящий топливо гибрид с приличным набором функций: беспроводные Android Auto/Apple CarPlay, беспроводная зарядка для телефона, сиденья с подогревом и люк в крыше.

Особенно мне понравилась в этой машине система In-Vehicle Infotainment (IVI). Как я говорил ранее, у машины есть беспроводное Android Auto, что довольно редко для такого ценового диапазона. Приложение имеет красивые плавные анимации меню, поэтому я понял, что ЦП/GPU не такие уж и слабые; или, по крайней мере, ПО ест не слишком много ресурсов.

Как и со всеми остальными моими гаджетами, я решил немного поэкспериментировать и посмотреть, что можно сделать с этой системой.


IVI в автомобиле, как и многие другие системы в наши дни — это просто компьютер. Моя цель заключается в том, чтобы хакнуть IVI для получения root-доступа и попробовать запустить на ней собственное ПО. Разумеется, первым этапом взлома устройства является исследование.

Я искал ответы на следующие вопросы:

  • Что работает в этом устройстве?
    • Существует две версии IVI: для навигации, использующая Android, и система на основе Linux.

  • Кто-нибудь взламывал его раньше?
  • Есть ли режим разработчика у системы IVI с Linux?


Я люблю настройки для разработчиков и тестовые приложения. Обычно экспериментировать с ними очень интересно. Я подумал, что мне может повезти и там будет опция включения SSH-сервера или чего-то подобного.

Выяснилось, что в моей IVI можно войти в режим разработчика, перейдя на экран Software Update, быстро нажав десять раз слева от кнопки Update, а потом один раз справа от неё.

Settings.png


Если экран не появлялся сразу после завершения нажатий, я просто повторял процесс.

Code.png


Режим разработчика (Engineering Mode) защищён PIN-кодом из четырёх цифр. Это руководство помогло мне понять, что используется PIN-код »2400».

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

  • USB copy
    • В этом меню есть подопции копирования логов на USB-накопитель или обновления отдельных частей системы с USB.
    • Одна из опций давала понять, что удерживание кнопки Radio на IVI тоже запускает сбор логов.

  • Module Info > ISV Setting
    • В этом меню есть опция ADB TCP, а также радиокнопки для SW Test Tools.


При помощи этих параметров я сохранил на свой USB-накопитель множество логов и попытался использовать ADB для доступа к IVI.
Я подключил свой телефон при помощи беспроводного Android Auto, чтобы добраться до Wi-Fi системы IVI, и попытался просканировать порты устройства, но не смог найти открытого порта ADB. Позже выяснилось, что на самом деле эти опции ничего не делают.
Логи оказались настоящей сокровищницей информации о внутренней работе IVI.

Логи сохраняются на USB в одном большом tar.gz под названием daudio2.0v_{Date}-{Time}.tar.gz.

DAudioLogFile.png


В архиве содержится множество файлов, в том числе лог ядра, вывод команды top, логи logcat и логи BlueLink.

DAudioLogFiles.png


Самый интересный из файлов логов — это файл logcat. По сути, для каждого приложения, запущенного в IVI, активно ведутся логи, и все они направляются в этот файл.

DAudioLogcatExample.png


На этом этапе я уже понимал, что для попадания в систему недостаточно будет просто включить какой-то параметр. Чтобы получить доступ, мне на самом деле придётся использовать эксплойт.

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

Мне пришло в голову, что проще всего будет сделать это, скачав обновление прошивки и распаковав его.


Я провёл дальнейшие исследования и изучил логи. Выяснилось, что в этих IVI работает D-Audio2V, разработанная Hyundai Mobis. D-Audio2V — это второе поколение Hyundai Display Audio OS, оно используется в различных автомобилях Hyundai и Kia. Обнаружилось, что на сайте Hyundai Mobis есть доступная для скачивания часть исходного кода D-Audio2. Я просмотрел его, но по большей части это были просто небольшие патчи разных опенсорсных проектов для работы системы Wi-Fi.

Обновления прошивки систем D-Audio2 находились на сайте update.hyundai.com в разделе Display Audio Software Update. К сожалению, конкретно для моего автомобиля там обновления не было, поэтому я просто скачал обновления для пары других машин.

Файлы прошивок скачиваются в виде простых файлов .zip, внутри которых находится ещё один файл .zip. Внутренний .zip называется enc_system_package_{version}.zip. Похоже, внутри system_package содержится прошивка для разных модулей IVI наподобие GPS и HD Radio, а также образ самой системы.

Обновление выглядело многообещающе, я попытался извлечь образ системы, но…

DAudioFirmwareEncryption.png


Весь .zip был зашифрован.

Однако это не охладило меня: на моём компьютере уже установлены инструменты наподобие John The Ripper и Hashcat, которые можно использовать для брутфорса паролей zip. Я попробовал взломать перебором пароль с ограничением до восьми символов, потому что с этим моя система могла справиться за разумное время, но ничего не получилось. Ещё я попробовал использовать некоторые из своих списков слов, но тоже потерпел неудачу.


Далее я начал искать другие инструменты или сервисы, которыми можно было бы воспользоваться. Так я нашёл bkcrack. Как оказалось, традиционное шифрование zip можно сломать при помощи атаки известным открытым текстом. Это значит, что если я смогу найти как минимум 12 байтов одного из файлов, находящихся внутри зашифрованного zip, то потенциально смогу расшифровать и весь файл.

Началась охота за подходящим файлом. Я посмотрел список файлов в зашифрованном zip и нашёл пару хороших кандидатов для атаки. Внутри папки MODEM\us есть файл modem_version.txt длиной 37 байтов. Так как это текстовый файл, вероятно, он имеет человекочитаемый формат.

DAudioFirmwareModemFiles.png


Сначала я загуглил файл в Интернете, надеясь, что смогу найти подходящий, но в основном находил мёртвые FTP-ссылки, поэтому решил пойти другим путём.

Я надеялся, что Hyundai использует одинаковые модули модемов в своих IVI, а следовательно и одинаковые файлы прошивок модема. Если я смогу найти незашифрованное обновление модема для другой IVI, то, возможно, найду и соответствующий файл modem_version.txt.

На сайте с обновлениями Hyundai я выяснил, что у Hyundai есть специальное ПО для обновления IVI навигации.

NavigationUpdater.png


Я установил ПО Navigation Updater и скачал последнее обновление для Hyundai Ioniq Navigation IVI 2020–2021 годов.

Затем я перешёл в папку, куда ПО распаковало файлы, и открыл tar-файл system_package.

NavigationTarFile.png


Внутри находилась папка modem, в которой находился очень знакомый набор файлов! Однако файл modem_version.txt имел другой размер.

NavigationModemFiles.png


Я знал, что есть множество других файлов, которые тоже могут подойти. Но какие из них будут совпадать с нужными?

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

ModemFilesCompared.png


К счастью, ко мне на помощь пришёл zip. При создании файла zip для каждого файла в нём вычисляется CRC. CRC (cyclic redundancy check) — это алгоритм нахождения контрольной суммы, которую программа распаковки zip использует для проверки того, что файл был расшифрован/распакован правильно. Одинаковые файлы генерируют одинаковые CRC. Так как файлы обновления системы навигации находились в файле tar, а не zip, я извлёк их, а затем запаковал в zip.

ModemFilesMatchedCRC.png


Совпала одна пара файлов: partition.mbn. Я нашёл нужный мне открытый текст.

Я загрузил в bkcrack найденный текст, и…

bkcrackFailed.png


Не сработало? Но почему?

В конечном итоге я просто начал забрасывать в программу что угодно, надеясь получить ключи. Как оказалось, есть много ложноположительных срабатываний, особенно если ограничить bkcrack минимумом в 12 байт открытого текста.

bkcrackFalsePositive.png


Однако попытки использовать эти ключи приводили к созданию неправильного файла zip

bkcrackFalsePositiveCreatingZip.png


bkcrackFalsePositivePasswordInput.png


bkcrackFalsePositiveBadPassword.png


Я вернулся на страницу issues bkcrack на Github и изучил все issue. Там я и узнал, что «открытый текст» (plaintext) должен быть не из самого исходного файла, а из правильно сжатой версии исходного файла.

Мне нужно было найти конкретную программу и параметры, которые Hyundai Mobis использовала для сжатия исходного zip.

Я запаковал файл partition.mbn при помощи встроенного приложения Windows для создания zip. Не сработало. Затем я попробовал все комбинации параметров в 7Zip.

7zipOptions.png


Я даже написал на C# программу, которая использовала библиотеку сжатия для создания каждой возможной комбинации.

Но ничего не сработало. Я подумал, что вряд ли Hyundai использовала какую-то неизвестную программу Windows для zip, поэтому перешёл на Linux.

Я создал множество файлов zip с различными параметрами при помощи инструмента командной строки zip, установленного в моей версии Kali.

ZipVariations.png


Затем я прошёлся по каждому, и в процессе выяснил, что использовал для bkcrack неправильные параметры. Мне нужно было указать запись файла внутри zip, а не сам zip. Пройдясь по моему списку несколько раз и попробовав множество возможных ключей, bkcrack нашёл его.

bkcrackSuccess.png


Я использовал найденные bkcrack «мастер-ключи» для создания zip, и…

bkcrackFalsePositiveCreatingZip.png


bkcrackSuccessPasswordInput.png


modemVersionTxt.png


Мне удалось успешно извлечь все файлы из зашифрованного zip!

bkcrack также позволяет восстановить пароль к zip из найденных им мастер-ключей, поэтому я попробовал использовать эту возможность, но программа не смогла найти ничего длиной до 16 символов, а большего количества символов взломать на своём PC я бы не смог.

Но поскольку теперь мне всё было доступно, я извлёк файл system.img, находившийся внутри папки enc_system.

Даже из наличия имеющихся файлов я узнал многое, например, как в системе были установлены Python и Perl. Я подумал, что это может пригодиться на будущее для реверс-инжиниринга оболочки.

Я нашёл, где хранились приложения, и начал их обратную разработку. К счастью, поскольку приложения выводили кучу отладочной информации в файл Logcat, я смог выявить и подвергнуть реверс-инжинирингу множество важных функций.

DAudioAppFolders.png


Также я выяснил, что установлен драйвер для USB-адаптеров Ethernet RTL8152/8153.

rtl8152Driver.png


Я купил несколько USB-адаптеров Ethernet на основе RTL8153, надеясь, что у них есть открытые порты. У одного из купленных мной адаптеров был встроенный USB-хаб, из-за чего он оказался несовместимым с IVI, но второй купленный был прямым адаптером Ethernet, что позволило мне успешно подключиться к системе. К сожалению, он позволял мне только получить доступ к серверам CarPlay и Android Auto, других открытых портов не было.

В процессе реверс-инжиниринга двоичного файла automotivefw я выяснил, что параметр ADB TCP в режиме разработчика присваивает eth0 IP-адрес 192.168.7.110.

adbTools.png


При помощи логов я обнаружил, что eth0 должен иметь MAC-адрес F4:50: EB:2E:58:00. Я надеялся, что изменив MAC-адрес своего адаптера RTL8153, я смогу получить доступ к сети, которая, если повезёт, имеет доступ к ADB.

Я перенаправил RTL-донгл в ВМ Kali и попытался использовать ethtool для записи в него нового MAC-адреса. Быстро выяснилось, что MAC-адрес RTL8153 невозможно изменить при помощи ethtool.

Я поискал онлайн инструменты, способные это сделать, но изучив статьи, пришёл к выводу, что параметры MAC-адреса в этих чипах редактировать нельзя. Спустя несколько часов поисков я нашёл образы утилиты Realtek RtPGtoolUI. Судя по найденной информации, это была утилита, используемая производителями для настройки этих USB-адаптеров Ethernet, в том числе и для записи MAC-адресов. Благодаря прочитанной документации я также узнал, что во многих таких адаптерах вместо традиционного флеш-накопителя используется что-то под названием EFuses. Если в моём адаптере используется EFuses, то есть вероятность, что я не смогу обновить его даже при наличии нужного инструмента, но у меня оставалась надежда и я продолжал искать.

Я потратил бесчисленное количество часов в попытках найти возможность скачать приложение. Наконец я нашёл подозрительный китайский форум с нужным файлом.

RtPGtoolUI.png


Немного поэкспериментировав, я смог успешно прошить новый MAC-адрес в адаптер, хотя в нём и использовался EFuses.
Я подключил прошитый адаптер Ethernet к USB-разъёму автомобиля, однако выяснилось, что ничего не изменилось. Через Wireshark я не увидел никакого отличающегося трафика. Я смог убедиться, что смена MAC-адреса произошла успешно, но это не дало мне дополнительного доступа и даже адреса IPv4.

Я просканировал адрес 192.168.7.110, который указывал на IVI, но нашёл только те же открытые порты CarPlay/Android Auto.

После этого я посмотрел логи и осознал, что устройство eth0 — это некий встроенный адаптер Ethernet, который всегда отключен. Какой бы USB-адаптер я ни использовал, он всегда отображался как eth1. Также в этот момент я понял, что пароль Wi-Fi дампился в логи при его генерации, то есть вместо этого я могу использовать подключение к Wi-Fi. Подключение к Wi-Fi дало мне тот же доступ к адаптеру Ethernet, только на этот раз моему ноутбуку был выдан правильный адрес IPv4.

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


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

В образе системы мне не удалось найти ни одного двоичного файла, выполняющего обновление прошивки. Приложение Engineering Mode и приложение Setup давали понять, что после нажатия кнопки Update в параметрах устройство IVI загружается в режиме восстановления.

enc_systemFiles.png


В папке enc_system обновления прошивки находился файл enc_updateboot.img. Я предположил, что этот образ содержит систему восстановления.

К сожалению, 7Zip не смог извлечь образ, как это было с файлом system.img. Открыв образ в Notepad++, я понял, почему так случилось.

enc_updatebootEncrypted.png


В нём не было читаемых строк, файл оказался зашифрованным. Думаю, именно это обозначает префикс enc_.

Я проверил другие файлы в обновлении, все файлы с префиксом enc_ оказались зашифрованными.

Я снова зашёл в тупик. Без ключа шифрования я не смог бы узнать больше о процессе обновления системы.

Я решил продолжать искать во всей уже имевшейся у меня информации. Продолжив выполнять реверс-инжиниринг всех возможных приложений, я изучал все извлечённые логи и читал скачанный ранее опенсорсный код с сайта Mobis.


Изучая исходный код с сайта Mobis, я искал все файлы, где были скрипты оболочки. В результатах я нашёл скрипт оболочки linux_envsetup.sh.

linux_envsetupScript.png


Этот файл открыл передо мной все двери.

Оказалось, что это был скрипт, создающий файл zip обновления системы.

linux_envsetupScriptCode.png


Пароль zip для обновления системы всё это время был на моём жёстком диске.

linux_envsetupZipPass.png


К счастью, способ шифрования, ключ и IV тоже находились в скрипте.

linux_envsetupAESEncryption.png


Скрипт также дал подсказку об использованной подписи RSA, но, к сожалению, ключ для него в исходном коде отсутствовал.

linux_envsetupRSASigning.png


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

encryptionKeySearchResults.png


Google Git? Apple? Chegg???

Оказалось, что ключ шифрования в этом скрипте — это первый пример ключа AES 128bit CBC, указанный в документе NIST SP800–38A.

exampleAESKey.png


Не могла же Hyundai Mobis использовать этот ключ, и он использовался только для тестирования, так ведь?

updatebootDecryption.png


Нет ошибки? Этого не может быть…

Я смог открыть файл в 7Zip, но в нём находился только один повреждённый элемент.

updateboot7Zip.png


Однако пропустив этот файл через binwalk, я выяснил, что файл updateboot.img успешно распакован, и в нём куча информации.

updatebootBinwalk.png


Использовав аргумент -e (extract) в binwalk, я извлёк файл img, обнаружив barebone-установку linux.

updatebootExtracted.png


Внутри папки /usr/bin folder я нашёл любопытный двоичный файл updateAgent.

updateAgent.png


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

Поискав ключевые слова наподобие «RSA», я нашёл публичный ключ, но никакого приватного ключа.

RSADecompiled.png


Я снова загуглил часть приватного ключа.

RSAGoogleResults.png


О, разработчики снова использовали очень распространённый ключ. Любопытно, пользовались ли они туториалом RSA Encryption & Decryption Example with OpenSSL in C по ссылке…
Теперь у меня были все ключи от крепости, однако обновление прошивки для конкретно моей модели машины пока отсутствовало. Я не хотел рисковать и ломать головное устройство нового автомобиля, поэтому начал ждать выпуска обновления.

Дальнейшее развитие событий будет изложено во второй части статьи.

© Habrahabr.ru