大规模缓存中毒漏洞 Web Cache Poisoning

大规模缓存中毒漏洞 Web Cache Poisoning

识别和利用 70 多个缓存中毒漏洞

大规模缓存中毒漏洞 Web Cache Poisoning

尽管 Web Cache Poisoning 已经存在多年,但技术堆栈中日益复杂的技术不断引入意想不到的行为,这些行为可以被滥用来实现新的缓存中毒攻击。在本文中,我将介绍我用来向各种 Bug Bounty 计划报告 70 多个缓存中毒漏洞的技术。如果您还不熟悉 Web Cache Poisoning 的基础知识,我强烈建议您阅读albinowax 的Practical Web Cache Poisoning

背景故事

2020 年 12 月 19 日,我发表了一篇关于影响 Varnish 配置的特定边缘情况的简短文章,其中发送大写的主机头可能会污染缓存。不幸的是,由于这需要一个特定的自定义 Varnish 配置,因此扫描它并没有给我带来其他结果。令我惊讶的是,在发表这篇文章后不久,我意识到 Cloudflare 也容易受到相同的大写主机头攻击,但这一次,它不需要自定义配置。这意味着 cloudflare 在将主机标头引入缓存键之前将其小写,但始终按照客户端发送的方式转发。如果 Cloudflare 背后的任何后端在发送大写主机标头时会以不同的响应进行响应,则它将导致缓存中毒。您可以在我的以前的文章,但是 Fastly 和 Cloudflare 现在都修复了该行为。由于这种微妙的不一致影响了一个很好的漏洞赏金目标子集,我决定看看我可以识别和大规模利用的其他常见模式。

Apache Traffic Server 中的 URL 片段处理不正确 ( CVE-2021-27577 )

Apache Traffic Server (ATS) 是 Yahoo 和 Apple 广泛使用的缓存 HTTP 代理。当发送到 ATS 的请求包含 url 片段时,ATS 会转发它而不剥离该片段。根据RFC7230,ATS 转发的请求是无效的,因为 origin-form 应该只由绝对路径和查询组成。

大规模缓存中毒漏洞 Web Cache Poisoning

此外,ATS 通过提取主机、路径和查询来生成缓存键,忽略 url 片段。因此,这意味着下面的两个请求将共享相同的缓存键:

大规模缓存中毒漏洞 Web Cache Poisoning
大规模缓存中毒漏洞 Web Cache Poisoning

ATS 在生成缓存密钥时忽略了 url 片段,但仍然转发它,这为缓存中毒攻击创造了巨大的机会。当 ATS 背后的代理配置为编码#为 时%23,攻击者可以在任何缓存键下缓存完全不同的路径。我能够使用这种技术来毒化静态文件,如下所示:

大规模缓存中毒漏洞 Web Cache Poisoning

如果后端也正常化/../,它将允许攻击者将用户重定向到任何路径,从而可以轻松升级 XSS 和 开放重定向。

大规模缓存中毒漏洞 Web Cache Poisoning

GitHub CP-DoS

由于缓存中毒漏洞的很大一部分是由未键入的标头引起的,因此我编写了一个工具来蛮力未键入的标头并检测缓存中毒。这使我能够快速扫描大规模的漏洞赏金目标。

由于许多漏洞赏金计划在其范围列表中包含 Github 存储库,因此一些 repo url 进入了我的目标列表。在查看扫描结果时,我注意到当标头content-type包含无效值时,所有 github 存储库都被标记​​为易受缓存中毒的影响。

大规模缓存中毒漏洞 Web Cache Poisoning

尽管扫描将 Github Repos 标记为易受攻击并且攻击在 Burpsuite 中有效,但我无法在浏览器中进行复制。很快就发现 Github 将 Authentication cookie 包含在缓存键中。虽然不可能毒化经过身份验证的用户的存储库,但可以删除所有访问它们的未经身份验证的用户的存储库,因为他们都共享相同的缓存密钥。这获得了 7500 美元,是我获得最高报酬的缓存中毒报告。

GitLab CP-DoS

