[Перевод] Как я хакнул свой автомобиль
Прошлым летом я купил 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, а потом один раз справа от неё.
Если экран не появлялся сразу после завершения нажатий, я просто повторял процесс.
Режим разработчика (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.
В архиве содержится множество файлов, в том числе лог ядра, вывод команды top
, логи logcat и логи BlueLink.
Самый интересный из файлов логов — это файл logcat. По сути, для каждого приложения, запущенного в IVI, активно ведутся логи, и все они направляются в этот файл.
На этом этапе я уже понимал, что для попадания в систему недостаточно будет просто включить какой-то параметр. Чтобы получить доступ, мне на самом деле придётся использовать эксплойт.
Я решил, что лучшим способом понять, как попасть внутрь, будет реверс-инжиниринг запущенных в 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, а также образ самой системы.
Обновление выглядело многообещающе, я попытался извлечь образ системы, но…
Весь .zip был зашифрован.
Однако это не охладило меня: на моём компьютере уже установлены инструменты наподобие John The Ripper и Hashcat, которые можно использовать для брутфорса паролей zip. Я попробовал взломать перебором пароль с ограничением до восьми символов, потому что с этим моя система могла справиться за разумное время, но ничего не получилось. Ещё я попробовал использовать некоторые из своих списков слов, но тоже потерпел неудачу.
Далее я начал искать другие инструменты или сервисы, которыми можно было бы воспользоваться. Так я нашёл bkcrack. Как оказалось, традиционное шифрование zip можно сломать при помощи атаки известным открытым текстом. Это значит, что если я смогу найти как минимум 12 байтов одного из файлов, находящихся внутри зашифрованного zip, то потенциально смогу расшифровать и весь файл.
Началась охота за подходящим файлом. Я посмотрел список файлов в зашифрованном zip и нашёл пару хороших кандидатов для атаки. Внутри папки MODEM\us есть файл modem_version.txt длиной 37 байтов. Так как это текстовый файл, вероятно, он имеет человекочитаемый формат.
Сначала я загуглил файл в Интернете, надеясь, что смогу найти подходящий, но в основном находил мёртвые FTP-ссылки, поэтому решил пойти другим путём.
Я надеялся, что Hyundai использует одинаковые модули модемов в своих IVI, а следовательно и одинаковые файлы прошивок модема. Если я смогу найти незашифрованное обновление модема для другой IVI, то, возможно, найду и соответствующий файл modem_version.txt.
На сайте с обновлениями Hyundai я выяснил, что у Hyundai есть специальное ПО для обновления IVI навигации.
Я установил ПО Navigation Updater и скачал последнее обновление для Hyundai Ioniq Navigation IVI 2020–2021 годов.
Затем я перешёл в папку, куда ПО распаковало файлы, и открыл tar-файл system_package.
Внутри находилась папка modem, в которой находился очень знакомый набор файлов! Однако файл modem_version.txt имел другой размер.
Я знал, что есть множество других файлов, которые тоже могут подойти. Но какие из них будут совпадать с нужными?
При сравнении двух наборов файлов я нашёл несколько файлов одинакового размера, но не было гарантии, что они имеют одинаковое содержимое.
К счастью, ко мне на помощь пришёл zip. При создании файла zip для каждого файла в нём вычисляется CRC. CRC (cyclic redundancy check) — это алгоритм нахождения контрольной суммы, которую программа распаковки zip использует для проверки того, что файл был расшифрован/распакован правильно. Одинаковые файлы генерируют одинаковые CRC. Так как файлы обновления системы навигации находились в файле tar, а не zip, я извлёк их, а затем запаковал в zip.
Совпала одна пара файлов: partition.mbn. Я нашёл нужный мне открытый текст.
Я загрузил в bkcrack найденный текст, и…
Не сработало? Но почему?
В конечном итоге я просто начал забрасывать в программу что угодно, надеясь получить ключи. Как оказалось, есть много ложноположительных срабатываний, особенно если ограничить bkcrack минимумом в 12 байт открытого текста.
Однако попытки использовать эти ключи приводили к созданию неправильного файла zip
Я вернулся на страницу issues bkcrack на Github и изучил все issue. Там я и узнал, что «открытый текст» (plaintext) должен быть не из самого исходного файла, а из правильно сжатой версии исходного файла.
Мне нужно было найти конкретную программу и параметры, которые Hyundai Mobis использовала для сжатия исходного zip.
Я запаковал файл partition.mbn при помощи встроенного приложения Windows для создания zip. Не сработало. Затем я попробовал все комбинации параметров в 7Zip.
Я даже написал на C# программу, которая использовала библиотеку сжатия для создания каждой возможной комбинации.
Но ничего не сработало. Я подумал, что вряд ли Hyundai использовала какую-то неизвестную программу Windows для zip, поэтому перешёл на Linux.
Я создал множество файлов zip с различными параметрами при помощи инструмента командной строки zip, установленного в моей версии Kali.
Затем я прошёлся по каждому, и в процессе выяснил, что использовал для bkcrack неправильные параметры. Мне нужно было указать запись файла внутри zip, а не сам zip. Пройдясь по моему списку несколько раз и попробовав множество возможных ключей, bkcrack нашёл его.
Я использовал найденные bkcrack «мастер-ключи» для создания zip, и…
Мне удалось успешно извлечь все файлы из зашифрованного zip!
bkcrack также позволяет восстановить пароль к zip из найденных им мастер-ключей, поэтому я попробовал использовать эту возможность, но программа не смогла найти ничего длиной до 16 символов, а большего количества символов взломать на своём PC я бы не смог.
Но поскольку теперь мне всё было доступно, я извлёк файл system.img, находившийся внутри папки enc_system.
Даже из наличия имеющихся файлов я узнал многое, например, как в системе были установлены Python и Perl. Я подумал, что это может пригодиться на будущее для реверс-инжиниринга оболочки.
Я нашёл, где хранились приложения, и начал их обратную разработку. К счастью, поскольку приложения выводили кучу отладочной информации в файл Logcat, я смог выявить и подвергнуть реверс-инжинирингу множество важных функций.
Также я выяснил, что установлен драйвер для USB-адаптеров Ethernet RTL8152/8153.
Я купил несколько USB-адаптеров Ethernet на основе RTL8153, надеясь, что у них есть открытые порты. У одного из купленных мной адаптеров был встроенный USB-хаб, из-за чего он оказался несовместимым с IVI, но второй купленный был прямым адаптером Ethernet, что позволило мне успешно подключиться к системе. К сожалению, он позволял мне только получить доступ к серверам CarPlay и Android Auto, других открытых портов не было.
В процессе реверс-инжиниринга двоичного файла automotivefw я выяснил, что параметр ADB TCP в режиме разработчика присваивает eth0 IP-адрес 192.168.7.110.
При помощи логов я обнаружил, что 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, то есть вероятность, что я не смогу обновить его даже при наличии нужного инструмента, но у меня оставалась надежда и я продолжал искать.
Я потратил бесчисленное количество часов в попытках найти возможность скачать приложение. Наконец я нашёл подозрительный китайский форум с нужным файлом.
Немного поэкспериментировав, я смог успешно прошить новый 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_system обновления прошивки находился файл enc_updateboot.img. Я предположил, что этот образ содержит систему восстановления.
К сожалению, 7Zip не смог извлечь образ, как это было с файлом system.img. Открыв образ в Notepad++, я понял, почему так случилось.
В нём не было читаемых строк, файл оказался зашифрованным. Думаю, именно это обозначает префикс enc_.
Я проверил другие файлы в обновлении, все файлы с префиксом enc_ оказались зашифрованными.
Я снова зашёл в тупик. Без ключа шифрования я не смог бы узнать больше о процессе обновления системы.
Я решил продолжать искать во всей уже имевшейся у меня информации. Продолжив выполнять реверс-инжиниринг всех возможных приложений, я изучал все извлечённые логи и читал скачанный ранее опенсорсный код с сайта Mobis.
Изучая исходный код с сайта Mobis, я искал все файлы, где были скрипты оболочки. В результатах я нашёл скрипт оболочки linux_envsetup.sh.
Этот файл открыл передо мной все двери.
Оказалось, что это был скрипт, создающий файл zip обновления системы.
Пароль zip для обновления системы всё это время был на моём жёстком диске.
К счастью, способ шифрования, ключ и IV тоже находились в скрипте.
Скрипт также дал подсказку об использованной подписи RSA, но, к сожалению, ключ для него в исходном коде отсутствовал.
Но, по крайней мере, у меня был ключ шифрования. Чтобы убедиться, что никто до меня не добрался так далеко, я загуглил его.
Google Git? Apple? Chegg???
Оказалось, что ключ шифрования в этом скрипте — это первый пример ключа AES 128bit CBC, указанный в документе NIST SP800–38A.
Не могла же Hyundai Mobis использовать этот ключ, и он использовался только для тестирования, так ведь?
Нет ошибки? Этого не может быть…
Я смог открыть файл в 7Zip, но в нём находился только один повреждённый элемент.
Однако пропустив этот файл через binwalk, я выяснил, что файл updateboot.img успешно распакован, и в нём куча информации.
Использовав аргумент -e (extract) в binwalk, я извлёк файл img, обнаружив barebone-установку linux.
Внутри папки /usr/bin folder я нашёл любопытный двоичный файл updateAgent.
Так как у меня уже был пароль zip и ключ шифрования, я решил поискать ключ подписки: если повезёт, то разработчики оставили не только публичный, но приватный ключ.
Поискав ключевые слова наподобие «RSA», я нашёл публичный ключ, но никакого приватного ключа.
Я снова загуглил часть приватного ключа.
О, разработчики снова использовали очень распространённый ключ. Любопытно, пользовались ли они туториалом RSA Encryption & Decryption Example with OpenSSL in C по ссылке…
Теперь у меня были все ключи от крепости, однако обновление прошивки для конкретно моей модели машины пока отсутствовало. Я не хотел рисковать и ломать головное устройство нового автомобиля, поэтому начал ждать выпуска обновления.
Дальнейшее развитие событий будет изложено во второй части статьи.