diff --git a/src/pentesting-web/xxe-xee-xml-external-entity.md b/src/pentesting-web/xxe-xee-xml-external-entity.md index a8077871a..934f78aa3 100644 --- a/src/pentesting-web/xxe-xee-xml-external-entity.md +++ b/src/pentesting-web/xxe-xee-xml-external-entity.md @@ -1,10 +1,5 @@ # XXE - XEE - XML External Entity -{{#include /banners/hacktricks-training.md}} - -- [Dojo CTF Challenge #42 – Hex Color Palette XXE write-up](https://www.yeswehack.com/dojo/dojo-ctf-challenge-winners-42) -- [lxml bug #2107279 – Parameter-entity XXE still possible](https://bugs.launchpad.net/lxml/+bug/2107279) - {{#include ../banners/hacktricks-training.md}} ## XML Основи @@ -88,7 +83,7 @@ XXE може бути використано для зловживання SSRF ``` ### Blind SSRF -Використовуючи **раніше прокоментовану техніку**, ви можете змусити сервер отримати доступ до сервера, який ви контролюєте, щоб показати, що він вразливий. Але, якщо це не працює, можливо, це тому, що **XML-ентитети не дозволені**, в такому випадку ви можете спробувати використовувати **XML-параметричні ентитети**: +Використовуючи **раніше згадану техніку**, ви можете змусити сервер отримати доступ до сервера, який ви контролюєте, щоб показати, що він вразливий. Але, якщо це не працює, можливо, це тому, що **XML-ентитети не дозволені**, в такому випадку ви можете спробувати використовувати **XML-параметричні ентитети**: ```xml %xxe; ]> @@ -102,7 +97,7 @@ XXE може бути використано для зловживання SSRF ### Приклад шкідливого DTD: -Структура така: +Структура виглядає наступним чином: ```xml "> @@ -112,11 +107,11 @@ XXE може бути використано для зловживання SSRF Кроки, виконані цим DTD, включають: 1. **Визначення параметричних сутностей:** -- Створюється XML параметрична сутність, `%file`, яка читає вміст файлу `/etc/hostname`. -- Визначається інша XML параметрична сутність, `%eval`. Вона динамічно оголошує нову XML параметричну сутність, `%exfiltrate`. Сутність `%exfiltrate` налаштована на виконання HTTP запиту до сервера атакуючого, передаючи вміст сутності `%file` у рядку запиту URL. +- XML параметрична сутність, `%file`, створюється, читаючи вміст файлу `/etc/hostname`. +- Інша XML параметрична сутність, `%eval`, визначається. Вона динамічно оголошує нову XML параметричну сутність, `%exfiltrate`. Сутність `%exfiltrate` налаштовується на виконання HTTP запиту до сервера атакуючого, передаючи вміст сутності `%file` у рядку запиту URL. 2. **Виконання сутностей:** -- Використовується сутність `%eval`, що призводить до виконання динамічного оголошення сутності `%exfiltrate`. -- Потім використовується сутність `%exfiltrate`, що викликає HTTP запит до вказаного URL з вмістом файлу. +- Сутність `%eval` використовується, що призводить до виконання динамічного оголошення сутності `%exfiltrate`. +- Сутність `%exfiltrate` потім використовується, що викликає HTTP запит до вказаного URL з вмістом файлу. Атакуючий розміщує цей шкідливий DTD на сервері під своїм контролем, зазвичай за URL на кшталт `http://web-attacker.com/malicious.dtd`. @@ -126,7 +121,7 @@ XXE може бути використано для зловживання SSRF %xxe;]> 3;1 ``` -Цей payload визначає XML параметричну сутність `%xxe` і включає її в DTD. Коли її обробляє XML парсер, цей payload отримує зовнішній DTD з сервера зловмисника. Парсер потім інтерпретує DTD вбудовано, виконуючи кроки, викладені в шкідливому DTD, що призводить до ексфільтрації файлу `/etc/hostname` на сервер зловмисника. +Цей payload визначає XML параметричну сутність `%xxe` і включає її в DTD. Коли її обробляє XML парсер, цей payload отримує зовнішній DTD з сервера атакуючого. Парсер потім інтерпретує DTD вбудовано, виконуючи кроки, викладені в шкідливому DTD, що призводить до ексфільтрації файлу `/etc/hostname` на сервер атакуючого. ### Помилка на основі (Зовнішній DTD) @@ -153,7 +148,7 @@ _**Зверніть увагу, що зовнішній DTD дозволяє н ### **Помилка на основі (системний DTD)** -Отже, що стосується сліпих вразливостей XXE, коли **взаємодії поза каналом заблоковані** (зовнішні з'єднання недоступні)? +А що щодо сліпих вразливостей XXE, коли **взаємодії поза каналом заблоковані** (зовнішні з'єднання недоступні)? Лазівка в специфікації мови XML може **викрити чутливі дані через повідомлення про помилки, коли DTD документа поєднує внутрішні та зовнішні декларації**. Ця проблема дозволяє внутрішню перезапис сутностей, оголошених зовні, що полегшує виконання атак XXE на основі помилок. Такі атаки експлуатують перезапис сутності параметра XML, спочатку оголошеного в зовнішньому DTD, зсередини внутрішнього DTD. Коли з'єднання поза каналом заблоковані сервером, зловмисники повинні покладатися на локальні файли DTD для проведення атаки, намагаючись викликати помилку парсингу, щоб розкрити чутливу інформацію. @@ -172,11 +167,11 @@ _**Зверніть увагу, що зовнішній DTD дозволяє н ``` Описані кроки виконуються цим DTD: -- Визначення XML параметричної сутності з назвою `local_dtd` включає зовнішній DTD файл, розташований на файловій системі сервера. +- Визначення XML параметричної сутності з ім'ям `local_dtd` включає зовнішній DTD файл, розташований на файловій системі сервера. - Відбувається повторне визначення для XML параметричної сутності `custom_entity`, спочатку визначеної у зовнішньому DTD, щоб інкапсулювати [експлойт XXE на основі помилок](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages). Це повторне визначення призначене для викликання помилки парсингу, що відкриває вміст файлу `/etc/passwd`. - Використовуючи сутність `local_dtd`, залучається зовнішній DTD, що охоплює нововизначену `custom_entity`. Ця послідовність дій призводить до виникнення повідомлення про помилку, яке є метою експлойту. -**Приклад з реального життя:** Системи, що використовують середовище робочого столу GNOME, часто мають DTD за адресою `/usr/share/yelp/dtd/docbookx.dtd`, що містить сутність з назвою `ISOamso`. +**Приклад з реального життя:** Системи, що використовують середовище робочого столу GNOME, часто мають DTD за адресою `/usr/share/yelp/dtd/docbookx.dtd`, що містить сутність з ім'ям `ISOamso`. ```xml ) -Оскільки ця техніка використовує **внутрішній DTD, спочатку потрібно знайти дійсний**. Ви можете зробити це, **встановивши** ту ж **ОС / програмне забезпечення**, що використовує сервер, і **шукаючи деякі стандартні DTD**, або **отримавши список** **стандартних DTD** в системах і **перевіривши**, чи існує хоча б один з них: +Оскільки ця техніка використовує **внутрішній DTD, спочатку потрібно знайти дійсний**. Ви можете зробити це, **встановивши** ту ж **ОС / програмне забезпечення**, яке використовує сервер, і **шукаючи деякі стандартні DTD**, або **отримавши список** **стандартних DTD** в системах і **перевіривши**, чи існує хоча б один з них: ```xml %local_dtd; ]> ``` -Для отримання додаткової інформації перегляньте [https://portswigger.net/web-security/xxe/blind](https://portswigger.net/web-security/xxe/blind) +Для отримання додаткової інформації перевірте [https://portswigger.net/web-security/xxe/blind](https://portswigger.net/web-security/xxe/blind) ### Пошук DTD у системі @@ -226,11 +221,11 @@ Testing 0 entities : [] Для більш детального пояснення цієї атаки, **перегляньте другий розділ** [**цього чудового посту**](https://labs.detectify.com/2021/09/15/obscure-xxe-attacks/) **від Detectify**. -Можливість **завантажувати документи Microsoft Office пропонується багатьма веб-додатками**, які потім витягують певні деталі з цих документів. Наприклад, веб-додаток може дозволити користувачам імпортувати дані, завантажуючи електронну таблицю у форматі XLSX. Щоб парсер зміг витягти дані з електронної таблиці, йому неминуче потрібно буде розпарсити принаймні один XML файл. +Можливість **завантажувати документи Microsoft Office пропонується багатьма веб-додатками**, які потім продовжують витягувати певні деталі з цих документів. Наприклад, веб-додаток може дозволити користувачам імпортувати дані, завантажуючи електронну таблицю у форматі XLSX. Щоб парсер зміг витягти дані з електронної таблиці, йому неминуче потрібно буде проаналізувати принаймні один XML файл. Щоб перевірити цю вразливість, необхідно створити **файл Microsoft Office, що містить XXE payload**. Першим кроком є створення порожньої директорії, в яку документ може бути розпакований. -Після того, як документ буде розпакований, XML файл, розташований за адресою `./unzipped/word/document.xml`, слід відкрити та відредагувати у вибраному текстовому редакторі (наприклад, vim). XML слід змінити, щоб включити бажаний XXE payload, часто починаючи з HTTP запиту. +Після розпакування документа, XML файл, розташований за адресою `./unzipped/word/document.xml`, слід відкрити та відредагувати в улюбленому текстовому редакторі (наприклад, vim). XML слід змінити, щоб включити бажаний XXE payload, часто починаючи з HTTP запиту. Змінені XML рядки слід вставити між двома кореневими XML об'єктами. Важливо замінити URL на моніторинговий URL для запитів. @@ -254,7 +249,7 @@ jar:https://download.host.com/myarchive.zip!/file.txt 2. HTTP-відповідь, що містить архів, тимчасово зберігається в системі, зазвичай у місці на кшталт `/tmp/...`. 3. Архів потім розпаковується для доступу до його вмісту. 4. Конкретний файл в архіві, `file.zip`, читається. -5. Після операції будь-які тимчасові файли, створені під час цього процесу, видаляються. +5. Після завершення операції всі тимчасові файли, створені під час цього процесу, видаляються. Цікава техніка для переривання цього процесу на другому етапі полягає в тому, щоб підтримувати з'єднання з сервером відкритим безкінечно під час обслуговування архівного файлу. Інструменти, доступні в [цьому репозиторії](https://github.com/GoSecure/xxe-workshop/tree/master/24_write_xxe/solution), можуть бути використані для цієї мети, включаючи Python сервер (`slow_http_server.py`) та Java сервер (`slowserver.jar`). ```xml @@ -315,9 +310,9 @@ Responder.py -I eth0 -v ### XInclude -При інтеграції даних клієнта в XML-документи на стороні сервера, такі як ті, що в бекенд SOAP запитах, прямий контроль над структурою XML часто обмежений, що ускладнює традиційні атаки XXE через обмеження на модифікацію елемента `DOCTYPE`. Однак атака `XInclude` пропонує рішення, дозволяючи вставку зовнішніх сутностей у будь-який елемент даних XML-документа. Цей метод ефективний навіть тоді, коли можна контролювати лише частину даних у згенерованому сервером XML-документі. +При інтеграції даних клієнта в XML-документи на стороні сервера, такі як ті, що в бекенд SOAP запитах, прямий контроль над структурою XML часто обмежений, що ускладнює традиційні XXE атаки через обмеження на зміну елемента `DOCTYPE`. Однак атака `XInclude` надає рішення, дозволяючи вставку зовнішніх сутностей у будь-який елемент даних XML-документа. Цей метод є ефективним навіть тоді, коли можна контролювати лише частину даних у згенерованому сервером XML-документі. -Щоб виконати атаку `XInclude`, потрібно оголосити простір імен `XInclude`, а також вказати шлях до файлу для запланованої зовнішньої сутності. Нижче наведено стисле приклад того, як така атака може бути сформульована: +Щоб виконати атаку `XInclude`, необхідно оголосити простір імен `XInclude`, а також вказати шлях до файлу для запланованої зовнішньої сутності. Нижче наведено стисле приклад того, як така атака може бути сформульована: ```xml productId=&storeId=1 ``` @@ -327,9 +322,9 @@ productId= ``` @@ -343,7 +338,7 @@ productId=%a;%dtd;]> @@ -519,7 +514,7 @@ Content-Type: application/x-xliff+xml ------WebKitFormBoundaryqBdAsEtYaBjTArl3-- ``` -Цей підхід виявляє, що User Agent вказує на використання Java 1.8. Відзначеною обмеженням цієї версії Java є неможливість отримати файли, що містять символ нового рядка, такі як /etc/passwd, використовуючи техніку Out of Band. +Цей підхід показує, що User Agent вказує на використання Java 1.8. Відзначеною обмеженням цієї версії Java є неможливість отримати файли, що містять символ нового рядка, такі як /etc/passwd, використовуючи техніку Out of Band. Витік даних на основі помилок Щоб подолати це обмеження, використовується підхід на основі помилок. Файл DTD структурований наступним чином, щоб викликати помилку, яка включає дані з цільового файлу: ```xml @@ -539,7 +534,7 @@ Content-Type: application/x-xliff+xml %foo; %xxe; ``` -Ця модифікація призводить до успішної ексфільтрації вмісту файлу, оскільки це відображається в виході помилки, надісланому через HTTP. Це вказує на успішну атаку XXE (XML External Entity), що використовує як Out of Band, так і Error-Based техніки для витягнення чутливої інформації. +Ця модифікація призводить до успішної ексфільтрації вмісту файлу, оскільки це відображається в виході помилки, надісланому через HTTP. Це вказує на успішну атаку XXE (XML External Entity), що використовує як Out of Band, так і Error-Based техніки для витягання чутливої інформації. ## RSS - XEE @@ -716,7 +711,7 @@ Error : failed to load external entity "file:///aaa/FLAG{secret}" > [!TIP] > Якщо парсер скаржиться на символи `%`/`&` всередині внутрішнього підмножини, подвоюйте їх кодування (`%` ⇒ `%`), щоб затримати розширення. -#### 2. Обхід захисту lxml 5.4.0 (libxml2 все ще вразливий) +#### 2. Обхід посилення lxml 5.4.0 (libxml2 все ще вразливий) `lxml` ≥ 5.4.0 забороняє *параметричні* сутності помилок, як у наведеному вище прикладі, але **libxml2** все ще дозволяє їх вбудовувати в *загальну* сутність. Трюк полягає в тому, щоб: 1. Прочитати файл у параметричну сутність `%file`. 2. Оголосити іншу параметричну сутність, яка створює **загальну** сутність `c`, чий системний ідентифікатор використовує *неіснуючий протокол*, наприклад `meow://%file;`. @@ -731,21 +726,54 @@ Error : failed to load external entity "file:///aaa/FLAG{secret}" ]> &c; ``` -#### Основні висновки +#### Ключові висновки * **Параметричні сутності** все ще розширюються libxml2, навіть коли `resolve_entities` має блокувати XXE. * **Недійсний URI** або **неіснуючий файл** достатні для конкатенації контрольованих даних у викинутому виключенні. -* Техніка працює **без вихідного з'єднання**, що робить її ідеальною для середовищ з суворими фільтрами виходу. +* Техніка працює **без вихідного з'єднання**, що робить її ідеальною для середовищ з суворим фільтром виходу. #### Рекомендації щодо пом'якшення * Оновіть до **lxml ≥ 5.4.0** і переконайтеся, що підлягаюча **libxml2** є **≥ 2.13.8**. * Вимкніть `load_dtd` та/або `resolve_entities`, якщо це абсолютно не потрібно. * Уникайте повернення сирих помилок парсера клієнту. -## Посилання +### Приклад зміцнення Java DocumentBuilderFactory + +Java-додатки часто парсять XML, використовуючи `DocumentBuilderFactory`. За замовчуванням фабрика **дозволяє розв'язання зовнішніх сутностей**, що робить її вразливою до XXE та SSRF, якщо не встановлені додаткові прапори зміцнення: +```java +DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); +DocumentBuilder builder = dbf.newDocumentBuilder(); // XXE-prone +``` +Приклад безпечної конфігурації: +```java +DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + +// Completely forbid any DOCTYPE declarations (best-effort defence) +dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + +// Disable expansion of external entities +dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); +dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + +// Enable "secure processing" which applies additional limits +dbf.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true); + +// Defensive extras +dbf.setXIncludeAware(false); +dbf.setExpandEntityReferences(false); + +DocumentBuilder builder = dbf.newDocumentBuilder(); +``` +Якщо додаток повинен підтримувати DTD всередині, залишайте `disallow-doctype-decl` вимкненим, але **завжди** залишайте два параметри `external-*-entities` встановленими на `false`. Ця комбінація запобігає класичним атакам на розкриття файлів (`file:///etc/passwd`), а також вектором SSRF на основі мережі (`http://169.254.169.254/…`, протокол `jar:` тощо). + +Дослідження з реального світу: **CVE-2025-27136** в емуляторі Java S3 *LocalS3* використовував вразливий конструктор, показаний вище. Неавтентифікований зловмисник міг надати підготовлене XML тіло до кінцевої точки `CreateBucketConfiguration` і змусити сервер вбудувати локальні файли (наприклад, `/etc/passwd`) у HTTP-відповідь. + +## References + +- [OffSec Blog – CVE-2025-27136 LocalS3 XXE](https://www.offsec.com/blog/cve-2025-27136/) - [https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf](https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf) - [https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html](https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html) -- Витягти інформацію через HTTP, використовуючи власний зовнішній DTD: [https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/](https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/) +- Extract info via HTTP using own external DTD: [https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/](https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/) - [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection) - [https://gist.github.com/staaldraad/01415b990939494879b4](https://gist.github.com/staaldraad/01415b990939494879b4) - [https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9](https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9)