GitLab 使用 Google Cloud Platform 和 Fastly 在https://assets.gitlab-static.net/*. Google Cloud Bucketsx-http-method-override默认支持使用header,它允许覆盖 HTTP 方法。附加 header x-http-method-override: POST,将返回一个 405 状态码,默认情况下 Fastly 不会缓存。但是,可以发送标头x-http-method-override: HEAD并将缓存毒化为返回空响应正文。

大规模缓存中毒漏洞 Web Cache Poisoning

此外,该PURGE方法也被启用,大大降低了攻击的复杂性。这获得了 4,850 美元的顶级赏金。除了 GitLab,我还能够在许多其他赏金目标上使用相同的技术。

X-Forwarded-Scheme – Rack中间件

Ruby on Rails 应用程序通常与 Rack 中间件一起部署。下面的 Rack 代码获取 value 的x-forwarded-scheme值并将其用作请求的方案。

大规模缓存中毒漏洞 Web Cache Poisoning

发送x-forwarded-scheme: http标头将导致 301 重定向到同一位置。如果响应被 CDN 缓存,它会导致重定向循环,本质上拒绝访问文件。这被利用在大量的赏金目标上,例如:

Hackerone.com 静态文件上的 CP-DoS

由于 Hackerone 的缓存配置设置为仅缓存静态文件,因此缓存中毒攻击仅限于静态文件。

大规模缓存中毒漏洞 Web Cache Poisoning

尽管在报告 DoS 漏洞时超出了范围,但仍获得了 2500 美元的赏金。

www.shopify.com 的单一请求 DoS

同样的技术也影响了www.shopify.com,但是 Shopify 的缓存配置增加了攻击的影响。由于服务器没有配置缓存 HTML 页面,而是默认缓存了 301 个请求,因此只需要一个不定时的请求就触发了 Cache Poisoning DoS。

大规模缓存中毒漏洞 Web Cache Poisoning

这最初获得了 1300 美元,但在进一步调查后发现这也会影响其他本地子域和主机,例如apps.shopify.com. 由于该漏洞影响了许多 Shopify 主机,并且只需要一个请求来毒化缓存,因此悬赏金额增加到 6300 美元

在 21 个子域上存储 XSS

在测试私人程序时,我注意到在 Hackerone 上发现的相同漏洞影响了他们的所有子域。然而这一次,服务器也信任X-forwarded-host301 重定向的标头,允许攻击者将 JS 文件重定向到攻击者控制的 Javascript。

大规模缓存中毒漏洞 Web Cache Poisoning

由于这可能导致在目标的主网站和超过 21 个其他子域上存储 XSS,因此将其分类为关键并奖励最高 3000 美元的赏金。

Cloudflare 和存储桶

由于 Cloudflare 是使用最广泛的内容交付网络,S3 等存储桶往往落后于 cloudflare。不幸的是,默认情况下,此设置过去容易受到缓存中毒的影响。

直到 2021 年 8 月 3 日,即使没有Cache-control指令,Cloudflare 也会缓存 403 状态代码。这使得污染托管在 S3 存储桶上并通过 Cloudflare 代理的任何文件成为可能。发送无效的授权标头会导致可缓存的 403 错误。

S3 存储桶:

大规模缓存中毒漏洞 Web Cache Poisoning

Azure 存储

Exodus 使用子域downloads.exodus.com来提供下载服务,例如 Exodus 钱包安装程序。由于文件存储在 Azure 存储 Blob 上,因此可能会导致带有精心设计的授权标头的可缓存 403 错误。Exodus 团队在收到报告几小时后解决了这个问题,并奖励了 2500 美元

大规模缓存中毒漏洞 Web Cache Poisoning

Cloudflare 还更改了它的默认配置,现在不再默认缓存 403 响应。

快速主机头注入

在向同一个漏洞赏金计划报告了多个缓存中毒漏洞后,他们同意将他们的 Varnish 配置文件发送给我,以便我可以更轻松地识别其他不一致之处。浏览文件后,我发现了一个类似于以下的片段:

大规模缓存中毒漏洞 Web Cache Poisoning

该片段用于托管地图图像的子域。请求图像看起来像这样:

大规模缓存中毒漏洞 Web Cache Poisoning

