介绍
在最近的一个项目中,我发现了一个与 XML 外部实体(XXE)攻击相关的重大安全问题。
本文讲述了我在项目中发现并利用 XXE 漏洞的过程,特别是通过一种非传统的方式——利用 Java 异常在日志文件中输出攻击结果。
什么是XXE?
XML 外部实体(XXE)是一种安全漏洞,通常出现在处理 XML 输入的应用程序中。在 XXE 攻击中,攻击者可以利用应用程序的 XML 解析器来引入外部实体,从而实现多种恶意行为,如读取本地文件、发起服务器请求,甚至在服务器上执行任意代码。如果不加以处理,这类漏洞可能导致严重后果,因此在网络安全领域中是一个至关重要的问题。
问题:初步突破
在对我的最新项目进行全面测试时,我发现了一个令人担忧的功能。项目的解决方案允许上传包含 XML 标记的 schema 文件,这就为 XXE 漏洞打开了大门。
对此产生了兴趣后,我决定深入研究这一潜在威胁。我的第一次突破发生在发现了一个允许服务器端请求伪造(SSRF)漏洞的 XXE 漏洞。SSRF 是一种安全漏洞,攻击者可以利用它诱使服务器向内部网络中的其他资源或外部网站发起非预期的请求。
我通过在 schema 文件中注入以下 XXE 负载成功实现了这一漏洞:
有了这个 payload 后,我简单地从模板创建了一个 schema 文件,并将 payload 添加到其中。
在创建完 schema 文件后,我继续将其上传到系统中:
该应用程序在默认情况下会在上传后自动处理 schema 文件。在加载过程中,由于注入导致 schema 文件无效,会触发错误:
尽管发生了错误,但注入的 XML 实体仍被处理,导致服务器后端执行了一次 HTTP 请求。这是此次发现的关键时刻,因为我成功实现了 SSRF(服务器端请求伪造)。
很快我意识到,读取文件并不可行,因为没有直接的输出。我们得到的只是一个通用的错误信息。schema 文件需要遵循特定的模板,这使得使用包含多条指令的 DTD 技术变得不现实,因为在第一条指令之后就会引发 XML 解析错误。
利用服务器日志
但我并未气馁,决心找到一种方法来在目标机器上披露文件。在持续的探索中,我发现了一个解决方案:应用程序具有日志记录功能,并且可以显示日志。这一发现为我打开了新的路径。
我开始着手从已处理的注入 XML 实体中提取有价值的信息。
于是,我创建了一个包含声明实体的模板 schema 文件,加载了一个外部 XML DTD。
外部 DTD 允许应用程序引用一个独立文件来定义 XML 结构,从而为潜在的漏洞利用提供了可能性:
接着,我在远程主机上准备了恶意的 evil.dtd
文件:
与之前一样,我从模板创建了一个 schema 文件,并在其后附加了我的 payload:
schema 文件上传成功,但加载过程由于错误而失败,情况如下:
然而,这种方式仍会加载外部 DTD(evil.dtd)并处理它:
DTD 文件中的 payload 通过引用一个不存在的文件触发了服务器异常。这个文件名是通过将 'nonexistent/'
路径与一个表示 C:/ 盘列表的字符串组合而成的。
基本上,未处理的异常文本将类似于:
Error, non-existing file at: file:///nonexistent/(C:/)LISTING.
这些文本将会出现在错误日志中:
除了目录列表,这种技术还可以用来读取文件。通过操控 DTD 文件的内容,攻击者可以针对系统中的特定文件:
申明:本账号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法。