提交 31d3c3a6 编写于 作者: W wizardforcel

ch14.

上级 9c16b205
# 十四、XML 外部实体注入
> 作者:Peter Yaworski
> 译者:[飞龙](https://github.com/)
> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
XML 外部实体(XXE)漏洞涉及利用应用解析 XML 输入的方式,更特别来说,应用程序处理输入中外部实体的包含方式。为了完全理解理解如何利用,以及他的潜力。我觉得我们最好首先理解什么是 XML 和外部实体。
元语言是用于描述其它语言的语言,这就是 XML。它在 HTML 之后开发,来弥补 HTML 的不足。HTML 用于定义数据的展示,专注于它应该是什么样子。房子,XML 用于定义数据如何被组织。
例如,HTML 中,你的标签为`<title>`, `<h1>`, `<table>`, `<p>`,以及其它。这些东西都用于定义内容如何展示。`<title>`用于定义页面的标题,`<h1>`标签定义了标题,`<table>`标签按行和列展示数据,并且`<p>`表示为简单文本。反之,XML 没有预定义的标签。创建 XML 文档的人可以定义它们自己的标签,来描述展示的内容。这里是一个示例。
```xml
<?xml version="1.0" encoding="UTF-8"?>
<jobs>
<job>
<title>Hacker</title>
<compensation>1000000</compensation>
<responsibility optional="1">Shot the web</responsibility>
</job>
</jobs>
```
读完了之后,你可以大致猜测出 XML 文档的目的 -- 为了展示职位列表,但是如果它在 Web 页面上展示,你不知道它看起来是什么样。XML 的第一行是一个声明头部,表示 XML 的版本,以及编码类型。在编写此文的时候,XML 有两个版本,1.0 和 1.1。它们的具体区别超出了本书范围,因为它们在你渗透的时候没什么影响。
在初始的头部之后,标签`<jobs>`位于所有其它`<job>`标签的外面。`<job>`又包含`<title>``<compensation>``<responsibilities>`标签。现在如果是 HTML,一些标签并不需要(但最好有)闭合标签(例如`<br>`),但是所有 XML 标签都需要闭合标签。同样,选取上面的例子,`<jobs>`是个起始标签,`</jobs>`是对应的闭合标签。此外,每个标签都有名称,并且可以拥有属性。使用标签`<job>`,标签名称就是`job`,但是没有属性。另一方面,`<responsibility>`拥有名称`responsibility`,并拥有属性`optional`,由属性名称`optional`和值`1`组成。
由于任何人可以定义任何标签,问题就来了,如果标签可以是任何东西,任何一个人如何知道如何解析和使用 XML 文档?好吧,一个有效的 XML 文档之所以有效,是因为它遵循了 XML 的通用规则(我不需要列出它们,但是拥有闭合标签是一个前面提过的例子),并且它匹配了它的文档类型定义(DTD)。DTD 是我们继续深入的全部原因,因为它是允许我们作为黑客利用它的一个东西。
XNK DTD 就像是所使用的标签的定义文档,并且由 XML 设计者或作者开发。使用上面的例子,我就是设计者,因为我在 XML 中定义了职位文档。DTD 定义了存在什么标签,它们拥有什么属性,以及其它元素里面有什么元素,以及其他。当你或者我创建自己的 DTD 时,一些已经格式化了,并且广泛用于 RSS、RDF、HL7 SGML/XML。以及其它。
下面是 DTD 文件的样子,它用于我的 XML。
```xml
<!ELEMENT Jobs (Job)*>
<!ELEMENT Job (Title, Compensation, Responsiblity)>
<!ELEMENT Title (#PCDATA)>
<!ELEMENT Compenstaion (#PCDATA)>
<!ELEMENT Responsibility(#PCDATA)>
<!ATTLIST Responsibility optional CDATA "0">
```
看一看这个,你可能猜到了它大部分是啥意思。我们的`jobs`标签实际上是 XML `!ELEMENT`,并且可以包含`job`元素。`job`是个`!ELEMENT`,可以包含标题、薪资和职责,这些也都是`!ELEMENT`,并且只能包含字符数据(`#PCDATA`)。最后,`!ELEMENT responsibility`拥有一个可选属性(`!ATTLIST`),默认值为 0。
并不是很难吧?除了 DTD,还有两种还未讨论的重要标签,`!DOCTYPE``!ENTITY`。到现在为止,我只说了 DTD 文件是我们 XML 的扩展。要记住上面的第一个例子,XML 文档并不包含标签定义,它由我们第二个例子的 DTD 来完成。但是,我们可以将 DTD 包含在 XML 文档内,并且这样做之后, XML 的第一行必须是`<!DOCTYPE>`元素。将我们的两个例子组合起来,我们就会得到这样的文档:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Jobs [
<!ELEMENT Job (Title, Compensation, Responsiblity)>
<!ELEMENT Title (#PCDATA)> <!ELEMENT Compenstaion (#PCDATA)>
<!ELEMENT Responsibility(#PCDATA)>
<!ATTLIST Responsibility optional CDATA "0">
]>
<jobs>
<job>
<title>Hacker</title>
<compensation>1000000</compensation>
<responsibility optional="1">Shot the web</responsibility>
</job>
</jobs>
```
这里,我们拥有了内部 DTD 声明。要注意我们仍然使用一个声明头部开始,表示我们的文档遵循 XML 1.0 和 UTF8 编码。但是之后,我们为 XML 定义了要遵循的`DOCTYPE `。使用外部 DTD 是类似的,除了`!DOCTYPE ``<!DOCTYPE note SYSTEM "jobs.dtd">`。XML 解析器在解析 XML 文件时,之后会解析`jobs.dtd`的内容。这非常重要,因为`!ENTITY`标签被近似处理,并且是我们利用的关键。
XML 实体像是一个信息的占位符。再次使用我们之前的例子。,如果我们想让每个职位都包含到我们网站的链接,每次都编写地址简直太麻烦了,尤其是 URL 可能改变的时候。反之,我们可以使用`!ENTITY`,并且让解析器在解析时获取内容,并插入到文档中。你可以看看我们在哪里这样做。
与外部 DTD 文档类似,我们可以更新我们的 XML 文档来包含这个想法:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Jobs [
<!ELEMENT Job (Title, Compensation, Responsiblity, Website)>
<!ELEMENT Title (#PCDATA)> <!ELEMENT Compenstaion (#PCDATA)>
<!ELEMENT Responsibility(#PCDATA)>
<!ATTLIST Responsibility optional CDATA "0">
<!ELEMENT Website ANY>
<!ENTITY url SYSTEM "website.txt"> ]>
<jobs>
<job>
<title>Hacker</title>
<compensation>1000000</compensation>
<responsibility optional="1">Shot the web</responsibility>
<website>&url;</website>
</job>
</jobs>
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册