Самая интересная атака на побочные каналы фронтенда - XSLeaks (Часть 2)
Last updated
Last updated
Из последнего абзаца предыдущего поста видно, что когда XSLeaks
комбинируется с поиском, и это может создать больший эффект - этот метод атаки называется XS-Search
.
Причина, по которой он имеет больший эффект, заключается в том, что результаты поиска обычно считаются конфиденциальными. Как только результаты поиска могут быть выведены определенными способами, злоумышленники могут получить чувствительную информацию через функцию поиска. Итак, какие средства могут быть использованы?
Помимо методов, упомянутых в предыдущем посте, в этом посте будет обсужден более распространенный метод: Cache probing
.
Кэш-механизмы повсеместно распространены в мире компьютерных наук. В плане отправки запросов вы можете реализовать свой собственный кэш на JavaScript, где повторные запросы не отправляются снова. Браузеры также реализуют кэш-механизмы на основе HTTP-спецификации, а DNS также имеет кэширование при отправке запросов!
Браузеры имеют кэширование DNS, операционные системы имеют свои собственные кэши, а DNS-серверы также имеют свои собственные кэши. Кэширование повсюду, и даже у процессоров есть кэш-механизмы, такие как L1 и L2, которые обменивают пространство на время для ускорения выполнения.
Если вы помните, уязвимости процессора Spectre и Meltdown, упомянутые ранее, связаны с кэшированием. На самом деле, они похожи на технику Cache probing
, обсуждаемую в этом посте.
Как следует из названия, эта техника использует наличие чего-либо в кэше для вывода исходной информации.
Например, предположим, что веб-сайт отображает приветственную страницу, если пользователь вошел в систему, с изображением welcome.png
на ней. Если пользователь не вошел в систему, его перенаправят на страницу входа. Как только изображение отображается, оно будет сохранено в кэше браузера.
Поскольку изображения в кэше загружаются быстрее, мы можем определить, находится ли изображение в кэше, измеряя время, необходимое для загрузки welcome.png
. Это позволяет нам определить, вошел ли пользователь в систему.
Давайте рассмотрим случай из прошлого, чтобы понять это быстрее. В 2020 году Securitum обнаружил уязвимость во время проведения тестирования на проникновение на польском приложении ProteGo Safe: .
Во время пандемии COVID-19 многие правительства разработали свои собственные приложения или веб-сайты для единого отчета о состоянии здоровья и других вещах. Польша не стала исключением, и правительство запустило веб-сайт ProteGo Safe, где люди могли сообщать о своем состоянии или просматривать последнюю информацию.
На основе анкеты для отчетности о состоянии можно было получить четыре результата:
High
Medium
Low
Very low
В зависимости от результата на странице отображались разные изображения (такие как high.png
, medium.png
и так далее). Например, самый низкий риск был бы представлен символом, указывающим на безопасность.
Исходя из этого, автор определил состояние здоровья пользователя, измеряя время, необходимое для загрузки изображения. Если загрузка high.png
была самой быстрой, это означало, что состояние пользователя было high
. Код, использованный для обнаружения, выглядит следующим образом:
Время загрузки каждого изображения можно получить с помощью performance.getEntries()
, что позволяет нам определить, какое изображение загружается быстрее.
Однако есть небольшая проблема: этот трюк можно использовать только один раз. После первого открытия веб-сайта все четыре изображения будут загружены, и при следующем тесте все четыре будут в кэше и загрузятся быстро.
Поэтому нам нужно найти способ очистить кэш для пользователя. Когда браузер получает ответ с кодом состояния ошибки (4xx и 5xx), он очищает кэш. Итак, как мы можем сделать так, чтобы ответ для https://example.com/high.png
вернул ошибку?
Автор использовал здесь хитрый прием. Поскольку этот веб-сайт размещен на Cloudflare и имеет включенную функцию WAF (Web Application Firewall), он автоматически блокирует определенные полезные нагрузки. Например, URL https://example.com/high.png?/etc/passwd
будет заблокирован, потому что он содержит подозрительный /etc/passwd
, что приведет к коду состояния 403.
Поэтому автор добавил ?etc/passwd
к странице и использовал следующий код:
Таким образом, отправленное изображение будет иметь заголовок referrer
, содержащий /etc/passwd
, что приведет к блокировке его сервером и возврату ошибки, тем самым очищая кэш.
Расширяя эту идею, предположим, что есть веб-сайт, на котором мы можем сообщить, тестировались ли мы на определенное состояние, и он также отображает разные изображения в зависимости от результата. Мы можем использовать ту же технику, полагаясь на XSLeaks
, чтобы определить, тестировался ли человек, открывающий веб-сайт, на положительный результат, тем самым раскрывая его личную информацию.
Хотя определение того, находится ли ресурс в кэше, на основе времени является эффективным методом, оно иногда может быть затруднено из-за неопределенности сети. Например, если сеть работает очень быстро, может быть трудно определить, какой ресурс закэширован, когда каждый ресурс, кажется, имеет время отклика 1 мс или 2 мс.
Поэтому существует еще одна техника атаки, которая сочетает метод использования <img>
для определения того, загружено ли изображение, как упоминалось ранее, с Cache probing
. Вместо того чтобы полагаться на время, она использует события ошибок для определения, находится ли ресурс в кэше.
Предположим, есть страница под названием https://app.example.com/search?q=abc
, которая отображает разный контент в зависимости от результата поиска. Если что-то найдено, появится изображение https://app.example.com/found.png
; в противном случае изображение не будет присутствовать.
Сначала, как и в предыдущем шаге, нам нужно очистить кэш. Существует несколько методов на выбор, один из которых похож на метод Cookie Bomb
, упомянутый ранее, где мы заставляем сервер вернуть ошибку, отправляя большой запрос, тем самым очищая кэш в браузере:
Второй шаг — загрузить целевой веб-сайт https://app.example.com/search?q=abc
. В этот момент страница будет отображаться в зависимости от результата поиска. Как упоминалось ранее, если что-то найдено, изображение https://app.example.com/found.png
появится и будет сохранено в кэше браузера.
Последний шаг — сделать URL очень длинным и затем снова загрузить изображение:
Если изображение не в кэше, браузер отправит запрос для его получения. Это приведет к той же ситуации, что и на первом шаге, когда сервер возвращает ошибку из-за слишком длинного заголовка, что вызывает событие onerror.
С другой стороны, если изображение в кэше, браузер напрямую использует закэшированное изображение, не отправляя запрос. После загрузки изображения из кэша будет вызвано событие onload.
Таким образом, мы можем устранить нестабильный фактор времени и использовать кэш вместе с событиями ошибок для выполнения XSLeaks.
Давайте рассмотрим реальный случай, когда была применена эта техника.
My Activity
Gmail
Google Search
Google Books
Google Bookmarks
Google Keep
Google Contacts
YouTube
С помощью этих техник атаки XS-Search
злоумышленник может получить информацию, такую как:
Search history
Watched videos
Email content
Private notes
Web pages bookmarked
Оригинальная статья перечисляла много других примеров, но я выделил несколько более серьезных здесь.
Например, в Gmail есть функция "Расширенный поиск", аналогичная Google Search, где вы можете указать условия поиска с помощью фильтров. URL этой функции поиска также можно скопировать и вставить, чтобы напрямую открыть страницу поиска.
Если поиск успешен, появится определенный значок: https://www.gstatic.com/images/icons/material/system/1x/chevron_left_black_20dp.png
Поскольку электронная почта — это место, где хранится много конфиденциальной информации, например, некоторые плохо реализованные веб-сайты могут напрямую отправлять пароли в открытом виде пользователям. Эта техника может быть использована для постепенной утечки пароля.
Например, если формат электронного письма выглядит так: "Ваш пароль — 12345, пожалуйста, храните его в безопасности", мы можем последовательно искать:
Your password is 1
Your password is 2
Your password is 3
...
Таким образом, мы можем раскрыть первый символ пароля. После утечки мы продолжаем поиск:
Your password is 11
Your password is 12
Your password is 13
...
Это может утечь второй символ, и, продолжая пробовать, можно утечь полный пароль.
Однако, хотя это технически осуществимо, выполнение этой атаки более сложно. В конце концов, утечка занимает время и открывает подозрительное новое окно. Чтобы предотвратить замечание пользователями, полагаются на техники социального инжиниринга.
Из эксперимента terjanq видно, что XSLeaks
, использующие кэш, могут быть выполнены на многих продуктах, и это осуществимо. Кроме Google, должно быть много других веб-сайтов, которые могут выдавать информацию, используя аналогичные методы.
Уязвимости подобного рода, которые затрагивают множество веб-сайтов и не считаются специфическими для конкретного сайта, обычно обрабатываются браузерами.
Предыдущие методы эксплуатации основывались на предположении, что "кэш всех веб-сайтов общий", другими словами, если это предположение можно разрушить, этот метод атаки становится неэффективным.
Поэтому Chrome ввел новый механизм в 2020 году: разделение кэша. Ранее кэш использовался каждым веб-сайтом, и ключ кэша был URL, что позволяло XSLeaks
использовать существование кэша для утечки информации.
С введением разделения кэша ключ кэша изменился. Теперь это кортеж, состоящий из следующих трех значений:
Top-level site
Current-frame site
Resource URL
В примере предыдущей атаки, предположим, изображение https://app.example.com/found.png
загружается с https://app.example.com/search?q=abc
. Ключ кэша будет:
https://example.com
https://example.com
https://app.example.com/found.png
А если изображение https://app.example.com/found.png
загружается с другой страницы https://localhost:5555/exploit.html
, ключ кэша будет:
http://localhost:5555
http://localhost:5555
https://app.example.com/found.png
До разделения кэша ключ кэша имел только третье значение, поэтому в этих двух случаях они делили один и тот же кэш. Однако с разделением кэша все три значения должны быть одинаковыми, чтобы кэш мог быть доступен. Эти два случая имеют явно разные ключи, поэтому они будут использовать разные кэши.
Поскольку используются разные кэши, злоумышленники не могут выполнять атаки Cache probing
с других страниц, чтобы обнаружить существование кэша.
Одним из основных преимуществ является более быстрая скорость загрузки благодаря кэшированию. Предположим, многие веб-сайты используют сервис cdn.js
. Если вы загрузили этот файл на сайте A, он не будет загружен снова на сайте B.
Однако с разделением кэша это больше невозможно, потому что сайт A и сайт B будут иметь разные ключи, поэтому файл все равно будет загружен снова.
Наконец, стоит упомянуть, что разделение кэша в первую очередь зависит от "Site"
, а не от "Origin"
. Поэтому, если вы находитесь в ситуации Same-Site
, разделение кэша не имеет значения.
В приведенном ранее примере, что если атака запускается не с http://localhost:5555, а с https://test.example.com? Ключ кэша будет:
https://example.com
https://example.com
https://app.example.com/found.png
Это то же самое, что и загрузка изображения с https://app.example.com/search?q=abc, поэтому атаку Cache probing
все еще можно выполнить.
Кроме того, в headless Chrome
по умолчанию не включено разделение кэша. Поэтому, если вы используете Puppeteer в headless
режиме для доступа к веб-сайтам, они все равно будут делить один и тот же ключ кэша.
Из-за ограничений по объему я представил только несколько методов XSLeaks
. На самом деле существует много других техник.
Существует всего пять категорий данных, которые могут утечь:
Status code
Redirects
API usage
Page Content
HTTP header
Каждая из этих категорий имеет свои специфические методы для достижения утечек.
Например, в категории перенаправлений есть метод под названием "Max Redirect Leak", который использует максимальное количество разрешенных перенаправлений, чтобы определить, выполняет ли веб-страница серверные перенаправления.
Принцип следующий: в спецификации fetch
есть ограничение на количество перенаправлений для ответа:
If request's redirect count is 20, then return a network error.
Поэтому, предположим, что нашей целью для тестирования является http://target.com/test
, мы сначала создаем API на нашем собственном сервере, который перенаправляет 19 раз, с последним перенаправлением на http://target.com/test
.
Если ответ от http://target.com/test
является перенаправлением, это вызовет максимальный лимит в 20 перенаправлений и вызовет ошибку сети. Если это не перенаправление, то ничего не произойдет.
Проверяя, возникает ли ошибка во время выполнения fetch()
, мы можем определить, перенаправляется ли http://target.com/test
.
Веб-сайт xsinator
содержит много интересных техник XSLeaks
. Если вам интересно, вы можете ознакомиться с ним.
В этой статье мы продолжаем обсуждать XSLeaks
, о которых упоминали в предыдущей статье, и представляем метод атаки, использующий кэш в качестве оракула утечки. Это распространенная практика в мире атак бокового канала. Кроме того, мы предоставляем некоторые примеры из реальной жизни, чтобы показать влияние применения XSLeaks
на реальные веб-сайты. Например, пример с Google демонстрирует, что сочетание XSLeaks с функциональностью поиска может создать даже большее воздействие, чем предполагалось.
XSLeaks
— моя любимая тема в безопасности фронтенда. Если бы я серьезно писал об этом, я мог бы легко написать целую серию статей на 30 дней, потому что действительно существует много различных способов использования XSLeaks
. Некоторые методы атаки даже используют компоненты более низкого уровня, что делает атаки более сложными и требует большего предварительного знания.
Хотя XSLeaks
, как косвенный метод атаки, может не иметь такого же уровня воздействия, как прямые атаки XSS
, он все равно довольно увлекателен.
В 2019 году terjanq обнаружил уязвимость XS-Search в различных продуктах Google и написал статью под названием Технические детали можно найти в статье . Затронутые продукты включают:
В этот момент мы можем использовать упомянутую ранее технику, чтобы определить, существует ли конкретное ключевое слово в поиске (скрин из видео пока - ):
Эта реализация разделения кэша также имеет некоторое влияние на обычные веб-сайты. Один из примеров — общий CDN. Некоторые веб-сайты, такие как , размещают множество библиотек JavaScript бесплатно, что облегчает их загрузку на веб-сайты:
Кроме обращения к базе знаний была опубликована статья в 2021 году под названием "XSinator.com: From a Formal Model to the Automatic Evaluation of Cross-Site Leaks in Web Browsers", которая обнаружила много новых методов XSLeaks
с использованием автоматизированных техник.
Они также предоставляют веб-сайт, который объясняет, какие версии браузеров подвержены уязвимостям: