Не все cookie одинаково полезны

- КиТ :: Будь в СЕТИ!

В этой статье я хотел бы рассказать о том, как можно объединить небольшие недочеты в обработке cookie-значений в цепочку, и произвести за счет этого атаку на пользователей популярных веб-приложений. История началась больше года назад, когда я испытывал программу DOMinator для поиска DOM-Based XSS на сайтах Bug Bounty программ

Одним из первых предупреждений, которое я получил, была уязвимость Cookie Injection в JavaScript сценарии Google Analytics.

При обращении к сайту с Google Analytics, сценарий обрабатывает значение HTTP заголовка Referer и извлекает из него host и путь к сценарию, для отслеживания откуда пришел пользователь. В дальнейшем эти данные попадают в cookie параметр .

Выглядит это следующим образом: Изменяя путь к сценарию на своем сайте, с которого пользователь переходит на сайт с Google Analytics, можно влиять на конец значения cookie и попытаться изменить атрибуты cookie, так как путь никак не обрабатывается перед попаданием в значение. Однако, атрибуты будут перезаписаны последующими значениями, которые подставляет Google Analytics. Результат: На данный момент это было сложно назвать уязвимостью, но тем не менее поведение сценария довольно интересное, к тому же он невероятно распространен.

Bug Bounty и Cookie

Небольшое отступление. Уязвимости, связанные с cookie, в рамках программ вознаграждения за уязвимости, примечательны тем, что у вас может получится два основных сценария:

Найдена возможность перезаписи и создания произвольных cookie параметров.

Ответ: Это всего лишь cookie, что это тебе даст?

Найдена XSS через cookie параметр.

Ответ: Ты ведь не можешь создать произвольный cookie параметр, значит, это не уязвимость!

И только если оба варианта оказались в рамках одной Bug Bounty программы, то вам, так уж и быть, заплатят.

Необходимость каждый раз доказывать угрозу от проблем, связанных с сookie, зачастую отталкивает людей от их поиска. Так как за потраченное на это время можно найти еще десяток уязвимостей, которые будут приняты без вопросов. В основном проверяются только самые базовые вещи, типа фиксации сессии и правильности установленных атрибутов secure, httpOnly…

Cookie

Взглянем на структуру сookie заголовков:

Структура довольно сложная и с ней работают при каждом запросе браузер, JavaScript сценарии и веб-сервер. Каждый при этом обрабатывает по-своему, и одна и та же строка может дать разные результаты.

Анализируя обработку cookie необходимо задаться следующими вопросами:

Нужны ли пробелы после ; Какие символы можно использовать вместо ; Какое значение будет результирующее в случае одинаковых ключей Важен ли регистр у ключей Сколько может быть атрибутов у параметра Какое значение будет результирующее в случае одинаковых атрибутов Как правильно кодировать спецсимволы

Особенности обработки Cookie

Первая и наиболее известная особенность — Safari позволяет объявлять несколько параметров через один заголовок Set-Cookie. Возвращаясь к проблеме Google Analytics, проверим данную особенность в установке cookie через JavaScript. Получаем первый вариант эксплуатации: Результат Safari создаст два cookie параметра и .

То есть, для пользователя Safari на любом сайте с Google Analytics можно создать произвольный cookie параметр. Осталось только придумать зачем…

CSRF

Защиту от CSRF можно условно разделить на 3 типа:

Различные токены для каждого действия. Хранятся на сервере. Один сессионный токен на все действия. Хранится на сервере в сессии пользователя. Один сессионный токен на все действия. Хранится в cookie параметре.

Третий вариант основывается на том, что значение токена в cookie пользователя недоступно для злоумышленника. Для прохождения проверки достаточно просто послать одинаковое значение токена в cookie и post параметрах. То есть, простая перезапись значения через Google Analytics тут подойдет идеально.

Особенности обработки Cookie #2

Что если развернуть атаку на 180 градусов? Не обязательно, чтобы в браузере действительно был cookie параметр с CSRF токеном, значение которого мы знаем. Достаточно, чтобы так считал веб-сервер.

В этом поможет еще одна обнаруженная особенность обработки сookie. Note: For backward compatibility, the separator in the Cookie header

is semi-colon (;) everywhere. A server should also accept comma (,)

as the separator between cookie-values for future compatibility.

Многие веб-серверы поддерживают перечисление сookie не только через точку с запятой, но и через запятую.

Более того, в некоторых случаях пробел не обязателен.

В свою очередь, для большинства браузеров такие символы как пробел и запятая являются вполне нормальными. И если установить:

Для браузера это будет одно значение, но для некоторых серверных реализаций — два сookie параметра. Однако, в случае эксплуатации данных особенностей для обхода CSRF защиты, необходимо помнить, что мы не перезаписываем старый токен, а добавляем еще один, то есть важен порядок обработки сookie. Итого получается уже две цепочки эксплуатации уязвимости:

Эксплуатация

