在本节中,我们将讨论什么是web缓存投毒,以及什么行为可以导致web缓存中毒漏洞。我们还将研究一些利用这些漏洞的方法,并提出一些减少这些漏洞的方法。
1. 什么是web缓存投毒
Web缓存投毒是一种高级技术,攻击者利用Web服务器和缓存的行为,将有害的HTTP响应提供给其他用户。
从根本上说,网络缓存投毒包括两个阶段。首先,攻击者必须找出如何从后端服务器引出响应,该响应无意中包含某种危险的payload。一旦成功,他们需要确保他们的响应被缓存,并随后提供给目标受害者。
web缓存投毒可能导致致命的影响,可以以多种方式进行利用,如XSS、JavaScript注入、开放重定向等等。
1.1 web缓存原理
要了解web缓存投毒漏洞是如何产生的,那么对web缓存的原理有一个基本的了解是很重要的。
如果服务器必须分别向每个HTTP请求发送新的响应,这可能会使服务器超载,导致延迟问题和糟糕的用户体验,特别是在业务高峰时期。使用缓存是减少此类问题的一种主要方法。
缓存位于服务器和用户之间,通常在固定的时间内保存(缓存)对特定请求的响应。如果另一个用户发送相同的请求,缓存会给用户直接返回保存的副本,而不需要与后端服务器交互。通过减少服务器必须处理的重复请求的数量,这极大地减轻了服务器的负载。
1.1.1 缓存键
当缓存接收到HTTP请求时,它首先必须确定是否存在可以直接提供的缓存响应,或者是否必须将请求转发给后端服务器进行处理。缓存通过比较预定义的缓存键来识别相同的请求。通常,这将包含请求行和Host头。请求中不包含在缓存键中的部分称为“unkey”。
如果传入请求的缓存键与前一个请求的缓存键匹配,那么缓存认为它们是相同的。因此,它将提供为原始请求生成的缓存副本。这将应用于匹配到缓存键的所有后续请求,直到缓存的响应过期。
至关重要的是,请求的其他部分完全被缓存忽略。稍后我们将更详细地探讨这种行为的影响。
2. web缓存投毒攻击影响
web缓存投毒的影响主要取决于两个关键因素:
攻击者到底可以成功地缓存什么。由于投毒的缓存更多的是一种分发手段,而不是单独的攻击,web缓存投毒的影响不可避免地与注入的payload的危害性联系在一起。与大多数类型的攻击一样,web缓存投毒也可以与其他攻击结合使用,从而进一步升级潜在的影响。
受影响页面的流量。当缓存被“投毒”时,“投毒”响应只会提供给访问受影响页面的用户。因此,影响可能从不存在到巨大,这取决于页面是否受欢迎。例如,如果攻击者设法在主站的主页上投毒,攻击可能影响成千上万的用户,这些用户与攻击者之间不需要进行任何交互。
请注意,缓存条目的持续时间并不一定会影响web缓存投毒的影响。攻击通过编写脚本无限期地重新缓存投毒。
3. 构造web缓存投毒攻击
一般来说,构建一个基本的web缓存投毒攻击包括以下步骤:
识别和评估非缓存键输入;
从后端服务器引出有害的响应;
获取缓存的响应;
3.1 识别和评估非缓存键输入
任何web缓存投毒攻击都依赖于对非缓存键输入的操作,比如HTTP头。当决定是否向用户提供缓存的响应时,Web缓存会忽略非缓存键的输入。这种行为意味着您可以使用它们注入您的payload,并引发一个“投毒的”响应,如果缓存,将为所有匹配到缓存键的用户请求提供服务。因此,构建web缓存投毒攻击的第一步是识别服务器支持的非缓存键输入。
您可以通过向请求手工添加随机输入并观察它们是否对响应有影响,来识别非缓存键输入。这可能是显而易见的,比如直接在响应中返回输入,或者触发一个完全不同的响应。然而,有时效果更微妙,需要一点侦查工作来发现。您可以使用Burp Comparer等工具来比较响应中有没有注入的内容,但这仍然需要大量的手工工作。
4. Param Miner插件
可以通过将Param Miner扩展从BApp商店添加到Burp来自动化识别非缓存键输入。要使用Param Miner,您只需右键单击您想要分析的请求包,并单击“Guess headers”。然后,Param Miner在后台运行,从其大量的、内置的头列表发送包含不同输入的请求。如果其中有注入的请求对响应有影响,Param Miner将此记录在Burp中,如果您使用Burp Suite Professional,可以在“Issues”中,免费版可以在扩展的“Output”选项卡中("Extender" > "Extensions" > "Param Miner" > "Output")查看。
例如,在下面的截图中,Param Miner在网站的主页上发现了一个非缓存键 X-Forwarded-Host:
注意:当对线上网站测试非缓存键时,有可能在无意中导致缓存为真实用户提供。因此,确保所有请求都有唯一的缓存键是很重要的,这样它们才会只提供给您。要做到这一点,您可以在每次请求时手动添加一个缓存破坏者(例如一个唯一参数)到请求行。或者,如果你使用的是Param Miner,有一些选项可以自动为每个请求添加缓存破坏者。
4.1 从后端服务器引出有害的响应
一旦你确定了一个非缓存键,下一步就是准确评估网站是如何处理它的。理解这一点对于成功引发有害响应至关重要。如果一个输入在服务器的响应中没有经过适当的清理,或者被用于动态生成其他数据,那么这可能是web缓存投毒的入口点。
4.2 获取缓存的响应
通过操作输入来引起有害的响应已经成功了一半,但是除非能够缓存响应,否则不会有太大的效果,这有时会很棘手。
是否能够缓存响应取决于各种因素,如文件扩展名、内容类型、路由、状态码和响应头。您可能需要花一些时间来处理不同页面上的请求,并研究缓存的行为。一旦确定了如何获取包含恶意输入的缓存响应,就可以将攻击传递给潜在的受害者了。
5. 利用web缓存投毒漏洞
这个基本过程可以用来发现和利用各种不同的web缓存投毒漏洞。
在某些情况下,web缓存投毒漏洞是由于缓存设计中的一般缺陷而产生的。其他时候,特定网站实现缓存的方式可能会引入意想不到的行为,从而被利用。
在后面的部分中,我们将概述这两种场景的一些最常见的示例。
6. 如何防御web缓存投毒漏洞
防止网络缓存投毒的最有效方法显然是完全禁用缓存。虽然对许多网站来说,这可能不是一个现实的选择,但在其他情况下,这可能是可行的。例如,如果您使用缓存只是因为在采用CDN时默认启用了缓存,那么可能有必要评估默认缓存选项是否真的反映了您的需求。
即使您确实需要使用缓存,将其限制为纯静态文件响应也是有效的,前提是您要对“静态”类保持足够的警惕。例如,确保攻击者不能欺骗后端服务器,将正常的静态资源替换为攻击者的恶意静态资源。
这也与更广泛的web安全问题有关。现在大多数网站在其开发过程和日常运营中都加入了各种第三方技术。无论您自己的内部安全状况多么健壮,只要将第三方技术集成到您的环境中,您就需要依赖开发人员与您一样具有安全意识。你的安全程度取决于你的弱点,在集成任何第三方技术之前,确保完全理解其安全性影响是至关重要的。
特别是在web缓存中毒的情况下,这不仅意味着要决定是否在默认情况下打开缓存,还需要查看CDN支持哪些HTTP头。由于攻击者能够操纵一系列模糊的请求头,其中许多对网站的功能来说是完全不必要的,所以上面讨论的一些web缓存投毒漏洞就暴露了出来。同样,您可能会在没有意识到的情况下受到这些类型的攻击,这纯粹是因为您实现了某些默认支持这些非缓存键输入的技术。如果是站点不需要的HTTP头,那么应该禁用它。
在实现缓存时,还应该采取以下注意事项:
如果出于性能原因考虑从缓存键中排除某些内容,则重写请求。
不要接受比较大的GET请求。请注意,某些第三方技术在默认情况下可能允许这种情况。
修补客户端漏洞,即使它们看起来不可利用。由于缓存的行为不可预测,这些漏洞中的一些实际上可能会被利用。不管是基于缓存的还是其他的,这些漏洞被人利用可能只是时间问题。




