Статья Современные web-уязвимости (6.CSRF- Cross Site Request Forgery)

ripmandin

Red Team
13.03.2020
38
147
BIT
9
Эксклюзивно для codeby.net продолжаю публиковать перевод ресерчей по книге 2021 года от Brandon Wieser The Hackers Codex: Modern Web Application Attacks Demystified.
В этот раз разберем CSRF уязвимости и как их находить.
  1. Html Injection
  2. Host Header Injection
  3. Username Enumeration – SSN
  4. Same Origin Policy и Exploiting CORS Misconfigurations
  5. Origin Reflection Attacks
  6. CSRF
  7. CSRF Bypass – Clickjacking Drag and Drop
  8. Redirection Bugs
  9. XSS – Cross-Site Scripting
  10. Identifying XSS Vulnerabilities
  11. JSONP
  12. Language-Specific XSS
  13. SOME Attacks
  14. CSV Injection
  15. HTTP Desync
  16. Web Cache Poisoning
Вся информация предоставлена исключительно в ознакомительных целях. Автор не несет ответственности за любой возможный вред, причиненный с использованием сведений из этой статьи.

CRSF

Прежде чем мы обсудим следующий тип cross-origin атак, нам нужно определить новую концепцию - идею запроса, изменяющего состояние данных (state-changing request). В контексте безопасности веб-приложений, запрос на изменение состояния может быть определен как веб-запрос, который изменяет хранящуюся информацию с одного значения на другое. Например, запросы, которые изменяют информацию профиля пользователя (адрес, номер телефона, имя и т. д.), учетные данные пользователя, электронную почту для сброса пароля, независимо от того, включена ли для пользователя двухфакторная аутентификация, перевод средств с одного банковского счета на другой или автоматическая покупка товара в интернет-магазине (Amazon's One-Click Buy, например).

Несмотря на то, что существует множество книг и ресурсов, посвященных CSRF атакам, давайте кратко рассмотрим вектор атаки. Для тех, кто не знает – согласно OWASP, подделка межсайтовых запросов (CSRF) - это «атака, которая заставляет конечного пользователя выполнять нежелательные действия в веб-приложении, в котором в настоящее время они аутентифицированы. С небольшой помощью социальной инженерии (например, отправки ссылки по электронной почте или в чате), злоумышленник может обмануть пользователя приложения для выполнения действий по выбору злоумышленника. Если жертвой стал обычный пользователь, то успешная CSRF-атака может заставить его выполнить запрос на изменение данных (state-changing request), например перевод средств, изменение адреса электронной почты и так далее. Если жертвой стал пользователь с правами админа, CSRF может скомпрометировать все веб-приложение".

Есть несколько книг и ресурсов, которые посвящены тестированию CSRF уязвимостей; однако большинство современных фреймворков программирования автоматически защищаются от большинства этих атак.
Например, заявляет: «CSRF защита включена по умолчанию с конфигурацией Java. Если вы хотите отключить CSRF, см. соответствующую конфигурацию Java. Посмотрите функцию csrf() в Java-документации для дополнительных настроек защиты CSRF».

Хотя большинство фреймворков предоставляют защиту по умолчанию, которую легко настроить, в некоторых случаях CSRF все еще может возникнуть.
Например, (гласит: «Самая главная защита от CSRF-атак заключается в том, чтобы гарантировать, что запросы GET (и другие "безопасные" методы, как определено RFC 7231 # section-4.2.1) не имеют побочных эффектов. Запросы через "небезопасные" методы, такие как POST, PUT и DELETE, могут быть защищены, через выполнение следующих действий…».
Аналогичным образом, говорится: «Первый шаг к защите от CSRF-атак - убедиться, что ваш веб-сайт использует правильные HTTP-методы. В частности, перед использованием CSRF Spring Security вы должны быть уверены, что ваше приложение использует PATCH, POST, PUT и / или DELETE для всего, что изменяет состояние».

По сути, в этих документах упоминается тот факт, что по умолчанию защита от CSRF может быть реализована только с помощью HTTP-методов PATCH, POST, PUT и / или DELETE. Если разработчик реализовал запрос на изменение данных с помощью запроса GET, эти средства защиты по умолчанию не могут спасти пользователя.

Резюмируя и уточняя, если вы видите действие, изменяющее состояние (например, изменение учетных данных, обновление адреса электронной почты для сброса пароля, перевод средств на счет в банке), осуществляющееся любым HTTP-методом, кроме PATCH, POST, PUT, и / или DELETE, стоит здесь внимательнее осмотреться, вероятно, запрос уязвим для CSRF.

Кроме того, есть и другая интересная информация в документации Spring. Например, в разделе JSON говорится: «Распространенный вопрос: нужно ли мне защищать запросы JSON, отправленные через JavaScript? Короткий ответ: это зависит от обстоятельств. Однако вы должны быть очень осторожны, поскольку существуют CSRF, которые могут повлиять на запросы JSON.
Например, злоумышленник может :
1628432086811.png

CSRF-эксплойт для JSON

Что сгенерирует следующую JSON Структуру:
1628432140181.png

JSON-структура, которая будет отправлена в запросе

Если бы приложение не проверяло Content-Type, то оно было бы подвержено этому эксплойту. В зависимости от настройки, приложение Spring MVC (которое проверяет Content-Type) может быть проэксплуатировано, путем добавления в URL суффикса, чтобы заканчиваться на ".json", как показано ниже:
1628432179442.png

Использование .json в форме приводит к попытке отправить данные в JSON формате

Кроме того, , которое приводит к байпасу (обходу) защиты. Если приложение принимает Content-Type «application /x-www-form-urlencoded», тогда появляется возможность создать следующую форму запроса:
Код:
<form action=”https://redact.com/api/rest/model/atg/userprofiling/ProfileActor/updateMyData" method=”post”>
<input hidden=”true” type=”text” name=”firstName” value=”Foo”>
<input hidden=”true” type=”text” name=”lastName” value=”Bar”>
<input hidden=”true” type=”text” name=”email” value=”hacked@gmail.com”>
<input type=”text” hidden=”true” name=”gender” value=”Mujer”>
<input type=”text” name=”mobileNumber” hidden=”true” value=”+521452453698">
<input type=”text” name=”countryCode” hidden=”true” value=”+52">
<input type=”submit” value=”send”>
И хотя эта информация подходит для Spring, вероятно, что большинство других фреймворков будут содержать те же слабые места. С точки зрения злоумышленника это великолепная находка. По сути, документация говорит нам внимательно присмотреться к JSON-запросам, изменяющим состояния (state-changing JSON requests), сделанным в JavaScript, потому что их можно будет использовать для CSRF-атак.

Обход защиты от CSRF. Получение CSRF токена через CORS уязвимость
В случае когда злоумышленник может обойти Same Origin Policy (см. предыдущие статьи), например через XSS-уязвимость или используя неверную конфигурацию CORS, он сможет затем обойти и защиту от CSRF, используемую в приложении (т.н. проверка CSRF-токенов). Давайте для примера, возьмем прошлые данные
1628432320664.png

и проэсплуатируем с помощью JavaScript ошибку отражения Origin (Origin Reflection).

Как вы можете помнить, скрипт заставляет конечного пользователя, который посещает вредоносную страницу, отправить запрос на сервер, в ответе которого есть конфиденциальные данные, а затем он сохраняет ответ в переменной, которая отправляется на сервер злоумышленника. Если злоумышленник может читать ответы на посылаемые запросы, тогда ничто не мешает ему прочесть CSRF токен и включить этот токен в дальнейший запрос. Например, представьте, что следующий код JavaScript (взятый из ) был добавлен к коду
1628432339230.png

и размещен на веб-сервере злоумышленника.
Код:
// Получение содержания страницы
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://www.example.com/shop/viewAccount", false);
xhr.withCredentials=true;
xhr.send(null);

// извлечение со страницы CSRF токена
var token = xhr.responseText;
var pos = token.indexOf("csrftoken");
token = token.substring(pos,token.length).substr(12,50);

// теперь выполним CSRF атаку используя XHR с извлеченным токеном
xhr.open("POST", "https://www.example.com/shop/voteForProduct", false);
xhr.withCredentials=true;
var params = "productId=4711&vote=AAA&csrftoken="+token;
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Content-length", params.length);
xhr.send(params);

По сути, атака работает так:
1. Жертва с активным файлом cookie сеанса уязвимого приложения переходит на сайт злоумышленника.
2. На сайте злоумышленников размещен вредоносный код JavaScript, который выполняет следующие действия через браузер жертвы:
а. Отправляет GET-запрос через браузер жертвы с учетными данными до конечной точки, которая содержит форму изменения данных.​
б. Читает ответ на запрос из-за мисконфигурации CORS и ищет CSRF токен.​
в. Создает новый POST-запрос с учетными данными и параметром значения, которые злоумышленник хочет изменить, и включает CSRF токен как одно из этих значений.​
г. Отправляет этот POST-запрос, тем самым изменяя значение или выполнение действия, которое желает злоумышленник.​
Обход защиты от CSRF. Внедрение Cookie
Некоторые приложения пытаются защититься от CSRF, используя шаблон, называемый «шаблоном двойной отправки cookie». Например, описывает опцию, позволяющую включить этот шаблон; однако по умолчанию она отключена. Документация заявляет: «Определитесь, должен ли секретный токен для пользователя храниться в cookie или в req.session. Хранение секретного токена в файле cookie активизирует шаблон двойной отправки cookie. По умолчанию - false».

Затем в документации приводится «простой экспресс-пример», демонстрирующий использование «шаблона двойной отправки cookie». Ниже приводится пример некоторого серверного кода, который генерирует форму, требующую CSRF токен для отправки.
1628432447401.png

документация ExpressJS о том как работает защищающий от CSRF шаблон двойной отправки cookie

Внутри установим значение csrfToken как значение скрытого поля ввода (hidden input name) с именем _csrf:
1628432479080.png

HTML-код для использования шаблона двойной отправки cookie

Как видно из строки «csrf ({cookie: true})», «шаблон двойной отправки cookie» активизирован. Давай копнем глубже. При нажатии в документации на ссылку «шаблон двойной отправки cookie» нам показывается :
«Если содержание состояние для токена CSRF на стороне сервера проблематично, альтернативной защитой является использование метода двойной отправки cookie. Этот метод прост в реализации и самодостаточен. В этой технике мы отправляем случайное значение как в файле cookie, так и в качестве параметра запроса, а сервер проверяет совпадение значения cookie и значения запроса. Когда пользователь посещает (даже до аутентификации, чтобы предотвратить вход через CSRF), сайт должен сгенерировать (криптографически стойкое) псевдослучайное значение и установить его как cookie на машине пользователя отдельно от идентификатора сеанса. Затем сайт требует, чтобы в каждом транзакционном запросе содержалось это псевдослучайное значение как hidden value или как другой параметр/заголовок запроса. Если на стороне сервера проверка подтвердила, что cookie и параметр запроса совпадают, сервер обрабатывает запрос как легитимный, иначе он отклоняет запрос.

Поскольку субдомены могут записывать файлы cookie в родительские домены и файлы cookie могут быть установлены для домена через незащищенное HTTP-соединение, эта техника работает, пока вы уверены, что ваши поддомены полностью защищены и принимают только HTTPS-соединения…»

Подводя итог, «шаблон двойной отправки cookie» записывает в cookie случайное значение, и такое же значение отправляется в параметре запроса. При поступлении запросов на изменение данных приложение проверяет соответствие этих двух значений (значение cookie и значение параметра запроса). Как изображено на картинке:
1628432515843.png


Согласно документации, если существует уязвимость поддомена, неправильная конфигурация CORS, ошибка XSS в любом поддомене или какой-либо из поддоменов не использует HTTPS, тогда можно обойти механизм защиты от CSRF.
Кроме того, возможен другой вектор атаки, о котором не говорится в документации. Если злоумышленник может создать и установить значение или перезаписать произвольные cookie (или даже CSRF cookie), то также можно обойти защиту. Это не такая уж и редкость, чтобы обнаружить уязвимость, которая позволяет злоумышленнику устанавливает значения cookie (в моем случае это случается не реже нескольких раз в год во время тестирования веб-приложений на проникновение, прим. автора). Более серьезные векторы подобных атак могут быть через уязвимость внедрения заголовка (header injection) или когда значение параметра запроса напрямую используется для установки значения cookie.

Обычно в баг-баунти эти уязвимости игнорируются или получают «информационные» или «низкие» рейтинг серьезности (если это не header injection); однако в случае "шаблона двойной отправки cookie" во многих случаях его можно использовать для обхода механизма защиты CSRF. Более подробную информацию можно найти в .

Подводя итог, для поиска уязвимостей CSRF выполните следующие действия:
1. Определите все возможные содержащиеся в приложении функции, изменяющие информацию (state-changing actions), особо отмечая любое использование «шаблона двойной отправки cookie».
а. Если в этих функциях, используется шаблон двойной отправки cookie, проверьте домен на наличие ошибок по внедрению файлов cookie.​
2. Настройте перехватывающий прокси, например BurpSuite, и один за другим выполните каждый запрос на изменение состояния, захватывая запрос в прокси.
3. Для каждого запроса сначала попытайтесь удалить токен CSRF и ретранслировать запрос.
4. Если в запросе на изменение информации НЕ используется какой-либо из методов PATCH, POST, PUT и / или DELETE - попытайтесь выполнить CSRF-атаку.
5. Измените любой из запросов PATCH, POST, PUT и / или DELETE на GET и воспроизвести запрос. Если приложение принимает запрос, удалите все токены CSRF, отправляемые в URL-адресе, и повторите попытку.
6. Для любых JSON или AJAX запросов попытайтесь изменить «Content-Type» на «text/plain». Если приложение принимает запрос, создайте proof of concept, подобно показанному на рисунке
1628432551611.png

а. Если приложение проверяет «Content-Type», попробуйте создайте вторую форму, добавив «.json» к ссылке.​
б. Кроме того, попробуйте изменить «Content-Type» на «Application/x-www-form-urlencoded».​
7. Проверьте остальные функции, изменяющие информацию в обычном режиме.
 
Последнее редактирование:

Сергей Попов

Кодебай
30.12.2015
4 710
6 628
BIT
548
Grey статус на форуме
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!