Web缓存投毒
翻译
原文:https://portswigger.net/web-security/web-cache-poisoning
- name: 翻译
desc: 原文:https://portswigger.net/web-security/web-cache-poisoning
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
# 0Web缓存投毒
在本节中,我们将讨论什么是 Web 缓存投毒,以及哪些行为会导致 Web 缓存投毒漏洞。我们还将研究利用这些漏洞的一些方法,并提出减少这些漏洞暴露面的建议方法。
# 1什么是Web缓存投毒?
Web 缓存投毒是一种高级技术,攻击者借助 Web 服务器和缓存的行为,向其他用户提供有害的 HTTP 响应。
从根本上说,Web 缓存投毒涉及两个阶段。首先,攻击者必须弄清楚,如何在无意中,从后端服务器引出一个 包含某种危险有效载荷 的响应。一旦成功,他们需要确保这些响应已经被缓存,并在随后的过程中提供给预期的受害者。
Web 缓存投毒可能是一种极具破坏性的手段,可以利用 XSS (opens new window)、JavaScript 注入、开放重定向等漏洞来分发多种不同的攻击。
实验室
如果你已经熟悉 Web 缓存投毒背后的基本概念,并且只想在一些实际的、易受攻击的目标上练习和利用它们,那么你可以从下面的链接访问本主题中的所有实验室。
# 1.1Web缓存投毒研究
这项技术首先在我们 2018 年的研究论文《实用的Web缓存投毒》中得到推广,并在 2020 年的第二篇研究论文《Web缓存纠缠:投毒的新途径》中得到进一步发展。如果你对我们 如何在野外发现和利用这些漏洞 的详细描述感兴趣,可以在我们的研究页面上找到并查看完整的文章。
# 1.2Web缓存是如何工作的?
要了解 Web 缓存投毒漏洞是如何产生的,必须对 Web 缓存的工作原理有一个基本的了解。
如果服务器必须单独向每个 HTTP 请求发送新的响应,这可能会使服务器过载,从而导致延迟问题和糟糕的用户体验,尤其是在繁忙时期。而 缓存 主要是用于减少此类问题的一种手段。
缓存位于服务器和用户之间,它保存(也称缓存)对特定请求的响应,这通常会被缓存在一段固定的时间点。如果另一个用户随后发送了一个等效请求,则缓存直接向用户提供缓存响应的副本,而无需与后端进行任何交互。这减少了服务器必须处理的重复请求数,极大地减轻了服务器的负载。
# 1.2.1缓存键
当缓存收到一个 HTTP 请求时,它首先必须确定,是否有一个可以直接提供的缓存响应,或者是否必须转发该请求 以供后端服务器处理。缓存通过比较请求组件的预定义子集(统称为 “缓存键”)来识别等效请求。通常,这将包含请求行和Host
标头。如果某个请求的缓存键 未包含在缓存当中,则称为 “无键”(unkeyed)。
如果传入请求的 缓存键 与前一个请求的键匹配,则缓存会认为它们是等效的。因此,它将提供为原始请求生成的缓存响应副本。这适用于 具有匹配缓存键 的所有后续请求,直到缓存的响应过期。
至关重要的是,缓存会完全忽略请求的其他组成部分。稍后我们将更详细地探讨 此行为造成的影响。
# 2Web缓存投毒攻击的影响是什么?
Web 缓存投毒的影响,在很大程度上取决于两个关键因素:
- 攻击者究竟可以成功缓存什么。由于缓存投毒更像是一种分发攻击的手段,而不是一种独立的攻击,因此 Web 缓存投毒的影响与所注入的载荷危害程度密不可分。与大多数类型的攻击一样,Web 缓存投毒也可以与其他攻击结合使用,以进一步升级潜在的影响。
- 受影响网页的流量。
在缓存投毒时,被投毒的响应 仅提供给 访问了受影响页面的用户。因此,影响范围飘忽不定,具体取决于这个页面的受欢迎程度。例如,如果攻击者设法毒害了一个 主要网站 的首页缓存响应,则该攻击可能会自动影响数千名用户,而无需攻击者进行任何后续交互。
请注意,缓存条目的持续时间不一定会干扰 Web 缓存投毒的影响。因为这种攻击通常可以编写一种脚本,实现无限期地重新毒害缓存。
# 3构造Web缓存投毒攻击
一般来说,构建一个基本的 Web 缓存投毒攻击包括以下步骤:
# 3.1识别和评估无键的输入
任何 Web 缓存投毒攻击都依赖于对无键输入(如标头)的操纵。Web 缓存在决定是否向用户提供缓存响应时,会忽略无键的输入。此行为意味着,你可以使用它们来注入有效载荷并引发 “投毒” 的响应,如果该响应被缓存,则稍后该响应将被提供给 请求中具有匹配缓存键 的所有用户。因此,构建 Web 缓存投毒攻击的第一步是,识别服务器支持哪些无键输入。
你可以在请求中添加随机输入,并观察它们是否对响应产生影响,从而手动识别无键的输入。这可能是显而易见的,例如直接在响应中反馈输入,或触发完全不同的响应。然而,某些时候的效果更微妙,需要一些侦察工作才能弄清楚。你可以使用 Burp Comparer 等工具,来比较 有/没有 注入时的响应,但这仍然需要大量的手动工作。
(((译者加:Burp Comparer 是默认自带的工具,启动 BurpSuite 之后在选项卡中就可以看到)))
# 3.1.1Param Miner扩展
幸运的是,你可以从 BApp 商店将 Param Miner (opens new window) 扩展添加到 Burp 中,从而自动识别无键的输入。
要使用 Param Miner,你只需右键单击想要调查的请求,然后单击 “Guess header”(猜测标头)。然后,Param Miner 将在后台运行,使用其大量的内置标头列表,生成并发送具有不同输入的请求。如果其注入的某个请求 对响应有影响,Param Miner 会将其记录在 Burp 中,
- 如果你使用的是 Burp Suite Professional (opens new window),则会记录在 “Issues” 窗口中,
- 或者如果你使用的是 Burp Suite Community Edition (opens new window),则记录在扩展的 “Output” 选项卡中(“Extensions” > “Installed” > “Param Miner” > “Output”)

