Я прошел через главу XSS в Академии веб-безопасности Портсвиггера, что настоятельно рекомендую. Это очень помогло мне понять XSS и другие веб-уязвимости. Расписание следующих нескольких статей будет: Stored XSS, DOM XSS, XSS Challenge Walkthroughs.
Объяснение сохраненного XSS
Сохраненные межсайтовые сценарии - это то же самое, что и Reflected XSS, однако сервер будет обслуживать (за неимением лучшего термина) злонамеренный ввод во всех будущих запросах к зараженной странице. Вредоносные данные могут быть отправлены через HTTP-запросы, через комментарии к сообщениям в социальных сетях или блогах, контактные данные в онлайн-платежной форме или в любом месте, где требуется какой-либо ввод на странице. Он также может поступать из других источников, таких как приложения веб-почты, доставляющие контент через SMTP (простой протокол передачи почты). Для большинства задач XSS в Академии веб-безопасности сохраненный XSS был найден в разделе комментариев сообщения в блоге, что означает, что каждый раз, когда эта страница загружалась любым пользователем, XSS запускался. Ключевое различие между отраженным и сохраненным XSS заключается в том, что сохраненные уязвимости XSS содержатся в приложении, и злоумышленнику не нужно побуждать цель щелкнуть определенную ссылку с помощью своих эксплуатировать.
Тестирование сохраненного XSS
Это несколько ручных способов тестирования XSS, потому что это можно легко автоматизировать с помощью Burp Suite или другого веб-сканера, но мы снова пытаемся понять, почему это дерьмо происходит именно так.
- Изменение параметров в сильном URL-запросе или в теле запроса.
- Тестирование различных полезных данных в пути к файлу URL.
- Изменение некоторых заголовков HTTP-запросов.
Независимо от того, где находится уязвимость XSS, первый шаг, который вам нужно предпринять для ее поиска, - это найти ссылки между точками входа и выхода данных, отправленных пользователем. Ручной способ сделать это - отправить определенное значение в точку входа и определить, существует ли оно в ответе и где. Если он существует в ответе, вы должны определить, существует ли он в нескольких запросах или просто отражен в немедленном ответе. Как только связь установлена, вы тестируете XSS, используя различные полезные данные. Они основаны на контексте ответа, в котором появляются сохраненные данные.
Различные контексты XSS
Ниже приведены различные сценарии, в которых вы можете найти уязвимость XSS, и то, как вы создадите свою полезную нагрузку на основе окружающего контекста.
- Самый простой контекст - это когда XSS-уязвимости обнаруживаются между тегами HTML, поэтому все, что вам нужно сделать, это ввести новые теги, такие как
<script>alert(1)</script>
или<img src=x onerror=alert(1)>
, но они не так распространены, как RIP. - Иногда вы можете встретить XSS в атрибутах HTML-тегов, поэтому вам нужно будет завершить значение атрибута, закрыть тег и ввести новый. Однако для этого потребуются символы
<
или>
, и многие приложения могут помещать эти символы в черный список. Поэтому, если вы не можете закрыть тег и создать новый, лучше всего ввести в тег новый атрибут. Я считаю, что в этих сценариях очень полезны такие обработчики событий, какonfocus
,autofocus
иonmouseover
. Примером может быть что-то вроде”onmouseover=”alert(3301)
, где эта полезная нагрузка явно закрывает атрибут того, что было раньше, и создает обработчик событийonmouseover
, чтобы окно предупреждения появлялось всякий раз, когда указатель мыши наводит курсор на контекст, в котором вы нашли XSS. - В других случаях уязвимость XSS может быть обнаружена в некотором клиентском JavaScript. В этих сценариях это может быть так же просто, как закрыть первый тег
script
и создать новый тег для выполнения вашего собственного Javascript. В других случаях XSS может быть в строке в контексте JavaScript, и вам нужно будет вырваться из строки. Важно помнить о синтаксических ошибках, поскольку они могут помешать выполнению сценария. Два полезных способа разорвать строку - это‘-alert(document.domain)-’
или‘;alert(document.domain)//
. - Однако в некоторых случаях символы, которые позволяют вырваться из строкового литерала (например,
'
), могут быть экранированы с помощью\
. Когда приложения экранируют одинарную кавычку, это выглядит как\'
, и это приложение будет читать это как одинарную кавычку, а не как специальный символ, который может вырываться из строкового литерала. Однако приложения не могут избежать обратной косой черты. Таким образом, если приложение преобразует';alert(1)//
в\';alert(1)//
, но не избегает обратной косой черты, то полезная нагрузка\';alert(1)//
будет преобразована в\\';alert(1)//
. Здесь первая обратная косая черта экранирует вторую, оставляя одинарную кавычку в качестве специального символа, который фактически завершает строку и позволяет нам вызывать нашalert
. - Есть и другие случаи, когда мы можем использовать кодировку HTML для запуска наших атак. Когда контекст XSS представляет собой некоторый существующий JavaScript в атрибуте тега в кавычках, например обработчик событий, можно использовать HTML-кодирование для обхода некоторых входных фильтров. Когда браузеры анализируют HTML в ответе сервера, они декодируют любой HTML перед его дальнейшей обработкой. Это означает, что можно обойти проверку ввода (например, символы черного списка веб-сайта, такие как
'
,<
или>
) с помощью кодировки HTML, выйти из любой строки и выполнить свой собственный код. Например, если есть XSS-уязвимость в:
<a href=”#” onclick=”...var data='{some_data_here}'...”>
и приложение блокирует символы одинарных кавычек, тогда можно было бы HTML закодировать символ одинарных кавычек как '
, выйти из Javascript в var data
и написать свой собственный код эксплойта. Что-то вроде '-alert(3301)-'
(это та же полезная нагрузка из контекста 3 - см. Выше, но только в кодировке HTML).
6. Наконец, еще один контекст, в котором мы можем найти уязвимость XSS, - это литералы шаблонов JavaScript. Это литералы sting, которые позволяют встроить выражения JavaScript. Это позволяет обрабатывать их и объединять с окружающим текстом. Следующий код показывает пример этого:
document.getElementById("cicada").innerHTML = `Hello ${user.username}`.
Здесь литерал шаблона встроен в синтаксис выражения: ${...}
и заключен в обратные кавычки вместо обычных одинарных кавычек. Когда XSS находится в литерале шаблона, вам не нужно выходить за пределы строки, вы можете включить свою полезную нагрузку непосредственно в строку, используя синтаксис, указанный выше: ${...}
. Пример полезной нагрузки,
document.getElementById("cicada").innerHTML = `Hello ${alert(document.cookie)}`
Забрать
Самое важное, что нужно вынести из этих разных контекстов, - это незнание какой-либо одной полезной нагрузки (для этого есть ТОННЫ шпаргалок), но знание когда использовать конкретную полезную нагрузку для определенного контекста. Как я только что описал, если вы видите контекст XSS в литерале шаблона, вам не нужно искать способы вырваться из него с помощью кодирования, дополнительных escape-символов или закрывающих тегов. Понимание контекста является ключевым. Цель состоит в том, чтобы быть снайпером, а не детишкой со сценарием спрея и молитвы. Самый смертный грех во взломе.
Следующее сообщение
В моей следующей статье я подробно расскажу о DOM XSS, а затем пройду около 10 уровней (средних и сложных) различных задач XSS, которые я выполнил.