引入的规则使得当 url 路径与正则表达式匹配时,缓存键将只包含从 url 中提取的坐标,而忽略所有其他 url 组件。因此,上面请求的图像将具有以下缓存键:

/4/151/16

由于该规则仅在路径中包含提取的坐标,这意味着我可以将任何主机标头发送到后端,它仍然会匹配相同的缓存键。不幸的是,这行不通,因为 Fastly 拒绝任何未列入白名单的主机标头。

大规模缓存中毒漏洞 Web Cache Poisoning

通过Fastly-host在请求中附加标头,完全绕过了这种机制。如果fastly-host标头包含列入白名单的值,则主机标头可以更改为任何内容:

大规模缓存中毒漏洞 Web Cache Poisoning

虽然可以为 CP-DoS 使用主机头注入,但我希望得到更多,所以我决定深入挖掘。在查看同一程序上的其他 Fastly 主机时,我发现一个 html 文件redacted-cdn.com易受 DOM XSS 攻击。由于这是在redacted-cdn.comorigin下,所以xss本身没有影响。

fastly-host在发现主机头被转发后,我能够通过使用头来升级它,但是快速主机被用于生成缓存密钥。因此,以下请求将匹配缓存键:

https://assets.redacted.com/test.html

大规模缓存中毒漏洞 Web Cache Poisoning

由于两台主机都在同一个负载均衡器后面,因此可以缓存托管在redacted-cdn.com下的文件assets.redacted.com,这本质上允许我将易受攻击的 html 文件移动到不同的域并在不同的源下实现 xss。

注入键控参数

很多时候,缓存被配置为仅在缓存键中包含特定的 GET 参数。这在托管图像的 CDN 中尤其常见,这些图像使用参数来修改图像大小或格式。

在使用 Fastly 缓存图像测试目标时,我注意到该size参数包含在缓存键中,但所有其他参数都被忽略了。如果size添加了两个参数,则两个参数都包含在缓存键中,但后端服务器使用最后一个参数的值。考虑到 Fastly (Varnish),在生成缓存密钥之前不做任何 url 规范化,我能够想出以下 DoS 方法:

大规模缓存中毒漏洞 Web Cache Poisoning

URL 编码第二个size参数导致它被缓存忽略,但被后端使用。将参数值设为 0 将导致可缓存的 400 错误请求。

用户代理规则

由于 FFUF 或 Nuclei 等大量流量工具会生成大量流量,一些开发人员决定阻止与其用户代理匹配的请求。具有讽刺意味的是,这些调整可能会引入不必要的缓存中毒 DoS 机会。

大规模缓存中毒漏洞 Web Cache Poisoning

我发现这适用于多个目标,使用来自不同工具或扫描仪的用户代理。

非法headers字段

标头名称格式在RFC7230 中定义如下:

大规模缓存中毒漏洞 Web Cache Poisoning

理论上,如果标头名称包含tchar 中列出的字符以外的字符,则应以 400 Bad 请求拒绝它。然而在实践中,服务器并不总是遵守 RFC。利用这种细微差别的最简单方法是针对 Akamai,它不会拒绝无效的标头,但只要缓存控制标头不存在,它就会转发它们并缓存任何 400 错误。

大规模缓存中毒漏洞 Web Cache Poisoning

发送包含非法字符的标头\会导致可缓存的 400 Bad Request 错误。这是整个测试过程中最常见的模式之一。

寻找新的headers

除了请求行的属性可用于毒化缓存的少数新案例外,检测到的大多数缓存毒化漏洞都是由未键入的标头引起的。

由于我想扩展我的标头列表,我使用 Google 的 BigQuery 来查询 HTTP 存档以获取Vary响应标头中使用的值。该因人而异头包含应由缓存服务器被键入头名。这使我能够找到一些额外的易受攻击的实例,否则这些实例不会被检测到。

这是与 Param-Miner 的标头列表合并的标头列表。

https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6 (2917L)

通用headers

下面的列表显示了用于利用 70 多个缓存服务器的所有标头。

大规模缓存中毒漏洞 Web Cache Poisoning

from

转载请注明出处及链接

Leave a Reply

您的电子邮箱地址不会被公开。 必填项已用 * 标注