前言:
今天做题遇到了一道XXE,发现自己对XML与DTD没有什么了解,翻阅一些资料学习一下,也是为XXE的学习打一点基础
内容主要参考了这两篇:DTD语法 (元素、属性、实体声明)与 浅谈XML实体注入漏洞
XML:可扩展标记语言(eXtensible Markup Language)
XML文档结构包括:XML声明、DTD文档类型定义(可选)、文档元素
DTD与XML的关系宛如 类与实例 的关系,DTD会规定XML的结构,有什么元素以及元素的先后顺序
<?xml version="1.0" ?>
<!--以下开始DTD文档,这是一个note文档 -->
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]> <!--以上部分即为DTD,它规定了下边XML的格式-->
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<message>Don't forget me this weekend!</message>
</note>

如何拥有一个DTD?
● 内部声明DTD
1.编写DTD:
<!DOCTYPE 根元素 [元素声明]>
● 引用外部DTD
2.引用本机DTD文件:
<!DOCTYPE 根元素 SYSTEM "DTD文件的路径">
3.引用网络上DTD文件:
<!DOCTYPE 根元素 PUBLIC "public_ID" "DTD文件的URL">
DTD(文档类型定义–Document Type Defination)语法:
1. 元素定义:
图中第一列是描述,第二列是一般化,第三列是例子(第一行除外)

● <!ELEMENT 元素名称 元素类型>
定义元素的类型有:
1. ANY:表示任意类型
2. EMPTY:空元素
3. #PCDATA:简单元素或纯文本元素,可以包含任意字符数据,但是不能包含任何子元素
4. 父元素类型:只包含子元素,并且除了子元素外没有文本
● <!ELEMENT 元素名称 (元素内容)>
定义元素的内容,一定要加上( )
2. 属性定义:
属性是对元素进行修饰、补充的
● 属性的语法:
<!ATTLIST 元素名称 属性名称 属性类型 设置说明>
在DTD中这样设置:
<!ATTLIST person name CDATA "张三">
在XML中这样实例:
<person name="张三" />
● 属性类型:

● 设置说明
1.Default 设置一个默认值 上面的"张三"就是一个默认值
<!ATTLIST person name CDATA "张三">
2.#REQUIRE 属性值是必须的
3.#IMPLIED 属性值可有可无
4.#FIXED value 属性值是固定的
<!ATTLIST person name CDATA #FIXED "张三">
通过以下伪代码 更好理解:
<?xml version="1.0" encoding="GB2312"?>
<!--一个内部DTD的示例,首先写根元素“家庭”-->
<!--包含两个元素,人至少出现一次,家电可以出现人一次,这两个元素都被定义为空类型-->
<!DOCTYPE 家庭[
<!ELEMENT 家庭 (人+,家电*)>
<!ELEMENT 人 EMPTY>
<!ELEMENT 家电 EMPTY>
<!--开始定义属性-->
<!ATTLIST 人
名字 CDATA #REQUIRED
年龄 CDATA #REQUIRED
爱好 CDATA #IMPLIED
>
<!ATTLIST 家电
名称 CDATA #REQUIRED
数量 CDATA #REQUIRED
说明 CDATA #IMPLIED
>
]>
<!--DTD部分结束-->
<家庭>
<人 名字="张三" 年龄="25"/>
<人 名字="李四" 年龄="38" 爱好="踢足球"/>
<家电 名称="彩电" 数量="三" />
</家庭>
3. 实体:
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
1. 预定义实体:

以上都是通用的预定义实体,此外在XML标准中还有:
' ' 单引号
& & &
" " 双引号
< < 小于号
> > 大于号
2. 自定义实体
自定义实体有三种:内部实体、外部实体、参数实体
● 内部实体
<!ENTITY 实体名称 "实体的值">
<!ENTITY name "张三">
● 外部实体
<!ENTITY 实体名称 SYSTEM "URL">
<!ENTITY name SYSTEM "http://example.com/dtd/writer.dtd">
<!ENTITY xxe SYSTEM "http://otherhost/xxxx.php" >]>
<!ENTITY xxe SYSTEM "file:///c://test/1.txt" >]>
还可以使用下图各种协议

● 参数实体
<!ENTITY %实体名称 "值">
<!ENTITY % name SYSTEM "file:///etc/passwd">
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE FAMILY[
<!ELEMENT FAMILY (NAME,AGE)>
<!ELEMENT NAME (#PCDATA)>
<!ELEMENT AGE (#PCDATA)>
<!ENTITY name "张三"> <!-- 内部实体-->
<!ENTITY age "19">
]>
<FAMILY>
<NAME>&name;</NAME>
<AHE>&age;</AHE>
</FAMILY>

本文介绍了XML的基本结构和DTD(文档类型定义)的作用,阐述了XML文档的元素定义、属性设置及实体声明。通过示例详细讲解了内部和外部DTD的创建,以及属性的默认值、必需值和固定值。同时,讨论了预定义和自定义实体的概念,强调了XXE漏洞与实体注入的安全问题。
3251

被折叠的 条评论
为什么被折叠?



