Web Cache Poisoning

Что такое Web Cache Poisoning?

Отравление веб-кэша — это продвинутая техника, при которой атакующий эксплуатирует поведение веб-сервера и кэша так, чтобы другим пользователям выдавался вредоносный HTTP-ответ.

Фундаментально отравление веб-кэша включает две фазы. Сначала атакующий должен добиться от бэкенд-сервера ответа, который непреднамеренно содержит некую опасную полезную нагрузку. Затем он должен обеспечить кэширование этого ответа и его последующую раздачу запланированным жертвам.

Web Cache Poisoning может стать механизмом доставки множества атак, эксплуатирующих уязвимости вроде XSS, открытых перенаправлений и т.п.

circle-check
circle-info

Исследования по отравлению веб-кэша

Эта техника была впервые популяризирована исследованием 2018 года «Practical Web Cache Poisoning», а в 2020 году развита в работе «Web Cache Entanglement: Novel Pathways to Poisoning». Подробные описания того, как находили и эксплуатировали эти уязвимости в реальных условиях, доступны на странице исследований.

Как работает веб-кэш?

Чтобы понять, как возникают уязвимости Web Cache Poisoning, важно в общих чертах понимать, как работают веб-кэши.

Если бы серверу приходилось по-отдельности формировать новый ответ на каждый HTTP-запрос, это, вероятно, перегрузило бы его, вызвав задержки и плохой пользовательский опыт, особенно в часы пик. Кэширование — прежде всего средство снижения таких проблем. Кэш располагается между сервером и пользователем и сохраняет (кэширует) ответы на конкретные запросы, обычно на фиксированное время. Если затем другой пользователь отправляет эквивалентный запрос, кэш просто выдаёт копию сохранённого ответа напрямую, без участия бэкенда. Это значительно снижает нагрузку на сервер за счёт уменьшения числа дублирующих запросов, которые ему приходится обрабатывать.

caching.svg

Ключи кэша

Получив HTTP-запрос, кэш сначала должен определить, есть ли уже сохранённый ответ, который можно отдать напрямую, или же нужно переслать запрос на обработку бэкенду. Кэши определяют эквивалентные запросы, сравнивая заранее определённое подмножество компонентов запроса, вместе называемое «ключ кэша» (cache key). Обычно он включает стартовую строку запроса и заголовок Host. Компоненты запроса, не включённые в ключ кэша, называют «не учитываемыми» (unkeyed).

Если ключ кэша входящего запроса совпадает с ключом предыдущего, кэш считает их эквивалентами и отдаёт копию сохранённого ответа, сгенерированного для исходного запроса. Это касается всех последующих запросов с совпадающим ключом кэша до тех пор, пока сохранённый ответ не протухнет.

Критично, что остальные компоненты запроса кэш полностью игнорирует. Влияние такого поведения мы рассмотрим ниже.

Каков эффект атаки Web Cache Poisoning?

Эффект отравления веб-кэша во многом зависит от двух факторов:

  • Что именно удаётся закэшировать атакующему. Поскольку отравленный кэш — это скорее механизм доставки, чем самостоятельная атака, эффект напрямую связан с внедрением полезной нагрузки. Как и большинство атак, отравление кэша можно комбинировать с другими техниками, ещё больше повышая влияние.

  • Объём трафика на затронутой странице. Вредоносный ответ будет отдаваться только пользователям, посещающим затронутую страницу, пока кэш отравлен. Поэтому влияние может варьироваться от нулевого до огромного, в зависимости от популярности страницы. Если, например, отравить кэшированную домашнюю страницу крупного сайта, атака может затронуть тысячи пользователей без дальнейших действий со стороны атакующего.

Обратите внимание, что время жизни кэша не обязательно влияет на итоговый эффект. Атаку обычно можно реализовать так, чтобы будет возможно повторно отравлять кэш бесконечно.

Построение атаки Web Cache Poisoning

В общем случае базовая атака строится так:

Нахождение не ключевых компонентов запроса

Любая атака отравления кэша опирается на манипулирование не ключевыми компонентами запроса, например, такими как заголовки запроса. Кэши игнорируют эти вхождения при решении, отдавать ли сохранённый ответ. Благодаря этому вы можете внедрить полезную нагрузку и добиться «отравленного» ответа, который, будучи закэшированным, будет выдаваться всем, чьи запросы имеют совпадающий ключ кэша. Поэтому первый шаг — выявить поддерживаемые сервером не ключевые компоненты запроса.

