Learn & practice AWS Hacking:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
Learn & practice GCP Hacking: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
CSS селектори створені для відповідності значенням атрибутів `name` та `value` елемента `input`. Якщо атрибут значення елемента введення починається з певного символу, завантажується попередньо визначений зовнішній ресурс:
Однак цей підхід стикається з обмеженням при роботі з прихованими елементами введення (`type="hidden"`), оскільки приховані елементи не завантажують фони.
Щоб обійти це обмеження, ви можете націлитися на наступний елемент-сibling, використовуючи комбінацію загального sibling `~`. Правило CSS тоді застосовується до всіх sibling, що йдуть після прихованого елемента введення, змушуючи фонове зображення завантажуватися:
Практичний приклад використання цієї техніки детально описаний у наданому фрагменті коду. Ви можете переглянути його [тут](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
1.**Довжина Payload**: Вектор CSS injection повинен підтримувати достатньо довгі payload для розміщення створених селекторів.
2.**Повторна оцінка CSS**: Ви повинні мати можливість оформити сторінку, що необхідно для виклику повторної оцінки CSS з новоствореними payload.
3.**Зовнішні ресурси**: Техніка передбачає можливість використання зовнішньо розміщених зображень. Це може бути обмежено політикою безпеки контенту (CSP) сайту.
Як [**пояснено в цьому пості**](https://portswigger.net/research/blind-css-exfiltration), можливо поєднати селектори **`:has`** і**`:not`** для ідентифікації контенту навіть з сліпих елементів. Це дуже корисно, коли ви не знаєте, що знаходиться всередині веб-сторінки, що завантажує CSS injection.\
Також можливо використовувати ці селектори для витягування інформації з кількох блоків одного типу, як у:
Об'єднуючи це з наступною технікою **@import**, можливо ексфільтрувати багато **інформації за допомогою CSS-ін'єкції з сліпих сторінок з** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
Попередня техніка має деякі недоліки, перевірте вимоги. Вам потрібно або**надіслати кілька посилань жертві**, або ви повинні мати можливість **вставити в iframe сторінку, вразливу до CSS-ін'єкції**.
Замість того, щоб завантажувати одну й ту ж сторінку знову і знову з десятками різних корисних навантажень щоразу (як у попередньому випадку), ми будемо **завантажувати сторінку лише один раз і лише з імпортом на сервер зловмисника** (це корисне навантаження, яке потрібно надіслати жертві):
1. Імпорт буде **отримувати деякий CSS скрипт** від атакуючих, і**браузер його завантажить**.
2. Перша частина CSS скрипту, яку надішле атакуючий, буде **іншим `@import` на сервер атакуючих знову.**
1. Сервер атакуючих поки не відповість на цей запит, оскільки ми хочемо витікати деякі символи, а потім відповісти на цей імпорт з корисним навантаженням, щоб витікати наступні.
3. Друга і більша частина корисного навантаження буде **корисним навантаженням для витоку селектора атрибутів**
1. Це надішле на сервер атакуючих **перший символ секрету і останній**
4. Як тільки сервер атакуючих отримає **перший і останній символ секрету**, він **відповість на імпорт, запитаний на кроці 2**.
1. Відповідь буде точно такою ж, як **кроки 2, 3 і 4**, але цього разу він спробує **знайти другий символ секрету, а потім передостанній**.
Ви можете знайти оригінальний [**код Пепе Віли для експлуатації цього тут**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) або ви можете знайти майже [**той же код, але з коментарями тут**.](./#css-injection)
Іноді скрипт **неправильно визначає, що префікс + суфікс, що було виявлено, вже є повним флагом**і продовжить рухатися вперед (в префіксі) і назад (в суфіксі), і в якийсь момент він зависне.\
Не хвилюйтеся, просто перевірте **вихідні дані**, тому що **ви можете побачити флаг там**.
* **`.class-to-search:nth-child(2)`**: Це буде шукати другий елемент з класом "class-to-search" в DOM.
***`:empty`** селектор: Використовується, наприклад, у [**цьому описі**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:**
**Посилання:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
Загальна мета полягає в тому, щоб **використовувати власний шрифт з контрольованої точки доступу**і забезпечити, щоб **текст (в даному випадку, 'A') відображався цим шрифтом лише в тому випадку, якщо вказаний ресурс (`favicon.ico`) не може бути завантажений**.
Псевдоклас **`:target`** використовується для вибору елемента, на який націлений **фрагмент URL**, як зазначено в [специфікації CSS Selectors Level 4](https://drafts.csswg.org/selectors-4/#the-target-pseudo). Важливо розуміти, що `::target-text` не відповідає жодним елементам, якщо текст не націлений явно фрагментом.
Проблема безпеки виникає, коли зловмисники експлуатують функцію **Scroll-to-text** фрагмента, що дозволяє їм підтвердити наявність конкретного тексту на веб-сторінці, завантажуючи ресурс з їхнього сервера через HTML-ін'єкцію. Метод полягає в ін'єкції CSS правила, як це:
У таких сценаріях, якщо текст "Administrator" присутній на сторінці, ресурс`target.png` запитується з сервера, що вказує на наявність тексту. Приклад цієї атаки можна виконати через спеціально підготовлене URL, яке вбудовує ін'єкційний CSS разом з фрагментом Scroll-to-text:
Тут атака маніпулює HTML-ін'єкцією для передачі CSS-коду, націлюючись на конкретний текст "Administrator" через фрагмент Scroll-to-text (`#:~:text=Administrator`). Якщо текст знайдено, вказаний ресурс завантажується, ненавмисно сигналізуючи про свою присутність атакуючому.
1.**Обмежене відповідність STTF**: Фрагмент Scroll-to-text (STTF) призначений для відповідності лише словам або реченням, тим самим обмежуючи його здатність витікати довільні секрети або токени.
2.**Обмеження до верхнього рівня контекстів перегляду**: STTF працює виключно в контекстах верхнього рівня перегляду і не функціонує в iframe, що робить будь-яку спробу експлуатації більш помітною для користувача.
3.**Необхідність активації користувачем**: STTF вимагає жесту активації користувача для роботи, що означає, що експлуатації можливі лише через ініційовану користувачем навігацію. Ця вимога значно зменшує ризик автоматизації атак без взаємодії з користувачем. Проте автор блогу вказує на специфічні умови та обходи (наприклад, соціальна інженерія, взаємодія з поширеними розширеннями браузера), які можуть полегшити автоматизацію атаки.
Для отримання додаткової інформації перегляньте оригінальний звіт: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)
Ви можете вказати **зовнішні шрифти для конкретних значень unicode**, які будуть **збиратися лише якщо ці значення unicode присутні** на сторінці. Наприклад:
When you access this page, Chrome and Firefox fetch "?A" and "?B" because text node of sensitive-information contains "A" and "B" characters. But Chrome and Firefox do not fetch "?C" because it does not contain "C". This means that we have been able to read "A" and "B".
**Reference:** [Викрадення даних у чудовому стилі – тобто як використовувати CSS для атак на вебдодатки](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)
The technique described involves extracting text from a node by exploiting font ligatures and monitoring changes in width. The process involves several steps:
- CSS is used to ensure that text does not wrap (`white-space: nowrap`) and to customize the scrollbar style.
- The appearance of a horizontal scrollbar, styled distinctly, acts as an indicator (oracle) that a specific ligature, and hence a specific character sequence, is present in the text.
- **Step 1**: Fonts are created for pairs of characters with substantial width.
- **Step 2**: A scrollbar-based trick is employed to detect when the large width glyph (ligature for a character pair) is rendered, indicating the presence of the character sequence.
- **Step 3**: Upon detecting a ligature, new glyphs representing three-character sequences are generated, incorporating the detected pair and adding a preceding or succeeding character.
- **Step 4**: Detection of the three-character ligature is carried out.
- **Step 5**: The process repeats, progressively revealing the entire text.
### Text node exfiltration (II): leaking the charset with a default font (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
This trick was released in this [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what\_can\_we\_do\_with\_single\_css\_injection/). The charset used in a text node can be leaked **using the default fonts** installed in the browser: no external -or custom- fonts are needed.
The concept revolves around utilizing an animation to incrementally expand a `div`'s width, allowing one character at a time to transition from the 'suffix' part of the text to the 'prefix' part. This process effectively splits the text into two sections:
During this transition, the **unicode-range trick** is employed to identify each new character as it joins the prefix. This is achieved by switching the font to Comic Sans, which is notably taller than the default font, consequently triggering a vertical scrollbar. This scrollbar's appearance indirectly reveals the presence of a new character in the prefix.
Although this method allows the detection of unique characters as they appear, it does not specify which character is repeated, only that a repetition has occurred.
Basically, the **unicode-range is used to detect a char**, but as we don't want to load an external font, we need to find another way.\
When the **char** is **found**, it's **given** the pre-installed **Comic Sans font**, which **makes** the char **bigger** and **triggers a scroll bar** which will **leak the found char**.
### Text node exfiltration (III): витік кодування з використанням шрифту за замовчуванням шляхом приховування елементів (не вимагає зовнішніх ресурсів) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
Цей випадок дуже схожий на попередній, однак у цьому випадку мета зробити конкретні **символи більшими за інші, щоб приховати щось** на кшталт кнопки, щоб її не натиснув бот, або зображення, яке не буде завантажено. Таким чином, ми могли б виміряти дію (або відсутність дії) і дізнатися, чи присутній конкретний символ у тексті.
### Text node exfiltration (III): витік кодування за допомогою таймінгу кешу (не вимагає зовнішніх ресурсів) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
Якщо є збіг, **шрифт буде завантажено з `/static/bootstrap.min.css?q=1`**. Хоча він не завантажиться успішно, **браузер повинен його кешувати**, і навіть якщо кешу немає, існує механізм **304 not modified**, тому **відповідь повинна бути швидшою** за інші.
Однак, якщо різниця в часі між кешованою відповіддю та некешованою не є достатньо великою, це не буде корисно. Наприклад, автор зазначив: Однак, після тестування, я виявив, що перша проблема полягає в тому, що швидкість не дуже відрізняється, а друга проблема в тому, що бот використовує прапор `disk-cache-size=1`, що дійсно продумано.
### Витік текстового вузла (III): витік кодування символів шляхом вимірювання часу завантаження сотень локальних "шрифтів" (не вимагаючи зовнішніх ресурсів) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
У цьому випадку ви можете вказати **CSS для завантаження сотень фальшивих шрифтів** з того ж походження, коли відбувається збіг. Таким чином, ви можете **виміряти час**, який це займає, і дізнатися, чи з'являється символ, чи ні, за допомогою чогось на кшталт:
Отже, якщо шрифт не збігається, час відповіді при відвідуванні бота очікується приблизно 30 секунд. Однак, якщо є збіг шрифтів, буде надіслано кілька запитів для отримання шрифту, що призведе до постійної активності в мережі. Як наслідок, знадобиться більше часу для задоволення умови зупинки та отримання відповіді. Тому час відповіді можна використовувати як індикатор для визначення, чи є збіг шрифтів.
Learn & practice AWS Hacking:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
Learn & practice GCP Hacking: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.