После подготовки неплохой базы, необходима проверка в реальных условиях. Практически сразу находится идеальный вариант .

На нем реализована CSRF защита, основанная на cookie, сервер поддерживает перечисление cookie через запятую без пробела, но… На нем нет Google Analytics. Зато он есть на ! Самое время проверить обработку атрибутов cookie значений, а если точнее, проверить возможность отбрасывания добавляемых в конце значений path и domain в случае, если инъекция происходит в значение cookie.

Оказалось, что Google Chrome в случае большого количества атрибутов cookie в какой-то момент просто прекращает их разбирать и не доходит до последних валидных значений.

То есть, в данном случае: Cookie будет установлена на , а не на .

Таким образом, добавляется еще одна цепочка эксплуатации: Формируем PoC: Описание:

Пользователь авторизован на Мобильная версия подхватывает сессию основного сайта даже если пользователь не заходил на нее Предполагаем, что пользователь не был на и у него не установлена cookie на нем Передаем Referer с путем, в котором содержится инъекция в cookie, на сайт Google Analytics создает сookie Из-за большого количества атрибутов Chrome перезаписывает domain на Ждем окончание обработки запроса и посылаем еще один запрос на создание твита «PoC», используя токен «x» В соответствии с порядком отправленных cookie, берет наше значение токена «x» и убеждается, что значение в post запросе и в cookie одинаковые У пользователя появляется твит PoC

Особенности обработки Cookie #3

Следующей целью стал , а точнее все сайты на Django. CSRF защита в Django также основана на cookie. Для успешного прохождения проверки достаточно послать одинаковые значения в cookie и post параметре , либо в HTTP заголовке . Однако, есть дополнительная проверка, которая в дальнейшем может помешать. В случае, если сайт работает по HTTPS, Django проверяет заголовок Referer и, в случае несовпадения, блокирует запрос, даже если в нем указан правильный токен. Post запросы без Referer также блокируются.

В ходе изучения обработки сookie в Django были обнаружены следующие особенности:

В качестве разделителя не обязательно использовать точку с запятой, достаточно любого пробельного символа между параметрами

Если в значении сookie есть символы , то первая часть сookie отбрасывается

.

В результате создается только сookie .

Оказалось, что данная проблема даже не в Django, а в Python. Библиотека Cookie обрабатывает значения в соответствии с . И действительно оказывается, что использование символов не предусмотрено, если значение не обрамлено двойными кавычками. Для браузеров же использование этих символов — вполне нормальное явление.

PoC для instagram практически идентичен предыдущему: Для пробрасывания cookie используется , а для создания токена конструкция .

Особенности обработки Cookie #4

После общения с Google, Twitter, Facebook, Django и Python я вновь решил попробовать обойти их исправления.

Произошли следующие изменения условий:

Google Analytics начал отбрасывать часть после точки с запятой и принудительно заменять пробел на %20 Python исправил некорректную обработку

Однако, все еще оставалась возможность перечисления cookie через пробельный символ в Django, чему сильно мешала замена используемая Google.

Проверка пробельных символов показала следующее:

Internet Explorer заменяет символы \x09 \x0b \x0c на _ Chrome не устанавливает cookie, если оно содержит символы \x09 \x0b \x0c FireFox считает данные символы нормальными

В результате чего получается следующий вариант эксплуатации для FireFox Особенности обработки Cookie #5

Также я обнаружил еще один интересный вариант в некоторых серверных реализациях, но пока не нашел применения в реальных условиях. При использовании спецсимволов в cookie, значение обрамляют в двойные кавычки. Данное поведение можно использовать следующим образом:

Для браузеров двойные кавычки не являются каким-то особым символом и в результате получится такой заголовок: Но некоторые веб-серверы могут обработать данные значения, как один параметр test, в результате чего параметр не будет создан. При совпадении невероятного количества условий, данная особенность также может быть использована.

Результаты

Варианты эксплуатации

Фиксы

В Google Analytics добавили принудительную замену пробела на %20 в значении cookie (сомнительное улучшение)

В Google Analytics исправили возможность изменить атрибуты cookie путем отбрасывания всего, что идет после символа ";"

Google Chrome НЕ будет исправлять перезапись с помощью большого количества атрибутов, так как возможности устанавливать произвольные атрибуты не должно быть у клиента изначально

Python исправил проблему с символами ()

Twitter изменили тип CSRF защиты на сайте

При общении с Google я столкнулся с тотальным непониманием сути уязвимости. От меня требовали примера на сайтах Google, которого у меня не было, и их совершенно не интересовало, что Google Analytics может нести угрозу на других сайтах. И лишь спустя десяток писем мой отчет попал к Krzysztof’у (судя по всему это был ), который разобрался что к чему и донес информацию до соответствующих разработчиков.

ПодпискаБудь в СЕТИ! Новости социальных сетей - всегда актуальное
 
Группы: ВК | OK | Tg