Их можно находить вручную, добавляя случайные вхождения в запросы и наблюдая, влияют ли они на ответ. Это может быть очевидно (прямое отражение ввода в ответ) или проявляться в виде совершенно другого ответа. Иногда эффект более тонкий и требует «детективной» работы. Можно использовать Burp Comparer для сравнения ответов с/без внедрённого ввода.

Param Miner

К счастью, процесс можно автоматизировать, подключив расширение Param Minerarrow-up-right из BApp-магазина Burp. Чтобы использовать Param Miner, щёлкните правой кнопкой на исследуемом запросе и выберите «Guess headers». Param Miner затем в фоне отправляет запросы с разными вхождения, например, заголовков запроса из своего внутреннего встроенного списка заголовков (Обычно этого достаточно, но можно использовать свой словарь в зависимости от необходимости). Если запрос с одним из таких вхождений влияет на ответ, Param Miner зафиксирует это в Burp — либо в панели «Issues» (в Burp Suite Professional), либо на вкладке «Output» расширения («Extensions» > «Installed» > «Param Miner» > «Output») в Burp Suite Community Edition.

Например, на скриншоте ниже Param Miner нашёл не ключевой компонент запроса - заголовок X-Forwarded-Host на главной странице сайта:

param-miner.png

Внимание: При тестировании не ключевых компонентов на настоящем сайте есть риск непреднамеренно заставить кэш раздавать ваши сгенерированные ответы реальным пользователям. Поэтому важно, чтобы ваши запросы имели уникальный ключ кэша и отдавались только вам. Для этого можно вручную добавлять cache buster/уникальный параметр в стартовую строку запроса каждый раз когда выполняется запроса. Либо, если вы используете Param Miner, предусмотрены опции автоматического добавления cache buster’а в каждый запрос.

Вызвать отравленный ответ от бэкенд-сервера

Определив не ключевой компонент, далее нужно понять, как сайт его обрабатывает. Это критично для успешного получения отравленного ответа. Если вхождение отражается в ответе без необходимой обработки или используется для динамической генерации данных, это потенциальная точка входа для отравления кэша.

Кэширование ответа

Манипулировать не ключевыми компонента ради отравленного ответа — это лишь половина дела; Без кэширования это мало что даст, а добиться кэширования бывает непросто.

Кэшируемость ответа может зависеть от множества факторов: расширения файла, типа содержимого, маршрута, кода состояния, заголовков ответа и пр. Вероятно, потребуется время, чтобы «поиграться» с запросами на разных страницах и изучить поведение кэша. Как только вы поймёте, как закэшировать ответ с вашей отравленной нагрузкой, можно доставлять эксплойт жертвам.

cache-poisoning.svg

Эксплуатация уязвимостей Web Cache Poisoning

Иногда данные мисконфигурации возникают из-за общих изъянов в дизайне кэшей. В других случаях неожиданные особенности появляются из-за конкретной реализации кэша на сайте и могут быть эксплуатированы.

Как предотвратить уязвимости Web Cache Poisoning

Радикальный способ — полностью отключить кэширование. Для многих сайтов это нереально, но в иных случаях — вполне. Например, если вы используете кэширование просто потому, что оно было включено по умолчанию при подключении CDN (сеть доставки контента), стоит оценить, насколько эти дефолтные опции отражают ваши потребности.

Даже если кэш нужен, ограничение кэширования только «статикой» тоже эффективно — при условии, что вы достаточно осторожны в определении «статичности». Например, убедитесь, что атакующий не сможет заставить бэкенд скачивать его «подменённую» статическую ресурсину вместо настоящей.

Ряд уязвимостей отравления кэша возникает из-за того, что атакующий может манипулировать «не ключевыми» заголовками запроса, многие из которых для работы сайта вообще не нужны. Такие уязвимости могут возникать просто потому что подключили технологию, которая по умолчанию поддерживает эти не ключевыми компоненты. Если заголовок не нужен для функционирования сайта — его следует отключить.

Также необходимо принять следующие меры при реализации кэширования:

  • Если вы по соображениям производительности планируете исключить что-то из ключа кэша, лучше перепишите запрос.

  • Не принимайте «крупные» GET-запросы. Помните, некоторые сторонние технологии могут разрешать это по умолчанию.

  • Исправляйте клиентские уязвимости, даже если они «неэксплуатируемы». Из-за непредсказуемых особенностей кэша некоторые из них могут оказаться эксплуатируемыми. Вопрос только во времени, когда кто-то найдёт особенность (кэш-поведение или иное), делающую уязвимость критичной.

Last updated