注意
在实时网站上测试无键的输入时,这存在无意中的风险,缓存有可能向真实用户提供生成的响应。因此,请务必确保你的请求都具有唯一的缓存键,以便它们仅提供给你。为此,你可以在每次发出请求时,手动在请求行中添加一个缓存干扰器(例如唯一参数)。或者,如果你正在使用 Param Miner,则可以选择 自动为每个请求添加缓存干扰器。
# 3.2从后端服务器引出有害响应
一旦你发现了一个无键的输入,下一步就是评估网站是如何处理它的。了解这一点对于 成功地引发有害响应 至关重要。如果一个输入没有经过适当的清理,就反馈在来自服务器的响应中,或者被用来动态生成其他数据,那么这就是 Web 缓存投毒的潜在入口点。
# 3.3获取缓存的响应
操纵输入以引发有害响应 是成功的一半,但除非你可以缓存响应,否则它不会取得多大的效果,这有时可能很棘手。
“是否缓存响应” 可能取决于各种因素,例如文件扩展名、内容类型、路由、状态代码和响应标头。你可能需要花一些时间,来简单地处理不同页面上的请求,并研究缓存的行为方式。一旦你弄清楚了 如何缓存包含恶意输入的响应,你就可以将漏洞利用传递给潜在的受害者了。
# 4利用Web缓存投毒漏洞
这个基本过程,可用于发现和利用各种不同的 Web 缓存投毒漏洞。
在某些情况下,Web 缓存投毒漏洞是由于 缓存设计中的一般缺陷而产生的。其他时候,某些网站实现缓存的特定方式 可能会引入可被利用的意外差异。
在以下各节中,我们将概述这两种场景的一些最常见示例。我们还提供了许多交互式实验室,以便你可以看到其中一些漏洞的实际应用,并练习利用它们。
# 5如何防范Web缓存投毒漏洞
防止 Web 缓存中毒的有效方法,显然是完全禁用缓存。但对于许多网站来说,这可能不是一个实用的选择,但在其他情况下,这可能是可行的。例如,如果你使用缓存,是因为当你采用 CDN 时它默认处于打开状态,那么这可能值得评估 默认的缓存选项 是否真的反映了你的需求。
即使你确实需要使用缓存,将其限制为纯静态响应也是有效的,前提是你对归类为 “静态” 的内容保持足够的警惕。例如,确保攻击者无法欺骗后端服务器,以检索其恶意版本的静态资源,而不是真正的静态资源。
这也涉及到更广泛的网络安全问题。大多数网站现在都将各种第三方技术,纳入其开发流程和日常运营中。无论你自己的内部安全态势有多强大,一旦你将第三方技术整合到自己的环境,你就需要祈祷,希望他们的开发人员也像你一样具有安全意识。由于你的安全性 仅取决于你的最薄弱点,因此在集成任何第三方技术之前,确保你完全了解这些技术的安全含义,这至关重要。
特别是在 Web 缓存中毒的场景下,这不仅意味着 决定是否默认打开缓存,还意味着 需要检查你的 CDN 支持哪些标头。上面讨论的几个 Web 缓存中毒漏洞之所以暴露出来,是因为攻击者能够操纵一系列模糊的请求标头,其中许多标头 对于网站的功能来说 是完全不必要的。同样,你可能会在不知不觉中,将自己暴露在此类攻击之下,这纯粹是因为你已经实施了一些技术,默认支持这些无键的输入。如果网站 在不需要某个标头的情况下,也能够正常工作,则应禁用该标头。
在实现缓存时,还应采取以下预防措施:
- 如果出于性能原因,想要从缓存键中排除某些内容,请重写整个请求。
- 不要接受畸形
GET
请求。请注意,默认情况下,某些第三方技术可能允许此操作。 - 修补客户端漏洞,即使它们看起来不可利用。由于缓存行为中的不可预测的异常,其中一些漏洞实际上可能是可利用的。这只是一个时间问题,当有人发现一个解析差异时,无论是基于缓存还是其他方式,都可能使这个漏洞被利用。