文章目录
XML简介和XXE漏洞
XML简介
- XML指可扩展标记语言,它被设计用来传输和存储数据。(HTML被用来显示数据)
- XML没有预定义的标签,需要自行定义标签
- XML是不作为的,及它不存在任何的行为,只是用来结构化、传输和存储信息
- 它仅仅是纯文字
- XML 是独立于软件和硬件的信息传输工具。
- (更多介绍详见w3school的介绍)
使用
XML结构
<!--声明部分-->
<?xml version="1.0" encoding="UTF-8">
<!--文档类型定义部分-->
<! DOCTYPE note[
<!ELEMENT file SYSTEM "file:///var/passwd">
]>
<!--内容部分-->
<letter date="2021/10/20">
<to>xxx</to>
<from>gs</from>
<body>记得去外滩!</body>
&file;
</letter>
- 第2行 是XML声明,它定义了XML的版本(version)和字符编码(encoding)
- 第4到6行是文档类型定义(DTD)内容
- 第5行引入了外部实体
- 第8-13行是内容部分
- 第8行的
<letter>
是根节点,date
是它的属性 - 第9行到第12行是具体的内容(
<to>、<from>、<body>
),称为子元素 - 第12行显示了引入的外部实体
- 第8行的
- 第13行则是根节点的闭标签
XML语法说明
-
每个标签都对应有一个闭合的标签
-
XML文档必须包含根节点。文档中的所有元素形成了一颗文档树,这颗树从根部开始并扩展到最底端。
-
上下层级的元素存在父子的关系,同级的为同胞(兄弟姐妹)
-
所有的元素都可以拥有子元素、文本内容和属性
-
XML标签大小写敏感
-
XML标签必须正确的嵌套
-
XML中的属性需要加引号
-
XML中的一些特殊字符无法直接在标签内部当作文本使用。比如
<message>123 < 321</message>
,此时的<
不再是小于号,而会被解析器当作新元素的开始。因此此处需要使用实体引用:<
。实体引用对照表如下:实体引用 符号 < < > > & & ' ’ " " -
XML 以
LF
存储换行。(PS:在 Windows 应用程序中,换行通常以一对字符来存储:回车符 (CR) 和换行符 (LF)。这对字符与打字机设置新行的动作有相似之处。在 Unix 应用程序中,新行以 LF 字符存储。而 Macintosh 应用程序使用 CR 来存储新行。)
XML元素
XML元素指从开始标签(包括)到结束标签(包括)的部分。元素可以包含其他元素、文本或两者的混合。元素可以拥有属性
- 元素的命名规则
- 可以包含字母、数字及其他的字符
- 不能以数字或标点符号开头
- 不能以字符
xml
开头,无论大小写都不行 - 名称不能包含空格
- 命名习惯:
- 多个单词间使用
_
分隔 - 避免
.
字符。比如<name.id>
,可能会被识别为name元素下的id元素-
字符。比如<name-id>
,可能仅会识别第一个单词:
字符。会被转换为命名空间来使用
- 多个单词间使用
- XML元素是可扩展的
XML属性
- 属性提供了元素的额外信息,通常不属于数据组成部分的信息
- 元数据(关于数据的数据)应当存为属性,数据本身存为元素
XML验证
-
拥有正确语法的XML被称为"形式良好"的XML
-
通过DTD验证的XML是合法的XML
-
合法的 XML 文档是“形式良好”的 XML 文档,同样遵守文档类型定义 DTD 的语法规则。(DTD 的作用是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构)
-
W3C支持一种基于XML的DTD代替者,命名为XML Schema
-
PS:XML美化可以通过XSLT来实现:
<?xml-stylesheet type="text/xsl" href="simple.xsl"?>
XML命名空间
命名空间提供避免元素命名冲突的方法
-
在XML中,标签是开发者自己定义的,当两个不同的文档使用相同的元素命名时,就会产生命名冲突
-
在标签中添加
xmlns
(xml namespace)属性来使用命名空间。比如:<!--文件1--> <h:table xmlns:h="http://www.w3.org/TR/html4/"> <h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr> </h:table> <!--文件2--> <f:table xmlns:f="http://www.w3school.com.cn/furniture"> <f:name>African Coffee Table</f:name> <f:width>80</f:width> <f:length>120</f:length> </f:table>
-
当命名空间被放在元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联
CDATA
所有XML文档中除
CDATA
之外的文本均会被解析器解析
-
CDATA指的是不应由XML解析器进行解析的文本数据
-
CDATA部分由
<![CDATA[
开始,由]]>
结束。]]>
部分不能拆开 -
CDATA部分不能包含字符串
]]>
,也不允许嵌套CDATA<script> <![CDATA[ function test(){ console.log("不会被解析") } ]]> </script>
DTD
文档类型定义(DTD)可定义合法的XML文档构建模块。DTD可以被成行的声明在XML文档中,也可作为一个外部引用。
内部DTD
-
如果DTD包含在XML源文件中,则应通过这样的语法包装在DOCTYPE声明中:
<!DOCTYPE 根元素 [元素声明]>
,比如:<?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>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
解释:
!DOCTYPE note
:定义此文档为note类型!ELEMENT not ()
:定义此DTD有四个元素,分别是to、from、heading、body
!ELEMENT to
:定义to元素为#PCDATA
类型,以此类推
外部DTD
-
外部DTD的封装应该是这样:
<!DOCTYPE 根元素 SYSTEM "外部DTD">
,比如:<?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd"> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
note.dtd的内容为:
<!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>
DTD实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。实体可以在内部或外部声明,需要包含在
<!DOCTYPE>
之中
内部实体
- 声明语法:
<!ENTITY 实体名 "实体值">
- 读取语法:
<author>&实体名;</author>
外部实体
- 声明语法:
<!ENTITY 实体名 SYSYEM "外部实体地址/名字"
XXE漏洞
XXE(XML External Entity),即XML外部实体注入,通过DTD外部实体声明
危害
- 任意文件读取。可以配合任意文件上传漏洞实现getshell
- 通过某些协议(比如安装expect扩展的PHP环境中)可以实现远程命令执行
- 通过HTTP协议探测内网端口
防护
- 使用开发语言提供的禁用外部实体来防止注入
- 过滤用户提交的XML数据。比如过滤掉
<!DOCTYPE
或<!ENTITY
攻击方式
-
方式一,构建如下payload:`]>``
通过file协议可以实现任意文件读取
-
方式二,构建payload:
<!DOCTYPE a [<!ENTITY file SYSTEM "http://127.0.0.1:81">]>
通过HTTP协议可以实现端口探测
-
方式三,构建payload:
<!DOCTYPE a [<!ENTITY file SYSTEM "expect://whoami">]>
通过expect协议可以执行系统命令
XXE盲注
实战例子
使用BountyHunter靶场
- 根据IP打开页面,进入表单位置
-
正常发送请求,并使用burpsuite抓包并查看内容
-
字符串疑似通过了Base64的加密,因此尝试解密
-
解密后发现参数以XML的形式传入的后台。构建payload尝试XXE注入。
-
加密后发包
-
成功读取出passwd文件的内容,因此XXE注入成功!