Введение
Отраженный межсайтовый скриптинг (Reflected Cross-Site Scripting, XSS) — это распространенная уязвимость веб-приложений, возникающая, когда приложение получает данные в HTTP-запросе и включает их в непосредственный HTTP-ответ небезопасным способом. Поскольку внедренный вредоносный скрипт «отражается» от веб-сервера, он выполняется в браузере жертвы, что позволяет злоумышленникам красть сессионные файлы cookie, выполнять действия от имени пользователя или изменять внешний вид веб-сайта.
Ключевая идея заключается в том, что XSS — это ошибка выполнения кода на стороне браузера. Сервер может отразить полезную нагрузку, но именно в браузере скрипт фактически запускается и именно там нарушается граница доверия.
В этой лабораторной работе вы будете взаимодействовать с локально размещенным уязвимым веб-приложением. Вы изучите систематический подход к поиску и эксплуатации Reflected XSS: определение места отражения ввода, тестирование обработки приложением специальных символов, выход из существующей структуры HTML и, наконец, выполнение вредоносной полезной нагрузки JavaScript.
Поиск точек отражения
На этом этапе вы узнаете, как идентифицировать точки отражения в веб-приложении. Точка отражения — это место в HTTP-ответе приложения, где введенные вами в HTTP-запросе данные отображаются (или «отражаются») обратно.
Мы запустили уязвимое веб-приложение на вашей локальной машине, доступное на порту 8080. В этом приложении есть функция поиска, которая принимает параметр запроса с именем q.
Чтобы найти точку отражения, нужно отправить уникальную, легко идентифицируемую строку в приложение и проверить, появится ли она в исходном коде ответа. Мы будем использовать инструмент командной строки curl для отправки HTTP GET-запроса к приложению.
Отражение необходимо, но недостаточно. Ваш ввод должен вернуться в таком контексте, где парсинг браузера может превратить его в исполняемый код.
Выполните следующую команду в терминале, чтобы отправить тестовую строку REFLECTION_TEST в конечную точку поиска:
curl -s "http://localhost:8080/search?q=REFLECTION_TEST"
Внимательно посмотрите на HTML-вывод, отображенный в вашем терминале. Вы должны увидеть, что ваш ввод REFLECTION_TEST встроен непосредственно в структуру HTML.
<!DOCTYPE html>
<html>
<head><title>Search Results</title></head>
<body>
<h2>Search Results</h2>
<form action="/search" method="GET">
<input type="text" name="q" value="REFLECTION_TEST">
<button type="submit">Search Again</button>
</form>
</body>
</html>
Обратите внимание, что ваш ввод помещен внутрь атрибута value тега <input>. Это подтверждает, что приложение берет наш ввод из URL и отражает его непосредственно в HTML-ответе. Это первое условие, необходимое для уязвимости Reflected XSS.
Тестирование фильтрации символов (< > ")
На этом этапе вы проверите, выполняет ли приложение санитацию или фильтрацию специальных символов HTML.
Контекстно-зависимое кодирование — это настоящая защита в данном случае. Опасные символы различаются в зависимости от того, попадает ли ввод в текст элемента, HTML-атрибут, JavaScript или URL.
Нахождения точки отражения недостаточно для подтверждения уязвимости XSS. Современные веб-фреймворки часто автоматически кодируют специальные символы. Например, знак «меньше» < может быть преобразован в <. Если приложение кодирует эти символы, браузер будет воспринимать их как безопасный текст, а не как исполняемый код, что предотвратит XSS.
Для внедрения вредоносного HTML или JavaScript нам обычно нужны такие символы, как знак «меньше» < (для начала тега), знак «больше» > (для закрытия тега) и двойные кавычки " (для манипуляции атрибутами).
Давайте отправим новую полезную нагрузку, содержащую эти специальные символы, чтобы увидеть, как приложение их обрабатывает. Мы будем использовать одинарные кавычки вокруг URL в нашей команде curl, чтобы оболочка Linux не интерпретировала специальные символы.
Выполните следующую команду для проверки фильтрации символов:
curl -s 'http://localhost:8080/search?q=FILTER_TEST<>"'
Изучите вывод, возвращенный сервером:
<!DOCTYPE html>
<html>
<head><title>Search Results</title></head>
<body>
<h2>Search Results</h2>
<form action="/search" method="GET">
<input type="text" name="q" value="FILTER_TEST<>"">
<button type="submit">Search Again</button>
</form>
</body>
</html>
Посмотрите на атрибут value в теге <input>. Символы <>" отражены точно так же, как мы их отправили, без какого-либо HTML-кодирования (например, < или "). Отсутствие санитации подтверждает, что приложение с высокой долей вероятности уязвимо для межсайтового скриптинга.
Выход из контекста HTML
На этом этапе вы узнаете, как выйти из текущего контекста HTML, чтобы подготовиться к внедрению полезной нагрузки.
Это суть практической работы с XSS: понимание контекста парсера, в котором вы находитесь, а затем использование синтаксиса для безопасного выхода из него в более опасный контекст.
Контекст имеет решающее значение в XSS. В нашем уязвимом приложении точка отражения находится внутри HTML-атрибута: value="[YOUR_INPUT]". Если мы просто внедрим тег <script>, он станет частью текстового значения поля ввода, а не будет выполнен браузером.
Чтобы заставить браузер выполнить наш код, мы должны сначала «выйти» из атрибута value и закрыть тег <input>.
Поскольку атрибут заключен в двойные кавычки, мы можем внедрить двойную кавычку ", чтобы преждевременно закрыть атрибут value. Затем мы можем внедрить знак «больше» >, чтобы закрыть сам тег <input>.
Давайте протестируем эту технику выхода. Отправьте следующую полезную нагрузку в приложение:
curl -s 'http://localhost:8080/search?q=BREAKOUT">'
Внимательно изучите HTML-вывод:
<!DOCTYPE html>
<html>
<head><title>Search Results</title></head>
<body>
<h2>Search Results</h2>
<form action="/search" method="GET">
<input type="text" name="q" value="BREAKOUT">">
<button type="submit">Search Again</button>
</form>
</body>
</html>
Посмотрите, что произошло с тегом <input>. Теперь HTML выглядит так: value="BREAKOUT">">.
Наша внедренная " успешно закрыла атрибут value, а внедренный > закрыл тег <input>. Оставшиеся "> в конце — это исходная закрывающая кавычка и скобка из шаблона приложения, которые теперь остались как безобидный текст на странице.
Вы успешно вышли из контекста HTML-атрибута. Пробел сразу после вашей полезной нагрузки теперь воспринимается как стандартное содержимое тела HTML, куда можно вставлять новые теги.
Выполнение полезной нагрузки JavaScript
На этом заключительном этапе вы объедините технику выхода с вредоносной полезной нагрузкой JavaScript для достижения межсайтового скриптинга.
Теперь, когда вы знаете, как выйти из тега <input>, вы можете добавить любой допустимый HTML или JavaScript сразу после вашей последовательности выхода. Самым распространенным доказательством концепции (PoC) для XSS является внедрение тега <script>, который вызывает окно alert() в JavaScript.
Наша полная полезная нагрузка будет выглядеть так: "><script>alert("XSS")</script>
Вот как работает эта нагрузка. Последовательность "> выходит из атрибута value и закрывает тег <input>. Затем тег <script> начинает новый блок выполнения JavaScript. Внутри этого блока alert("XSS") — это код JavaScript, который будет выполнен. Наконец, тег </script> закрывает блок выполнения.
Выполните следующую команду, чтобы внедрить полную полезную нагрузку XSS:
curl -s 'http://localhost:8080/search?q="><script>alert("XSS")</script>'
Изучите итоговый HTML-вывод:
<!DOCTYPE html>
<html>
<head><title>Search Results</title></head>
<body>
<h2>Search Results</h2>
<form action="/search" method="GET">
<input type="text" name="q" value=""><script>alert("XSS")</script>">
<button type="submit">Search Again</button>
</form>
</body>
</html>
Если бы жертва перешла по ссылке, содержащей эту полезную нагрузку в своем веб-браузере (например, http://localhost:8080/search?q="><script>alert("XSS")</script>), ее браузер проанализировал бы HTML сверху вниз. Когда он дойдет до внедренного тега <script>, он выполнит код JavaScript, открыв окно оповещения с надписью "XSS".
В реальной атаке вместо безобидного оповещения злоумышленник внедрил бы код для кражи сессионных файлов cookie жертвы (document.cookie) и отправки их на вредоносный сервер, что привело бы к полному захвату учетной записи.
Резюме
Поздравляем! Вы успешно завершили лабораторную работу по отраженному межсайтовому скриптингу (Reflected XSS).
В этой лабораторной работе вы узнали, как:
- Идентифицировать точки отражения путем отправки уникальных строк и анализа HTTP-ответа.
- Проверять фильтрацию символов, чтобы определить, безопасно ли приложение кодирует специальные символы HTML.
- Выходить из контекста HTML-атрибутов путем манипуляции кавычками и скобками.
- Создавать и внедрять полную полезную нагрузку JavaScript для достижения выполнения кода в браузере.
Понимание этих механизмов необходимо как для выявления уязвимостей в качестве исследователя безопасности, так и для реализации надлежащей санитации ввода и кодирования вывода в качестве разработчика.



