payload1是xxe一个经典payload。一般用于无回显的blind xxe
。但是问题来了,为何Payload作者将payload内容分两部分(比如像payload1这样),而不是将所有攻击实体放到一个payload中(比如像payload2这样)。注意:Blind XXE是没有回显的,为了测试方便,我将payload有回显的显示了。
测试代码
1 |
|
payload1
evilt.dtd
1 |
|
payload2
1 |
|
钻这个牛角尖的意义:
- 如果没有公网空间payload1将无法使用,而payload2可行的话就可以解决payload1的缺陷。
- payload1的作者为何把payload分两部分构造为payload1,而不是分一部分构造成功payload2。
- 更深入的了解xxe payload的构造。
我在payload1能执行成功的情况下,有测试了payload2。结果令人失望,没有成功。难道原因是payload作者也想把所有攻击内容放在一个payload只是这样无法执行成功?网上看了一下全是清一色的经典payload的样式。看来只有我来自己构造一个能实现payload1功能,同时包含所有攻击代码的payload了。
错误信息
第一个想是通过查看错误信息来找原因。
报错PEReferences forbidden in internal subset in Entity
根据报错,我将http://127.0.0.1/?%file;
中的%编码为
还是报错Invalid URI: http://127.0.0.1/?% in Entity
,说明%file
只是变成了%file,但是%file没有解析为实体file的值。
我又将第二个实体中的SYSTEM去掉,也就是第二个实体我声明为内部实体,结果%file
成功解析为实体file内容。
1 |
|
这令我很是不解,为何内部声明%file能够成功解析,为何外部声明时不行?我暂时理解为,外部声明需要多一个步骤URL合法性检验。说明在%file还没有被解析为file实体值时,URL合法性检验就开始了。而是在HTTP协议中%与url编码中的%有冲突了。
然而一切都是我的猜想而已。想了一下,xml解析器是在php内部,无法知道它解析一个xml的具体细节。除非我可以调式源代码(目前没有这能力。),那下面我只能看看,有没有权威的文档去解释这个问题了。
权威文档
《XML Schema,DTD,and Entity Attacks》一文中有关XXE和参数实体的部分。
书到用时方恨少,读然好想写英语。这次只能借助百度翻译和有道翻译了。下面是针对于英文材料翻译和我的一些理解。
参数实体是一种特殊类型的实体,它只能在DTD定义本身中使用。这些实体与文档实体的定义基本相同,但它们的行为更像(但不完全像)代码宏,并允许使用它们。
更灵活的DTD定义。考虑以下内容,其中的an-element被定义为一个常规参数实体,
远程dtd被定义为一个外部参数实体:
1 |
"> |
参数实体的定义与文档实体几乎相同,除了附加的”%”符号之外。
对参数实体的引用必须出现在DTD中,并且必须使用”%…;”语法。此外,对于在DTD中使用参数实体的上下文,通常会有各种各样的限制。一个重要的限制(在几个XML解析器中一致地出现)是,虽然参数实体可以定义用于引用的DTD语法(例如”%an-element”),但是它可能不会定义一个立即被用于另一个DTD标记的值。也就是说,这个语法会在我们测试的解析器中失败:
1 |
|
然而,如果实体引用存在于子DTD中,这种样式的语法通常会成功。也就是说,如果文档的DTD引用外部实体,包括使用参数实体引用的外部文档的值,并且外部文档引用前面定义的实体,那么动态构建的DTD标记将被解释为人们所期望的。
以上是对英文材料的翻译。下面是我的理解。通过将英文文档中的第一例子提交到我们的本地测试靶机,发现没有保存,可以正常打印xml对象,说明解析成功。
但是第二个就通常可能无法解析。
文章说第二例子通常是无法解析的,并没有说一定无法解析。说明大部分情况下是无法解析的,因为xml的解析器在php,java,C#等等中情况会有一些不一样。我们暂且认为文章中第二个xml就是无法解析吧!
按照文章的意思,如果文档的DTD引用外部实体,包括使用参数实体引用的外部文档的值,并且外部文档引用前面定义的实体,那么动态构建的DTD标记将被解释为人们所期望的。
于是我将第二个xml写为
1 |
|
remote.dtd
1 |
|
这样之后不在报错。
现在回到本文的问题,我们想构造的payload其实道理和英文材料中的第二个xml很相似。
我们在上面声明% file实体,在下一行就直接通过%file;使用它,按照英文材料的意思这样通常是解析不成功的。那么我们通过错误信息
章节中遇到的内部声明%file
可以解析,而外部声明为何无法解析。也许这就是英文材料中说的通常的情况的例外。我承认这解释有点不负责任,没有论证。所以等到有能力可以调式php源码时,才深挖真正的原因吧。
最后说一下目前的结论吧。虽然一不定是正确的,至少是可以让我能暂时安心睡觉的一个解释。 payload作者之所以把paylaod内容分两部分写,是因为无法实现分一部分写。分一部分写,无法让payload执行成功!
该文章关于该问题提出了一些想法。XXE漏洞以及Blind XXE总结
参考文章
XML Schema,DTD,and Entity Attacks
文章来源于gv7.me:Blind XXE经典payload引发的脑洞
相关推荐: 复现JBossMQ JMS Invocation Layer漏洞(CVE-2017-7504)
0x01 漏洞信息 项目 描述 漏洞名称 JBossMQ JMS Invocation Layer RCE CVE编号 CVE-2017-7504 漏洞描述 HTTPServerILServlet.java在JMS上JbossMQ实现的HTTP调用层,默认情况…
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论