Контексты XSS
При тестировании Reflected и Stored XSS ключевая задача — определить контекст возникновения уязвимости:
Местоположение внутри ответа, где появляются данные, контролируемые атакующим.
Любая проверка ввода или иная обработка, которую приложение применяет к этим данным.
XSS между HTML‑тегами
Когда контекст XSS — это текст между HTML‑тегами, вам нужно внедрить новые HTML‑теги, рассчитанные на запуск JavaScript.
Некоторые полезные способы выполнить JavaScript:
<script>alert(document.domain)</script>
<img src=1 onerror=alert(1)>XSS в атрибутах HTML‑тега
Когда контекст XSS — внутри значения атрибута HTML‑тега, иногда можно завершить значение атрибута, закрыть тег и внедрить новый. Например:
Чаще в такой ситуации угловые скобки блокируются или кодируются, и ваш ввод не может вырваться из тега, в котором он находится. Если удаётся закрыть значение атрибута, обычно можно добавить новый атрибут, создающий контекст в котором мы можем добавлять новый обработчик события и использовать js. Например:
Вышеуказанная полезная нагрузка создаёт событие onfocus, которое выполнит JavaScript, когда элемент получит фокус, а также добавляет атрибут autofocus, чтобы попытаться автоматически вызвать событие onfocus без взаимодействия с пользователем. Наконец, он добавляет x=" для аккуратного восстановления последующей разметки.
Иногда контекст XSS — это тип атрибута HTML‑тега, который сам по себе может создавать необходимый js-контекст. В таком случае можно выполнить JavaScript, не завершая значение атрибута. Например, если контекст XSS — в атрибуте href тега anchor, вы можете использовать псевдопротокол javascript для выполнения скрипта. Например:
Вы можете столкнуться с сайтами, которые кодируют угловые скобки, но всё же позволяют добавлять атрибуты. Иногда такие инъекции возможны даже внутри тегов, которые обычно не инициируют события автоматически, например в теге canonical. Вы можете эксплуатировать это поведение с помощью access keys и взаимодействия пользователя в Chrome. Access keys позволяют назначать горячие клавиши, ссылающиеся на конкретный элемент. Атрибут accesskey позволяет определить букву, которая при нажатии в комбинации с другими клавишами (они различаются на разных платформах) вызовет события. В следующей лабораторной вы можете поэкспериментировать с access keys и эксплуатировать тег canonical. XSS in hidden input fields
XSS внутри JavaScript
Когда контекст XSS — это существующий JavaScript внутри ответа, возможен широкий спектр ситуаций, требующих разных техник для успешной эксплуатации.
Завершение существующего скрипта
В простейшем случае можно просто закрыть тег script, который охватывает существующий JavaScript, и внедрить новые HTML‑теги, запускающие выполнение JavaScript. Например, если контекст XSS следующий:
То вы можете использовать следующую полезную нагрузку, чтобы вырваться из существующего JavaScript и выполнить свой:
Причина, по которой это работает, состоит в том, что браузер сначала выполняет HTML‑разбор, чтобы определить элементы страницы, включая блоки скриптов, и только затем выполняет разбор JavaScript для понимания и выполнения внедрённых скриптов. Приведённая полезная нагрузка оставляет исходный скрипт «сломанным» — с незавершённой строковой константой. Но это не мешает последующему скрипту быть разобранным и выполненным в обычном порядке.
Выход из строкового литерала JavaScript
В случаях, когда контекст XSS находится внутри заключённого в кавычки строкового литерала, часто можно вырваться из строки и выполнить JavaScript напрямую. Критически важно восстановить скрипт после места инъекции, поскольку любые синтаксические ошибки далее помешают выполнению всего скрипта.
Некоторые полезные способы вырваться из строкового литерала:
Некоторые приложения пытаются не допустить выхода из строкового литерала, экранируя любые одиночные кавычки обратной косой чертой. Обратная косая черта перед символом сообщает парсеру JavaScript, что символ следует трактовать буквально, а не как специальный. В такой ситуации приложения часто допускают ошибку, не экранируя сам символ обратной косой черты. Это означает, что атакующий может использовать собственную обратную косую черту, чтобы «обезвредить» обратную косую черту, добавленную приложением.
Например, предположим, что ввод:
Преобразуется в:
Теперь вы можете использовать альтернативную полезную нагрузку:
Которая преобразуется в:
Здесь первая обратная косая черта означает, что вторая будет интерпретирована буквально, а не как специальный символ. Это приводит к тому, что кавычка интерпретируется как терминатор строки, и атака срабатывает.
Некоторые сайты усложняют эксплуатацию XSS, ограничивая набор допустимых символов. Это может делаться на уровне сайта или посредством WAF, который не допускает ваши запросы до веб‑приложения. В таких ситуациях нужно экспериментировать с альтернативными способами вызова функций, обходящими эти меры безопасности. Один из способов — использовать оператор throw вместе с обработчиком исключений. Это позволяет передавать аргументы функции без использования круглых скобок. Следующий код присваивает функцию alert() глобальному обработчику исключений, а оператор throw передаёт 1 этому обработчику (в данном случае alert). В итоге функция alert() вызывается с аргументом 1.
Существует несколько способов использовать этот приём для вызова функций без скобок.
Следующая лабораторная демонстрирует сайт, который фильтрует некоторые символы. Чтобы решить её, вам придётся использовать техники, подобные описанным выше.
Использование HTML‑кодирования
Когда контекст XSS — это существующий JavaScript внутри заключённого в кавычки атрибута тега (например, обработчика события), можно использовать HTML‑кодирование для обхода некоторых фильтров ввода.
Когда браузер разобрал HTML‑теги и атрибуты внутри ответа, он выполняет HTML‑декодирование значений атрибутов тегов до их дальнейшей обработки. Если серверное приложение блокирует или санитизирует некоторые символы, необходимые для успешной XSS‑эксплуатации, нередко можно обойти проверку, закодировав эти символы в HTML‑сущности.
Например, если контекст XSS следующий:
И приложение блокирует или экранирует одиночные кавычки, вы можете использовать такую полезную нагрузку, чтобы вырваться из строкового литерала JavaScript и выполнить свой скрипт:
Последовательность ' — это HTML‑сущность, представляющая апостроф или одиночную кавычку. Поскольку браузер HTML‑декодирует значение атрибута onclick до интерпретации JavaScript, сущности декодируются в кавычки, которые становятся разделителями строк, и атака срабатывает.
XSS в шаблонных литералах JavaScript
Шаблонные литералы JavaScript — это строковые литералы, допускающие встраивание JavaScript‑выражений. Встроенные выражения вычисляются и обычно конкатенируются с окружающим текстом. Шаблонные литералы заключаются в обратные апострофы вместо обычных кавычек, а встроенные выражения обозначаются синтаксисом ${...}.
Например, следующий скрипт выведет приветственное сообщение, включающее отображаемое имя пользователя:
Когда контекст XSS — внутри шаблонного литерала JavaScript, нет необходимости завершать литерал. Вместо этого достаточно использовать синтаксис ${...}, чтобы встроить JavaScript‑выражение, которое будет выполнено при обработке литерала. Например, если контекст XSS следующий:
То вы можете использовать такую полезную нагрузку, чтобы выполнить JavaScript, не завершая шаблонный литерал:
XSS через инъекцию клиентских шаблонов
Некоторые сайты используют клиентские шаблонные фреймворки, например AngularJS, для динамической отрисовки веб‑страниц. Если они внедряют пользовательский ввод в эти шаблоны небезопасным образом, атакующий может внедрять собственные вредоносные выражения шаблонов, запускающие XSS‑атаку.
Last updated