Исследователи из Технологический института Джорджии, Мичиганского университета и Рурского университета разработали технику атаки iLeakage, позволяющую эксплуатировать уязвимость в ARM-процессорах Apple серий “A” и “M” через открытие в браузере специально оформленной страницы. Подготовленные исследователями прототипы эксплоитов позволяют при запуске JavaScript-кода в браузере узнать содержимое сайтов, открытых в других вкладках, например, продемонстрирована возможность определения текста письма, открытого во вкладке с Gmail, просмотра истории YouTube и извлечения пароля, подставленного менеджером паролей LastPass в форму входа в Instagram. Атака применима к браузеру Safari на системах с macOS и любым браузерам на платформе iOS (правила Apple предписывают во всех браузерах для iOS использовать только системный движок WebKit, общий с Safari).
Несмотря на то, что атака применима только к продуктам Apple, в ней предложен достаточно интересный способ обхода ограничений разрешения таймера в движке WebKit, который потенциально может оказаться полезным для обхода аналогичных ограничений в других браузерах. Выявленная в чипах Apple M1 и M2 уязвимость напоминает классическую уязвимость Spectre v1 и также приводит к утечке содержимого памяти при выполнении операций в спекулятивном режиме, которые в случае неверного предсказания отбрасываются процессором, но следы их выполнения оседают в процессорном кэше.
В рассматриваемом методе атаки спекулятивное выполнение позволило создать примитив для чтения произвольных 64-разрядных указателей в адресном пространстве процесса, отвечающего за отрисовку содержимого страниц в браузере. Для получения доступа к адресному пространству процесса, в котором отрисовывается чужой сайт, использован трюк с открытием исследуемой чужой страницы во всплывающем окне при помощи JavaScript-метода window.open(). В этом случае сайт открывался не в отдельном процессе, а в одном процессе с кодом атакующего.
В качестве одной из мер защиты в движке WebKit допускается работа JavaScript только с упакованными 35-разрядными указателями. Для организации доступа к всему адресному пространству процесса и обхода 35-разрядного ограничения исследователи задействовали технику Type Confusion, позволяющую вынудить JavaScript-движок обработать объект с некорректным типом. При обработке специально оформленного JavaScript-объекта в движке создаются условия, приводящие к спекулятивному исполнению инструкций, осуществляющих доступ к массиву.
Так как тип объекта не соответствует типу обрабатываемого массива, в обычных условиях подобные действия блокируются, поэтому код для атаки Type Confusion выносится в условный блок “if”, который не активируется при обычных условиях, но выполняется в спекулятивном режиме при неверном предсказании процессором дальнейшего ветвления.
В итоге процессор спекулятивно обращается к сформированному 64-разрядному указателю, но откатывает состояние после определения неудачного прогноза. При этом следы спекулятивного выполнения оседают в общем кэше и могут быть восстановлены при помощи методов определения содержимого кэша по сторонним каналам.
Для извлечения данных из L1-кэша CPU, оставшихся после спекулятивного выполнения операций, в атаке задействована модификация ранее предложенного Google метода pLRU (pseudo Least
Recently Used). При этом исходный метод pLRU завязан на измерении задержек при доступе к данным, различие которые даёт возможность судить о том, находится или нет определённая последовательность в процессорном кэше (если данные прокешированы – операция выполняется быстрее, а если нет – медленнее). Для защиты от зондирования процессорного кэша в современных браузерах точность работы таймера существенно понижена до уровня, не позволяющего выявлять различия.
Для преодоления ограничения точности таймера в атаке iLeakage предложена техника, позволяющая определять присутствие или отсутствие данных в кэше, используя состояние гонки. Суть метода в одновременном запуске двух потоков – основного и эталонного. Эталонный поток включает последовательность инструкций, выполняемых определённое эталонное время. В самом начале выполнения эталонного потока в значение 1 выставляется совместно используемая с основным потоком переменная, а после выполнения инструкций – переменная обнуляется. Таким образом, совместно используемая переменная имеет значение 1 только определённое короткое время.
В основном потоке инициируется цикл определения данных в кэше методом pLRU. Признаком наличия или отсутствия в кэше проверяемых данных является не измерение времени таймером, а состояние совместной переменной после проверки. Если переменная имеет значение 1, то операция завершена быстрее, чем был выполнен эталонный код в параллельном потоке, т.е. данные были отданы из кэша. Если переменная содержит значение 0, то операция выполнялась относительно долго из-за отсутствия данных в кэше и эталонный код в параллельном потоке успел полностью отработать.
Точность предложенного метода определения содержимого кэша составляет от 90% до 99%, а производительность определения данных от 23 до 34 байт в секунду, в зависимости от процессора и устройства. Перед проведением атаки требуется калибровка эталонного кода, которая занимает примерно пять минут. После завершения калибровки для текущей системы на извлечение 64-символьной строки уходит примерно 30 секунд.
Дополнительно можно отметить публикацию прототипа эксплоита, использующего уязвимость Zenbleed в процессорах AMD на базе микроархитектуры Zen2 для извлечения данных, обрабатываемых в других процессах, при открытии страницы с эксплоитом в Chrome. Кроме уязвимости Zenbleed (CVE-2023-20593) в эксплоите также задействована уязвимость CVE-2023-3079 в движке V8, исправленная в Chrome 115.