XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文件作为配置文件(spring、Struts2等)、文档结构说明文件(PDF、RSS等)、图片格式文件(SVG header)应用比较广泛。
0x01前言
本文讲述的XXE漏洞是一种针对使用XML交互的应用程序的攻击方法以及相关防护建议。
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文件作为配置文件(spring、Struts2等)、文档结构说明文件(PDF、RSS等)、图片格式文件(SVG header)应用比较广泛。
0x02.1XML文档结构
XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
0x02.2XML声明
XML声明包含包含下列内容:版本号(必选)、编码声明(可选)。
例子:<?xml version="1.0" encoding="UTF-8"?>
0x02.3文档类型定义
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。
0x02.4内部声明DTD
例子:<!DOCTYPE 根元素 [元素声明]>
0x02.5引用外部DTD
例子:<!DOCTYPE 根元素 SYSTEM "文件名">
0x02.6DTD实体
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。
0x02.7内部声明实体
例子:<!ENTITY 实体名称 "实体的值">
0x02.8引用外部实体
例子:<!ENTITY 实体名称 SYSTEM "URI">
当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、SSRF、DOS等危害。
ASP.NET环境下,使用XmlDocument类解析传入的XML文件,默认情况下,允许引用外部实体,当用户传入有害的XML时,会导致外部实体注入的漏洞的发生。
被解析的XML内容可控时,程序中又没有对可引用的外部实体进行限制,则可能导致DOS、SSRF、任意文件读取等危害。
0x04.1DOS
通过XML实现DOS其实不需要引用外部实体,但作为XML攻击的一种可能性,在此处简单提及。
当我们传入以下XML文件时,递归定义了XML实体,在解析过程会变得异常缓慢,占用系统大量资源,造成拒绝服务。
只需要手工发起数次攻击请求,即可占用大量资源。测试图如下:
0x04.2SSRF
当我们传入以下XML文件(引用外部实体http://***.ceye.io/xxe)后,应用会向http://***.ceye.io/xxe 链接发起一个GET请求尝试获取实体,这就导致了SSRF,我们可以通过SSRF扫描并攻击内网应用、获取网站真实IP等操作。
测试结果如下,可以看到应用向CEYE平台发起了一个GET请求:
0x04.3任意文件读取
文件读取可以分为两种情况:
0x04.3.1有回显,程序直接输出元素值
简单解释下面这段代码,代码创建了XmlDocument类用于解析XML文件,在解析了XML文件后,将XML中的元素输出在页面中:
传入以下XML文件,实体引用外部的文件,并作为一个元素,程序会自动解析读取文件并直接输出在页面上:
直接访问,可以看到C:/Windows/win.ini内容:
0x04.3.2无回显,程序仅解析XML不回显
可以看到代码仅仅解析了XML文件并没有输出任何参数,因此如果采用方法1的XML,尽管读取了win.ini文件,也不会将其输出至页面上。
这种情况可以带外传输,即先用一个实体读取文件,然后将读取的值附加在另一个外部实体的URL上,发出访问,从而将相关信息发送到攻击者的服务器上,直接看XML比较容易理解。
0x04.3.3相关的XML文件