示例:
<?xml version = "1.0" encoding = "utf-8"?> <!DOCTYPE test [ <!ENTITY file SYSTEM "file:///etc/passwd"> <!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"> ]> <author>&file;©right;</author>
导语
XXE:XML External Entity 即外部实体,从安全角度理解成XML External Entity attack 外部实体注入攻击。由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生的。例如PHP中的simplexml_load 默认情况下会解析外部实体,有XXE漏洞的标志性函数为simplexml_load_string()。
尽管XXE漏洞已经存在了很多年,但是它从来没有获得它应有的关注度。很多XML的解析器默认是含有XXE漏洞的,这意味着开发人员有责任确保这些程序不受此漏洞的影响。 比如今年7月刚爆出的微信支付XXE漏洞案例。
libxml2.9.1及以后,默认不解析外部实体。可以在此了解libxml各版本具体改动情况。本次测试在Window下使用的php5.4.45(libxml Version 2.7.8)。Linux中需要将libxml低于libxml2.9.1的版本编译到PHP中,可以使用phpinfo()查看libxml的版本信息。当XML声明中standalone值是yes的时候表示DTD仅用于验证文档结构,外部实体将被禁用。但它的默认值是no,而且有些parser会直接忽略这一项。
XML外部实体
本文主要讲外部实体注入攻击,所以基本的XML语法就不过多的描述。主要看一下DTD-实体。
首先让我们了解一下基本的PAYLOAD结构
DTD:Document Type Definition 即文档类型定义,用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在另外一个单独的文件中(外部引用)。
实体分为一般实体和参数实体
1. 一般实体的声明:<!ENTITY 实体名称 "实体内容">
引用一般实体的方法:&实体名称;
p.s.经实验,普通实体可以在DTD中引用,可以在XML中引用,可以在声明前引用,还可以在实体声明内部引用。
2. 参数实体的声明:<!ENTITY % 实体名称 "实体内容">
引用参数实体的方法:%实体名称;
p.s.经实验,参数实体只能在DTD中引用,不能在声明前引用,也不能在实体声明内部引用。
如果实体名称中出现如<
的特殊字符,解析就会失败。为了避免这种情况,XML用实体引用替换特殊字符。XML预定义了五个实体引用,即用<
、 >
、 &
、 &apos
、 "
替换<
、>
、&
、'
、"
。
DTD实体声明(重点)
1. 内部实体声明
<!ENTITY 实体名称 "实体的值">
当引用一般实体时,由三部分构成:&
、实体名
、;
,当是用参数传入xml的时候,&
需URL编码,不然&
会被认为是参数间的连接符号。
示例: