Месяц назад Apple выпустила iPhone 15 — свой первый смартфон с разъёмом USB-C. Предыдущие полтора года я занимался аппаратным хакингом iPhone, например, мы выпустили опенсорсный последовательный JTAG-адаптер для iPhone под названием Tamarin Cable. Компания Apple наконец-то перешла на USB-C, поэтому мне стало любопытно, можно ли сделать что-то подобное с iPhone 15. Я купил по предзаказу этот телефон, пару печатных плат и набор электронных компонентов.
Прежде всего нужно сказать, что это не уязвимость и не jailbreak, я просто исследую USB-C в iPhone 15 и развлекаюсь со взломом оборудования.
Но давайте начнём сначала. Что же такое JTAG? Изначально JTAG разработали в 80-х годах для тестирования печатных плат и их целостности при помощи интерфейса boundary scan. Однако сегодня под JTAG обычно подразумевают низкоуровневый интерфейс отладки процессора. При помощи JTAG можно получить доступ к памяти, останавливать CPU, пошагово выполнять команды и так далее, на ранних этапах цепочки запуска, ещё до запуска операционной системы с программным отладчиком. SWD, или Serial Wire Debug — это, по сути, другой электрический интерфейс для JTAG, созданный компанией Arm. Оригинальному JTAG требуется не менее четырёх контактов, а SWD достаточно лишь двух.
Итак, перейдём к iPhone 15. На iPhone с разъёмом Lightning существовал чип Tristar, позволявший переключать контакты на разъёме в разные режимы, отправляя нужные байты по протоколу SDQ. Можно было переключить iPhone в режимы Serial, JTAG или USB. Учитывая количество имеющихся у USB-C контактов, я подумал, что Apple, вероятно, сделала нечто подобное с iPhone 15. Стоит также заметить, что новый iPhone — не первое устройство USB-C компании Apple, например, у MacBook Pro с M1 и у iPad Pro уже были USB-C. Начав искать исследования по ним, я обнаружил, что в 2019 году команда T8012 изучала USB-C в MacBook Pro и обнаружила, что в MacBook Pro с чипом безопасности T2 один из разъёмов USB-C можно было мультиплексировать в два разных режима. Один из участников команды T8012 смог сдампить прошивку отвечавшего за это чипа ACE; выполнив реверс-инжиниринг прошивки, он выяснил, что Apple использует функцию USB-C под названием VDM (Vendor Defined Messages).
VDM позволяет выполнять произвольные коммуникации по линиям CC (Channel Configuration) разъёма USB-C. Обычно эти линии используются для определения ориентации и подачи питания, но также могут применяться для произвольных коммуникаций. Благодаря реверс-инжинирингу стало понятно, что при помощи команд VDM можно переключать режим отдельных контактов разъёма USB-C, например, в последовательный режим.
У проекта Asahi Linux есть отличный инструмент под названием macvdmtool. Благодаря ему можно использовать чип ACE в одном MacBook для общения с чипом ACE в другом MacBook. Это позволяет отправлять Vendor Defined Messages и, например, получать Serial Boot Lock непосредственно в MacBook
Я пообщался с teamstar, он сказал, что это работает даже на его iPad Pro с USB-C, поэтому VDM показались мне прекрасной возможностью получить JTAG на iPhone 15. Ещё немного исследовав вопрос, я нашёл потрясающую плату под названием Central Scrutinizer, разработанную на основе инструмента vdmtool проекта Asahi Linux. По сути, это реализация macvdmtool на основе Raspberry Pi Pico, поэтому её можно использовать для отправки произвольных сообщений VDM. Изучив опенсорсную архитектуру этого оборудования, я решил купить пару готовых печатных плат без компонентов и установить только те, которые понадобятся мне для общения с iPhone. Я смонтировал FUSB302 — программируемый контроллер USB-C, несколько схем сдвига уровня, пассивные компоненты (конденсаторы и резисторы), а с обратной стороны припаял Raspberry Pi Pico.
Потом я попробовал это устройство с Mac M1, и оно сработало. Я мог перезагружать Mac, переключать его в режим DFU и даже просматривать коммуникации по последовательному разъёму при помощи логического анализатора.
Далее можно было попробовать работу Central Scrutinizer с iPhone 15. Я подключил плату к телефону, и наблюдал активность в блокировке, но ничего не сработало. Я не мог перезагружать iPhone и отсутствовали многие сообщения, обозначавшие успех на MacBook. Настало время переходить к отладке. Сначала я хотел убедиться, что методика с VDM вообще сможет сработать, поэтому проверил работу инструмента macvdmtool с iPhone 15. Всё получилось, я мог перезагружать телефон и даже получить доступ к последовательной консоли, то есть методика в целом была рабочей, только пока не со Central Scrutinizer. Я попробовал проанализировать логику USB PD. У меня возникла одна мысль: когда я подключал iPhone к Mac, он начинал заряжаться, но не когда я подключал его к Central Scrutinizer. Кроме того, я заметил, что в прошивке Central Scrutinizer конфигурация Power Delivery была настроена на 0 миллиампер, поэтому устройство не могло подавать питание.
Я решил проверить осциллографом линию VBUS — линию подачи питания. Оказалось, что когда iPhone не был подключен, эта линия подтягивалась к 5 В, однако с подключенным iPhone VBUS немного колебалась, а затем оставалась на 2,5 В, хотя должна была иметь 5 В. Я подумал, что проблема была в этом, поэтому начал думать, как её решить. К счастью, решение нашлось в моём ящике с деталями. R5524 — это переключатель питания USB, позволивший подать питание на разъём USB. Благодаря небольшому хаку с магнитной проволокой я создал свою модификацию. Кроме того, я настроил значение Power Delivery в прошивке, задав случайное значение, чтобы показать, что мы поддерживаем подачу питания.
Итак, настал момент истины. Подключаем iPhone — всё работает! Мы получаем те же сообщения логов, что и в случае с MacBook, а когда отправляем с помощью Central Scrutinizer команду перезапуска, iPhone перезагружается. Более того, в логическом анализаторе, подключенном к контактам SPU, мы видим boot lock. Отлично! Central Scrutinizer работает с iPhone. Но мы пока не получили JTAG.
Как же нам получить в iPhone JTAG, а не просто последовательное соединение? В процессе своих исследований я наткнулся на страницу документации Asahi Linux по оборудованию. Авторы выполнили реверс-инжиниринг различных действий, которые можно отправлять через VDM. Например, для получения последовательной консоли или консоли UART они отправляли команду 306. Однако в конце страницы было интересное тестовое примечание:
«Велика вероятность, что это SWD» — именно то, что мы ищем. Поэтому я поискал команду 306 в кодовой базе Central Scrutinizer и нашёл эту строку, в которой просто заменил 306 на 206.
Но чтобы проверить, сработает ли это, мне нужна была чуть более сложная схема. Согласно документации, контакты имели 1,2 В, поэтому мне нужно было опорное напряжение для отладчика. Я припаял небольшой контактный разъём, выдававший мне землю и 1,2 В от одного из схемы сдвига уровня. По сути, мой план заключался в том, чтобы отправлять на iPhone сообщение VDM 206 через Central Scrutinizer. Я надеялся, что это изменит конфигурацию двух контактов SBU USB-C, чтобы они предоставляли SWD (двухконтактный интерфейс JTAG), после чего я бы мог просто подключить к контактному разъёму Central Scrutinizer отладчик SWD и, если повезёт, подключится по JTAG.
Вот как выглядела готовая тестовая схема с отладчиком, Central Scrutinizer и iPhone:
Также я подключил к контактам SBU осциллограф, чтобы можно было следить за тем, что происходит в сигнальных линиях. Я попробовал подключиться с отладчиком, на осциллографе возникла какая-то активность, но, к сожалению, отладчик выдавал одни ошибки, как будто ничего не подключено. Но постойте: я подключил два контакта, нужных для SWD, но что, если я случайно подсоединил их неверно? Вероятность этого была 50 на 50. Поэтому я просто поменял провода местами и попробовал снова. Другое дело: вывод теперь выглядит совершенно иначе, в нём говорится, что он найден отладочный порт нулевого провода:
И он даже может считывать идентификационный регистр отладочного порта. Итак, мы всё-таки получили SWD на iPhone 15. Однако мы видим и какие-то ошибки, он не может найти AP, или debug access port. И этого следовало ожидать: производимые на продажу iPhone просто невозможно отлаживать без эксплойта, например, для отладки iPhone X при помощи Tamarin нам понадобится эксплойт BootROM Checkmate. Поэтому, несмотря на то, что JTAG заработал, мы не сможем выполнять отладку процессора. Впрочем, даже на iPhone 15 нам удастся в будущем изучить при помощи SWD множество интересных вещей. Мне понравился проект, ниже я привожу ссылки на весь свой код и проектные файлы аппаратного варианта Central Scrutinizer, работающего с iPhone 15.
▍ Ссылки
Модифицированная прошивка Central Scrutinizer: https://github.com/stacksmashing/cs-sw-iphone15
Пропатченный под iPhone 15 инструмент macvdmtool: github.com/stacksmashing/macvdmtool
Мой доклад о Tamarin Cable на DEF CON: https://www.youtube.com/watch?v=8p3Oi4DL0eI
Секреты Apple Lightning: https://www.youtube.com/watch?v=p5tMaWsuGk0
Оборудование Central Scrutinizer: git.kernel.org/pub/scm/linux/kernel/git/maz/cs-hw.git
Central Scrutinizer на Tindie (без модификаций с iPhone 15 не работает): https://www.tindie.com/products/aaafnraa/serial-adapter-reboot-controller-for-apple-m1m2/
Автор:
ru_vds