Я прошел через главу XSS в Академии веб-безопасности Портсвиггера, что настоятельно рекомендую. Это очень помогло мне понять XSS и другие веб-уязвимости. Расписание следующих нескольких статей будет: Stored XSS, DOM XSS, XSS Challenge Walkthroughs.

Объяснение сохраненного XSS

Сохраненные межсайтовые сценарии - это то же самое, что и Reflected XSS, однако сервер будет обслуживать (за неимением лучшего термина) злонамеренный ввод во всех будущих запросах к зараженной странице. Вредоносные данные могут быть отправлены через HTTP-запросы, через комментарии к сообщениям в социальных сетях или блогах, контактные данные в онлайн-платежной форме или в любом месте, где требуется какой-либо ввод на странице. Он также может поступать из других источников, таких как приложения веб-почты, доставляющие контент через SMTP (простой протокол передачи почты). Для большинства задач XSS в Академии веб-безопасности сохраненный XSS был найден в разделе комментариев сообщения в блоге, что означает, что каждый раз, когда эта страница загружалась любым пользователем, XSS запускался. Ключевое различие между отраженным и сохраненным XSS заключается в том, что сохраненные уязвимости XSS содержатся в приложении, и злоумышленнику не нужно побуждать цель щелкнуть определенную ссылку с помощью своих эксплуатировать.

Тестирование сохраненного XSS

Это несколько ручных способов тестирования XSS, потому что это можно легко автоматизировать с помощью Burp Suite или другого веб-сканера, но мы снова пытаемся понять, почему это дерьмо происходит именно так.

  1. Изменение параметров в сильном URL-запросе или в теле запроса.
  2. Тестирование различных полезных данных в пути к файлу URL.
  3. Изменение некоторых заголовков HTTP-запросов.

Независимо от того, где находится уязвимость XSS, первый шаг, который вам нужно предпринять для ее поиска, - это найти ссылки между точками входа и выхода данных, отправленных пользователем. Ручной способ сделать это - отправить определенное значение в точку входа и определить, существует ли оно в ответе и где. Если он существует в ответе, вы должны определить, существует ли он в нескольких запросах или просто отражен в немедленном ответе. Как только связь установлена, вы тестируете XSS, используя различные полезные данные. Они основаны на контексте ответа, в котором появляются сохраненные данные.

Различные контексты XSS

Ниже приведены различные сценарии, в которых вы можете найти уязвимость XSS, и то, как вы создадите свою полезную нагрузку на основе окружающего контекста.

  1. Самый простой контекст - это когда XSS-уязвимости обнаруживаются между тегами HTML, поэтому все, что вам нужно сделать, это ввести новые теги, такие как <script>alert(1)</script> или <img src=x onerror=alert(1)>, но они не так распространены, как RIP.
  2. Иногда вы можете встретить XSS в атрибутах HTML-тегов, поэтому вам нужно будет завершить значение атрибута, закрыть тег и ввести новый. Однако для этого потребуются символы < или >, и многие приложения могут помещать эти символы в черный список. Поэтому, если вы не можете закрыть тег и создать новый, лучше всего ввести в тег новый атрибут. Я считаю, что в этих сценариях очень полезны такие обработчики событий, как onfocus, autofocus и onmouseover. Примером может быть что-то вроде ”onmouseover=”alert(3301), где эта полезная нагрузка явно закрывает атрибут того, что было раньше, и создает обработчик событийonmouseover, чтобы окно предупреждения появлялось всякий раз, когда указатель мыши наводит курсор на контекст, в котором вы нашли XSS.
  3. В других случаях уязвимость XSS может быть обнаружена в некотором клиентском JavaScript. В этих сценариях это может быть так же просто, как закрыть первый тег script и создать новый тег для выполнения вашего собственного Javascript. В других случаях XSS может быть в строке в контексте JavaScript, и вам нужно будет вырваться из строки. Важно помнить о синтаксических ошибках, поскольку они могут помешать выполнению сценария. Два полезных способа разорвать строку - это ‘-alert(document.domain)-’ или ‘;alert(document.domain)//.
  4. Однако в некоторых случаях символы, которые позволяют вырваться из строкового литерала (например, '), могут быть экранированы с помощью \. Когда приложения экранируют одинарную кавычку, это выглядит как \', и это приложение будет читать это как одинарную кавычку, а не как специальный символ, который может вырываться из строкового литерала. Однако приложения не могут избежать обратной косой черты. Таким образом, если приложение преобразует ';alert(1)// в \';alert(1)//, но не избегает обратной косой черты, то полезная нагрузка \';alert(1)// будет преобразована в \\';alert(1)//. Здесь первая обратная косая черта экранирует вторую, оставляя одинарную кавычку в качестве специального символа, который фактически завершает строку и позволяет нам вызывать наш alert.
  5. Есть и другие случаи, когда мы можем использовать кодировку HTML для запуска наших атак. Когда контекст XSS представляет собой некоторый существующий JavaScript в атрибуте тега в кавычках, например обработчик событий, можно использовать HTML-кодирование для обхода некоторых входных фильтров. Когда браузеры анализируют HTML в ответе сервера, они декодируют любой HTML перед его дальнейшей обработкой. Это означает, что можно обойти проверку ввода (например, символы черного списка веб-сайта, такие как ', < или >) с помощью кодировки HTML, выйти из любой строки и выполнить свой собственный код. Например, если есть XSS-уязвимость в:

<a href=”#” onclick=”...var data='{some_data_here}'...”> и приложение блокирует символы одинарных кавычек, тогда можно было бы HTML закодировать символ одинарных кавычек как &apos;, выйти из Javascript в var data и написать свой собственный код эксплойта. Что-то вроде &apos;-alert(3301)-&apos; (это та же полезная нагрузка из контекста 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, которые я выполнил.