XSS (Cross Site Scripting)
Якщо вас цікавить кар'єра в хакерстві і ви хочете зламати незламне - ми наймаємо! (вимагається вільне володіння польською мовою в письмовій та усній формі).
Методологія
Перевірте, чи будь-яке значення, яке ви контролюєте (параметри, шлях, заголовки?, куки?) відображається в HTML або використовується кодом JS.
Знайдіть контекст, де воно відображається/використовується.
Якщо відображається
Перевірте, які символи ви можете використовувати і, залежно від цього, підготуйте payload:
У сирому HTML:
Чи можете ви створити нові HTML теги?
Чи можете ви використовувати події або атрибути, що підтримують протокол
javascript:
?Чи можете ви обійти захист?
Чи інтерпретується HTML контент будь-яким клієнтським JS двигуном (AngularJS, VueJS, Mavo...), ви могли б зловживати Client Side Template Injection.
Якщо ви не можете створити HTML теги, які виконують JS код, чи могли б ви зловживати Dangling Markup - HTML scriptless injection?
Всередині HTML тегу:
Чи можете ви вийти в контекст сирого HTML?
Чи можете ви створити нові події/атрибути для виконання JS коду?
Чи підтримує атрибут, в якому ви застрягли, виконання JS?
Чи можете ви обійти захист?
Всередині JavaScript коду:
Чи можете ви втекти з тегу
<script>
?Чи можете ви втекти з рядка і виконати різний JS код?
Чи ваші введення в шаблонних літералах ``?
Чи можете ви обійти захист?
Javascript функція, що виконується
Ви можете вказати ім'я функції для виконання. наприклад:
?callback=alert(1)
Якщо використовується:
Ви могли б експлуатувати DOM XSS, зверніть увагу на те, як контролюється ваше введення і чи використовується ваше контрольоване введення будь-яким sink.
Коли ви працюєте над складним XSS, вам може бути цікаво дізнатися про:
Debugging Client Side JSВідображені значення
Щоб успішно експлуатувати XSS, перше, що вам потрібно знайти, це значення, контрольоване вами, яке відображається на веб-сторінці.
Проміжно відображене: Якщо ви виявите, що значення параметра або навіть шлях відображається на веб-сторінці, ви могли б експлуатувати Reflected XSS.
Збережене та відображене: Якщо ви виявите, що значення, контрольоване вами, зберігається на сервері і відображається щоразу, коли ви отримуєте доступ до сторінки, ви могли б експлуатувати Stored XSS.
Доступне через JS: Якщо ви виявите, що значення, контрольоване вами, доступне за допомогою JS, ви могли б експлуатувати DOM XSS.
Контексти
Коли ви намагаєтеся експлуатувати XSS, перше, що вам потрібно знати, це де відображається ваше введення. Залежно від контексту, ви зможете виконати довільний JS код різними способами.
Сирий HTML
Якщо ваше введення відображається на сирій HTML сторінці, вам потрібно буде зловживати деяким HTML тегом, щоб виконати JS код: <img , <iframe , <svg , <script
... це лише деякі з багатьох можливих HTML тегів, які ви могли б використовувати.
Також пам'ятайте про Client Side Template Injection.
Всередині атрибута HTML тегу
Якщо ваше введення відображається всередині значення атрибута тегу, ви могли б спробувати:
Втекти з атрибута і з тегу (тоді ви будете в сирому HTML) і створити новий HTML тег для зловживання:
"><img [...]
Якщо ви можете втекти з атрибута, але не з тегу (
>
закодовано або видалено), залежно від тегу ви могли б створити подію, яка виконує JS код:" autofocus onfocus=alert(1) x="
Якщо ви не можете втекти з атрибута (
"
закодовано або видалено), тоді залежно від якого атрибута ваше значення відображається, якщо ви контролюєте все значення або лише частину, ви зможете зловживати цим. Наприклад, якщо ви контролюєте подію, таку якonclick=
, ви зможете змусити її виконати довільний код, коли на неї натиснуть. Інший цікавий приклад - атрибутhref
, де ви можете використовувати протоколjavascript:
, щоб виконати довільний код:href="javascript:alert(1)"
Якщо ваше введення відображається всередині "незловживаних тегів", ви могли б спробувати трюк з
accesskey
, щоб зловживати вразливістю (вам знадобиться певний вид соціальної інженерії для експлуатації цього):" accesskey="x" onclick="alert(1)" x="
Дивний приклад Angular, що виконує XSS, якщо ви контролюєте ім'я класу:
Inside JavaScript code
В цьому випадку ваш ввід відображається між <script> [...] </script>
тегами HTML-сторінки, всередині .js
файлу або всередині атрибута, використовуючи javascript:
протокол:
Якщо відображається між
<script> [...] </script>
тегами, навіть якщо ваш ввід знаходиться всередині будь-яких лапок, ви можете спробувати ввести</script>
і вийти з цього контексту. Це працює, тому що браузер спочатку розбирає HTML теги і лише потім вміст, тому він не помітить, що ваш введений</script>
тег знаходиться всередині HTML коду.Якщо відображається всередині JS рядка і останній трюк не працює, вам потрібно буде вийти з рядка, виконати ваш код і відновити JS код (якщо є помилка, він не буде виконаний):
'-alert(1)-'
';-alert(1)//
\';alert(1)//
Якщо відображається всередині шаблонних літералів, ви можете вбудувати JS вирази за допомогою синтаксису
${ ... }
:var greetings = `Hello, ${alert(1)}`
Unicode кодування працює для написання дійсного javascript коду:
Javascript Hoisting
Javascript Hoisting посилається на можливість оголошувати функції, змінні або класи після їх використання, щоб ви могли зловживати сценаріями, де XSS використовує неоголошені змінні або функції. Перевірте наступну сторінку для отримання додаткової інформації:
JS HoistingJavascript Function
Кілька веб-сторінок мають кінцеві точки, які приймають як параметр ім'я функції для виконання. Загальний приклад, який можна побачити в реальному житті, це щось на зразок: ?callback=callbackFunc
.
Хороший спосіб дізнатися, чи намагається виконати щось, що надано безпосередньо користувачем, це змінити значення параметра (наприклад, на 'Vulnerable') і подивитися в консолі на помилки, такі як:
У разі, якщо це вразливо, ви могли б викликати сповіщення, просто надіславши значення: ?callback=alert(1)
. Однак, дуже поширено, що ці кінцеві точки перевіряють вміст, щоб дозволити лише літери, цифри, крапки та підкреслення ([\w\._]
).
Однак, навіть з цим обмеженням, все ще можливо виконати деякі дії. Це пов'язано з тим, що ви можете використовувати ці допустимі символи, щоб отримати доступ до будь-якого елемента в DOM:
Деякі корисні функції для цього:
Ви також можете спробувати викликати функції Javascript безпосередньо: obj.sales.delOrders
.
Однак, зазвичай кінцеві точки, що виконують вказану функцію, є кінцевими точками без особливо цікавого DOM, інші сторінки в тому ж походженні матимуть більш цікавий DOM для виконання більшої кількості дій.
Тому, щоб зловживати цією вразливістю в іншому DOM, була розроблена експлуатація Same Origin Method Execution (SOME):
SOME - Same Origin Method ExecutionDOM
Є JS код, який недобросовісно використовує деякі дані, контрольовані зловмисником, такі як location.href
. Зловмисник може зловживати цим для виконання довільного JS коду.
Універсальний XSS
Ці види XSS можуть бути знайдені де завгодно. Вони залежать не лише від експлуатації клієнта веб-додатку, але й від будь-якого контексту. Ці види довільного виконання JavaScript можуть навіть бути використані для отримання RCE, читання довільних файлів на клієнтах і серверах, і більше. Деякі приклади:
Server Side XSS (Dynamic PDF)Electron Desktop AppsОбхід WAF кодування зображення
Впровадження всередині сирого HTML
Коли ваш ввід відображається всередині HTML-сторінки або ви можете втекти і впровадити HTML-код у цьому контексті, перше, що вам потрібно зробити, це перевірити, чи можете ви зловживати <
, щоб створити нові теги: просто спробуйте відобразити цей символ і перевірте, чи він HTML-кодований або видалений, або чи він відображається без змін. Тільки в останньому випадку ви зможете експлуатувати цей випадок.
Для цих випадків також майте на увазі Client Side Template Injection.
Примітка: HTML-коментар може бути закритий за допомогою******** -->
або ****--!>
У цьому випадку, якщо не використовується чорний/білий список, ви можете використовувати пейлоади, такі як:
Але, якщо використовується чорний/білий список тегів/атрибутів, вам потрібно буде виконати брутфорс, які теги ви можете створити. Коли ви знайдете, які теги дозволені, вам потрібно буде виконати брутфорс атрибутів/подій всередині знайдених дійсних тегів, щоб побачити, як ви можете атакувати контекст.
Брутфорс тегів/подій
Перейдіть на https://portswigger.net/web-security/cross-site-scripting/cheat-sheet і натисніть на Скопіювати теги в буфер обміну. Потім надішліть їх усі за допомогою Burp intruder і перевірте, чи не було виявлено жодного тегу як шкідливий WAF. Коли ви виявите, які теги ви можете використовувати, ви можете виконати брутфорс усіх подій за допомогою дійсних тегів (на тій же веб-сторінці натисніть на Скопіювати події в буфер обміну і дотримуйтесь тієї ж процедури, що й раніше).
Користувацькі теги
Якщо ви не знайшли жодного дійсного HTML тегу, ви можете спробувати створити користувацький тег і виконати JS код з атрибутом onfocus
. У запиті XSS вам потрібно закінчити URL на #
, щоб змусити сторінку зосередитися на цьому об'єкті і виконати код:
Blacklist Bypasses
Якщо використовується якийсь вид чорного списку, ви можете спробувати обійти його за допомогою кількох дурних трюків:
Length bypass (small XSSs)
Більше маленьких XSS для різних середовищ payload можна знайти тут і тут.
Останній використовує 2 символи юнікоду, які розширюються до 5: telsr Більше таких символів можна знайти тут. Щоб перевірити, в які символи вони розкладаються, перевірте тут.
Click XSS - Clickjacking
Якщо для експлуатації вразливості вам потрібно, щоб користувач натиснув на посилання або форму з попередньо заповненими даними, ви можете спробувати зловживати Clickjacking (якщо сторінка вразлива).
Неможливо - Dangling Markup
Якщо ви просто вважаєте, що неможливо створити HTML-тег з атрибутом для виконання JS-коду, вам слід перевірити Dangling Markup, оскільки ви можете експлуатувати вразливість без виконання JS коду.
Впровадження всередині HTML-тегу
Всередині тегу/вихід з значення атрибута
Якщо ви всередині HTML-тегу, перше, що ви можете спробувати, це вийти з тегу та використати деякі з технік, згаданих у попередньому розділі, щоб виконати JS-код. Якщо ви не можете вийти з тегу, ви можете створити нові атрибути всередині тегу, щоб спробувати виконати JS-код, наприклад, використовуючи деякі корисні дані, як (зауважте, що в цьому прикладі подвійні лапки використовуються для виходу з атрибута, вам не знадобляться вони, якщо ваш ввід відображається безпосередньо всередині тегу):
Стилі подій
Всередині атрибута
Навіть якщо ви не можете вийти з атрибута ("
кодується або видаляється), в залежності від того, який атрибут відображає ваше значення якщо ви контролюєте все значення або лише частину ви зможете це зловживати. Наприклад, якщо ви контролюєте подію, таку як onclick=
, ви зможете змусити її виконати довільний код, коли на неї натиснуть.
Ще один цікавий приклад - атрибут href
, де ви можете використовувати протокол javascript:
для виконання довільного коду: href="javascript:alert(1)"
Обхід всередині події за допомогою HTML кодування/URL кодування
HTML закодовані символи всередині значення атрибутів HTML тегів декодуються під час виконання. Тому щось на зразок наступного буде дійсним (payload виділено жирним): <a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Повернутися </a>
Зверніть увагу, що будь-яке HTML кодування є дійсним:
Зверніть увагу, що URL кодування також буде працювати:
Обхід внутрішньої події за допомогою кодування Unicode
Спеціальні протоколи в атрибуті
Тут ви можете використовувати протоколи javascript:
або data:
в деяких місцях для виконання довільного JS коду. Деякі з них вимагатимуть взаємодії з користувачем, а деякі - ні.
Місця, де ви можете впроваджувати ці протоколи
В загальному протокол javascript:
може бути використаний в будь-якому тегу, який приймає атрибут href
та в більшості тегів, які приймають атрибут src
(але не <img>
)
Інші трюки обфускації
У цьому випадку трюк з HTML-кодуванням та кодуванням Unicode з попереднього розділу також дійсний, оскільки ви знаходитесь всередині атрибута.
Крім того, є ще один гарний трюк для цих випадків: Навіть якщо ваш ввід всередині javascript:...
кодується в URL, він буде декодований перед виконанням. Тож, якщо вам потрібно вийти з рядка, використовуючи одинарну лапку, і ви бачите, що він кодується в URL, пам'ятайте, що це не має значення, він буде інтерпретований як одинарна лапка під час виконання.
Зверніть увагу, що якщо ви спробуєте використати обидва URLencode + HTMLencode
в будь-якому порядку для кодування payload, це не спрацює, але ви можете змішувати їх всередині payload.
Використання Hex та Octal кодування з javascript:
Ви можете використовувати Hex та Octal кодування всередині атрибута src
iframe
(принаймні) для оголошення HTML тегів для виконання JS:
Зворотне таб-навигування
Якщо ви можете вставити будь-яке URL в довільний <a href=
тег, який містить атрибути target="_blank" і rel="opener"
, перевірте наступну сторінку для використання цієї поведінки:
обхід обробників подій
По-перше, перевірте цю сторінку (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) для корисних "on" обробників подій. У разі, якщо існує якийсь чорний список, який заважає вам створювати ці обробники подій, ви можете спробувати наступні обходи:
XSS в "Неексплуатованих тегах" (прихований ввід, посилання, канонічний, мета)
З тут тепер можливо зловживати прихованими ввідними даними з:
І в meta тегах:
З тут: Ви можете виконати XSS payload всередині прихованого атрибута, якщо зможете переконати жертву натиснути комбінацію клавіш. У Firefox Windows/Linux комбінація клавіш - ALT+SHIFT+X, а на OS X - CTRL+ALT+X. Ви можете вказати іншу комбінацію клавіш, використовуючи іншу клавішу в атрибуті доступу. Ось вектор:
Payload XSS буде щось на зразок цього: " accesskey="x" onclick="alert(1)" x="
Обхід чорного списку
Кілька трюків з використанням різного кодування вже були розкриті в цьому розділі. Поверніться назад, щоб дізнатися, де ви можете використовувати:
HTML кодування (HTML теги)
Unicode кодування (може бути дійсним JS кодом):
\u0061lert(1)
URL кодування
Шістнадцяткове та вісімкове кодування
кодування даних
Обходи для HTML тегів та атрибутів
Прочитайте Обходи чорного списку попереднього розділу.
Обходи для JavaScript коду
Прочитайте чорний список обходів JavaScript наступного розділу.
CSS-Гаджети
Якщо ви знайшли XSS у дуже маленькій частині вебу, яка вимагає певної взаємодії (можливо, маленьке посилання в нижньому колонтитулі з елементом onmouseover), ви можете спробувати модифікувати простір, який займає цей елемент, щоб максимізувати ймовірність активації посилання.
Наприклад, ви могли б додати деяке стилювання в елемент, як: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5
Але, якщо WAF фільтрує атрибут стилю, ви можете використовувати CSS Стилізаційні Гаджети, тому, якщо ви знайдете, наприклад
.test {display:block; color: blue; width: 100%}
та
#someid {top: 0; font-family: Tahoma;}
Тепер ви можете модифікувати наше посилання і привести його до форми
<a href="" id=someid class=test onclick=alert() a="">
Цей трюк був взятий з https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703
Впровадження всередині JavaScript коду
У цих випадках ваш вхід буде відображено всередині JS коду файлу .js
або між тегами <script>...</script>
або між HTML подіями, які можуть виконувати JS код, або між атрибутами, які приймають протокол javascript:
.
Вихід з <script> тегу
Якщо ваш код вставлений у <script> [...] var input = 'відображені дані' [...] </script>
, ви могли б легко вийти, закривши тег <script>
:
Зверніть увагу, що в цьому прикладі ми навіть не закрили одинарну лапку. Це тому, що парсинг HTML спочатку виконується браузером, що включає в себе ідентифікацію елементів сторінки, включаючи блоки скриптів. Парсинг JavaScript для розуміння та виконання вбудованих скриптів виконується лише пізніше.
Всередині коду JS
Якщо <>
очищуються, ви все ще можете втекти рядок, де ваше введення знаходиться і виконати довільний JS. Важливо виправити синтаксис JS, тому що якщо є будь-які помилки, код JS не буде виконано:
Template literals ``
Щоб створити рядки окрім одинарних і подвійних лапок, JS також приймає зворотні лапки ``
. Це відомо як шаблонні літерали, оскільки вони дозволяють вбудовані JS вирази з використанням синтаксису ${ ... }
.
Отже, якщо ви виявите, що ваш ввід відображається всередині JS рядка, який використовує зворотні лапки, ви можете зловживати синтаксисом ${ ... }
, щоб виконати произвольний JS код:
Це можна зловживати за допомогою:
Закодоване виконання коду
Unicode Encode JS execution
Техніки обхід чорних списків JavaScript
Рядки
Спеціальні ескейпи
Заміни пробілів всередині JS коду
Коментарі JavaScript (з Коментарі JavaScript трик)
JavaScript нові рядки (з JavaScript новий рядок трик)
Пробіли в JavaScript
Javascript всередині коментаря
JavaScript без дужок