XXE(XML External Entity Injection) 又称为XML外部实体注入。
XML是一种类似于HTML(超文本标记语言)的可扩展标记语言,是用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
XML 指可扩展标记语言(EXtensible Markup Language)。
XML 是一种很像HTML的标记语言。
XML 的设计宗旨是传输数据,而不是显示数据。
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准
<note>
<to>Toveto>
<from>Janifrom>
<heading>Reminderheading>
<body>Don't forget me this weekend!body>
note>
文档结构图:
XML 文档必须有根元素
XML 声明(可选)
所有的 XML 元素都必须有一个关闭标签
XML 标签对大小写敏感
XML 必须正确嵌套
XML 属性值必须加引号
实体引用(同html)
>
,<
XML 中的注释(同html)
在 XML 中,空格会被保留
XML 元素必须遵循以下命名规则:
拥有正确语法的 XML 被称为"形式良好"的 XML。
通过 DTD 验证的XML是"合法"的 XML。
接下来掌握DTD(Document Type Definition)相关知识,有利于我们掌握XXE。
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:
DOCTYPE root-element [element-declarations]>
如:
DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)> //!ELEMENT:用于定义元素的名字
<!ELEMENT from (#PCDATA)> //#PCDATA ANY
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>程咬金to>
<from>貂蝉from>
<heading>通知heading>
<body>今天晚上,大战三百回合!body>
note>
以上 DTD 解释如下:
这里解释一下PCDATA和CDATA
PCDATA:是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
CDATA:是不会被解析器解析的文本。
假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
DOCTYPE root-element SYSTEM "filename">
先声明一个note.dtd:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
再写xml:
DOCTYPE note SYSTEM "note.dtd">
<note>
<to>周瑜to>
<from>黄盖from>
<heading>提示heading>
<body>老子不服输body>
note>
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
<!ENTITY entity-name "entity-value">
示例:
DOCTYPE stu [
<!ELEMENT stu (name, age, address)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT address (#PCDATA)>
<!ENTITY name "亚瑟">
<!ENTITY age "18">
<!ENTITY address "对抗路">
]>
<stu>
<name>&name;name>
<age>&age;age>
<address>&address;address>
stu>
注意: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (。
浏览器效果:
简单一点的案例:
DOCTYPE stu [<!ENTITY name "亚瑟">]>
<name>&name;name>
浏览器效果:
和内部实体一致,只是DTD声明在外部。
语法:
xml中引用外部dtd实体:
DOCTYPE root[
]>
<root>
<username>&name;username>
root>
注意:这个地方直接浏览器访问拿不到数据,需要程序读取。
data.txt中随意什么内容都可以。
核心在于SYSTEM关键字。
SYSTEM这个地方常用的协议:
file:///path/to/file.ext
http://url/file.ext
php://filter/read=convert.base64-encode/resource=conf.php
支持的协议:
其余的参考:
DOCTYPE ANY [
]>
<value>&xxe;value>
DOCTYPE ANY [
]>
<value>&xxe;value>
语法:
<!ENTITY % 实体名称 "实体的值">
或者
<!ENTITY % 实体名称 SYSTEM "URI">
注意: % 和 实体名字之间有一个空格
示例:
DOCTYPE root [
%name;
]>
注意:参数实体只能在 DTD文件中被引用,其他实体在XML文档内引用。
参数实体 在DOCTYPE内 ,其他实体在DOCTYPE外
DOCTYPE root [
%name;
]>
<root>
<username>&name;username>
root>