Обход Content-Security-Policy для выполнения XSS с использованием MIME sniffing
Этичный ХакерКраткое изложение
Недавно я обнаружил уязвимость Cross Site Scripting, однако обычная полезная нагрузка XSS не запускалась, потому что CSP блокировал выполнение внешнего Javascript кода. Обнаружив еще одну уязвимость XSS в другой конечной точке (которая снова блокируется CSP), мне удалось объединить их вместе, что привело к обходу CSP и запуску XSS с помощью MIME sniffing.
Нахождение первого XSS
На следующем изображении показана конечная точка на главной странице, значение параметра которой отражается в теле веб-сайта.

Вместо того чтобы задавать строковое значение, давайте попробуем ввести простую нагрузку в виде HTML. Я ввел <h1>kleiton0x00</h1> и, надеюсь, полезная нагрузка будет отражена и отображена как HTML-контент.

Круто, у нас есть HTML Injection, так что давайте попробуем использовать его в XSS. На этот раз я ввел самую простую полезную нагрузку XSS: <script>alert(1)</script>
Если WAF ничего не отфильтрует или заблокирует, мы сможем активировать полезную нагрузку Javascript.

Полезная нагрузка успешно внедрена на веб-сайт, но нет всплывающего окна? Глядя на исходный код страницы, видим, что ничего не фильтровалось и не удалялось.

Обнаружение CSP
Взглянув на инструменты разработчика в браузере (Console), я понял, что скрипт блокируется Content-Security-Policy.

Что это значит? Политика безопасности содержимого (CSP) - это дополнительный уровень безопасности, в частности заголовок HTTP, который блокирует ввод внешних кодов на веб-сайт. Обычно хорошо реализованный CSP разрешает выполнение скриптов только внутренними объектами (самим доменом).
Сначала мы должны определить, как работает CSP и из какого источника он позволяет загружать скрипты внутри веб-сайта.

Глядя на заголовки HTTP, в частности Content-Security-Policy: мы видим, что у CSP есть правило принимать скрипты от самого веб-сайта, его каталогов и поддоменов. Похоже, мы очень ограничены, поскольку не можем внедрить собственный вредоносный Javascript.
Поиск другой уязвимой конечной точки для XSS
Поскольку мы не можем его обойти, я решил осмотреться, пытаясь найти больше XSS. Я открыл исходный код страницы и во время прокрутки заметил php-код, у которого есть параметр. Интересно!

Не теряя времени, сразу перешел в /js/countdown.php
В конце параметра я помещаю простое строковое значение, чтобы увидеть, как ведет себя веб-сайт.

Мы видим, как наша строка (kleiton0x00) отражается в исходном коде. Супер! Мы можем начать внедрение нашего кода javascript.
Выход из строки Javascript для выполнения второго XSS
Вместо того, чтобы вводить просто символы, давайте попробуем разбить строку js. Как это сделать? Исходя из кода, наш отраженный ввод добавляется сразу после чисел.
Добавим ); чтобы закрыть текущий код Javascript во 2-й строке. Скобка ) закроет значение переменной и ; закроет текущий код javascript во второй строке. Поскольку код закрыт, мы можем добавить новый код Javascript, который, конечно же, является нашим вредоносным кодом, в нашем случае alert(1);
К сожалению, в строке осталось: *1000).getTime();
Как от этого избавиться? Легко, просто закомментируем. Итак, в конце нашего ввода мы добавляем //
Наша финальная полезная нагрузка будет такой:
); alert (1); //

Отлично, основываясь на исходном коде страницы, мы успешно внедрили код Javascript и получили второй XSS!
Таким образом, полный URL-адрес будет: http://website.com/js/countdown.php?end=2534926825);alert(1);//
При переходе по указанному URL-адресу XSS не отображается. Почему? Потому что наш XSS снова блокируется CSP.
Обход CSP для 2 XSS с использованием MIME Sniffing
Пришло время объединить первый XSS, который мы нашли на главной странице, и второй XSS, который мы нашли на countdown.php.
Давайте посмотрим, как MIME Sniffing может привести к уязвимости XSS. Чтобы злоумышленник мог выполнить XSS-атаку с помощью MIME Sniffing, должны быть выполнены определенные предварительные условия. Обратите внимание, что оба предварительных условия на стороне клиента:
- Злоумышленник должен иметь возможность контролировать контент в ответе сервера, чтобы можно было внедрить вредоносный JavaScript (второй найденный нами XSS).
- Злоумышленник должен иметь возможность ввести исполняемый контекст с помощью HTML-инъекции или Javascript-инъекции (первый XSS, который мы нашли).
Наша полезная нагрузка XSS будет основана на том, что мы нашли в первом XSS ( <script>alert(1)</script> ). Вместо выполнения Javascript мы загрузим URL-адрес countdown.php, а именно: http://website.com/js/countdown.php?end=2534926825);alert(1);//
Итак, объединив полезную нагрузку первого XSS с URL-адресом уязвимого php файла, наша конечная полезная нагрузка будет выглядеть так:
<script src=’http://website.com/js/countdown.php?end=2534926825);alert(1);//></script>

Мы обошли CSP и успешно выполнили alert(1) с использованием MIME Sniffing.
На этом все. Спасибо за просмотр!