XXE XML外部实体注入 漏洞
0x00 XML 基础知识
ⅩML 介绍
-
XML 是 The Extensible Markup Language(可扩展标识语言)的简写。
-
XML最初的目的是弥补 HTML 的不足,后来逐渐用于网络数据的转换和描述 ,XML 的设计宗旨是传输数据
-
XML在 web 中的应用已十分广泛。XML 是各种应用程序之间数据传输 最常用的数据格式。
与 HTML 的区别:
-
XML 被设计用来传输和存储数据,其焦点是数据的内容。
-
HTML 被设计用来显示数据,其焦点是数据的外观。
-
HTML 旨在显示信息 ,而 XML 旨在传输信息
XML实体介绍
-
什么是XML实体
-
在一个甚至多个XML文档中频繁使用某一条数据,我们可以预先定义一个这条数据的“别名”,即一个 ENTITY ,然后在这些文档中需要该数据的地方调用它。根据实体的来源我们可以分为内部实体和外部实体。XML定义了两种类型的 ENTITY,一种在XML文档中使用,另一种作为参数在DTD文件中使用。定义好的 ENTITY在文档中通过"&实体名;"来使用。
-
可以把实体当作xml语言的变量
-
XML实体类型有两种:普通实体 和 参数实体
- XML实体的语法
]>
]>
]>
]>
DTD文档介绍
-
概述
-
DTD使数据格式之间按照相同的标准 来传输。
-
DTD是一种XML约束模式 语言,用来解释XML文档 。
-
DTD类型:分为内部DTD文档和外部DTD文档
-
DTD文档的语法结构:
-
内部 DTD文档的语法结构:
- 外部 DTD文档的语法结构:
- 新建一个DTD文档 outdid.dtd
- 新建一个XML文档 outdid.xml
- 内外 DTD文档结合的语法结构:
- 新建一个DTD文档 out2dtd.dtd
- 新建一个DTD文档 out2dtd.xml
XML支持的协议
XML 实体引用
- 普通实体引入外部实体:
- 参数实体引入外部实体:
XML实体定义总结
<?xml version='1.0' encoding='utf-8'?> //标识(可要可无)
//内部dtd文档
//内部普通实体定义
//内部参数实体定义
//外部普通实体声明
%b
]>
&xxe;
&b;
&c;
&xxe;
//区分内部还是外部实体调用看有没有SYSTEM 有SYSTEM关键字一定是外部调用
//普通实体外部调用
]>
&a; //只有调用实体才会发生文件读取
0x01 XXE 漏洞原理
XXE概述
- XXE漏洞也叫XML外部实体注入 ,XXE漏洞发生在应用程序解析XML输入 时,没有禁止外部实体的加载 ,导致可加载恶意外部文件
漏洞的产生
- 对上传的xml文件没有进行过滤 ,导致可上传恶意xml文件
0x02 XXE 漏洞危害
漏洞的危害
-
读取任意文件
-
执行系统命令
-
内网端口扫描
-
攻击内网其他网站
0x03 XXE 漏洞防御
-
禁止使用外部实体 ,例如 libxml_disable_entity_loader(true)
-
过滤 用户提交的XML数据 ,防止出现非法内容
0x04 XXE 漏洞利用
- 读取任意文件
<?xml version="1.0" encoding="urf-8">
&xxe;
外带数据 ** 读取任意文件**
- 监听8888端口
// payload
<?xml version="1.0" encoding="urf-8">
&send;
// 远程xxe.dtd文件
">
%int;
- 远程端口探测
- (主机存活扫描)根据页面延迟 banner信息 (不准)
<?xml version="1.0" encoding="urf-8">
&xxe;
- 远程命令执行
-
有些情况下攻击者能够通过XXE执行代码,这主要是由于配置不当/开发内部应用 导致的。
-
前提:PHP环境中安装了expect扩展
-
payload:
<?xml version="1.0" encoding="urf-8">
]>
&xxe;
漏洞代码分析
- 服务端代码分析
<?php
if(!empty($_POST['sub'])){
$data = $_POST['data']:
$xmL = simp_lexml_load_string(data); //XML解析函数
print($xm1);
}
?>
- simplexml_load_string() 函数的作用是把XML字符串载入对象中,函数获取xml内容,并没有进行任何的过滤 。
0x05 XXE 漏洞挖掘
- 判断当前网页数据传输是否使用xml语言
-
看content-type:application/xml
-
看请求体是否满足xml格式数据
- 直接加外部实体看他是否会解析
注:一定要有调用的过程,定义好的实体不去调用文件读取的步骤就是无效的