# 缓存投毒与缓存欺骗
从零到英雄学习AWS黑客技术,通过 htARTE (HackTricks AWS Red Team Expert)!
支持HackTricks的其他方式:
* 如果您想在**HackTricks中看到您的公司广告**或**下载HackTricks的PDF**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks商品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs系列**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram群组**](https://t.me/peass) 或在**Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
\
使用 [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) 轻松构建并**自动化工作流程**,由世界上**最先进的**社区工具提供支持。\
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
## 区别
> **web缓存投毒与web缓存欺骗有什么区别?**
>
> * 在**web缓存投毒**中,攻击者导致应用程序将一些恶意内容存储在缓存中,然后这些内容从缓存中提供给其他应用程序用户。
> * 在**web缓存欺骗**中,攻击者导致应用程序将属于另一个用户的一些敏感内容存储在缓存中,然后攻击者从缓存中检索这些内容。
## 缓存投毒
投毒缓存的目标是让**客户端加载部分或完全由攻击者控制的意外资源**。\
被投毒的响应只会提供给在缓存被投毒时访问受影响页面的用户。因此,影响可能从不存在到巨大不等,这取决于页面是否受欢迎。
要执行缓存投毒攻击,首先需要**识别未键入的输入**(不需要出现在缓存请求中但会改变返回页面的参数),看看**如何滥用**这个参数并**让响应被缓存**。
### 发现:检查HTTP头部
通常,当一个响应被**存储在缓存中**时,会有一个**头部指示这一点**,你可以在这篇文章中查看你应该注意哪些头部:[**HTTP缓存头部**](../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers)。
### 发现:缓存400代码
如果你认为响应被存储在缓存中,你可以尝试**发送带有错误头部的请求**,这应该会收到一个**状态码为400的响应**。然后尝试正常访问请求,如果**响应是400状态码**,你就知道它是脆弱的(你甚至可以执行DoS)。\
一个配置不当的头部可能只是`\:`作为头部。\
_注意有时这类状态代码不会被缓存,所以这个测试将是无用的。_
### 发现:识别和评估未键入的输入
你可以使用 [**Param Miner**](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943) 来**暴力破解可能**改变页面响应的**参数和头部**。例如,一个页面可能使用头部`X-Forwarded-For`来指示客户端从那里加载脚本:
```markup
```
### 从后端服务器引发有害响应
在确定了参数/头部后,检查它是如何被**清洗**的,以及它在响应中**反映**的**位置**或如何影响来自头部的响应。你能以任何方式滥用它吗(执行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攻击:
```markup
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a.">"
```
_Note that this will poison a request to `/en?region=uk` not to `/en`_
### 利用Web缓存投毒来利用Cookie处理漏洞
Cookies也可能反映在页面的响应中。如果您能够滥用它来引起XSS,例如,您可能能够在多个加载恶意缓存响应的客户端中利用XSS。
```markup
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`作为重定向的域名。您可以控制重定向指向的页面位置。
```markup
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 污染缓存:
```markup
GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com
```
### 利用 HTTP 请求走私攻击 HTTP 缓存投毒
在此了解如何执行[通过滥用 HTTP 请求走私进行缓存投毒攻击](http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-poisoning)。
### 自动化测试 Web 缓存投毒
可以使用 [Web 缓存漏洞扫描器](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner) 自动测试 web 缓存投毒。它支持许多不同的技术,并且高度可定制。
示例用法:`wcvs -u example.com`
\
使用 [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) 轻松构建并**自动化工作流程**,由世界**最先进**的社区工具提供支持。\
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
## 易受攻击的示例
### 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
在 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` 值并将其用作请求的方案**。
![](<../.gitbook/assets/image (159) (2).png>)
发送 `x-forwarded-scheme: http` 头将导致 301 重定向到相同位置,这将导致该资源的 DoS,如下例所示:
![](<../.gitbook/assets/image (166).png>)
应用程序可能还支持头部 `X-forwarded-host` 并将用户重定向到该主机,使得可以从攻击者服务器加载 JavaScript 文件:
![](<../.gitbook/assets/image (157) (2).png>)
### 403 和存储桶
以前,**Cloudflare** 曾经**缓存** **403 响应**,因此发送**错误的 Authorization** 头试图访问暴露的 **S3** 或 **Azure 存储 Blob** 将返回一个将被缓存的 403。Cloudflare 不再缓存 403 响应,但这可能适用于其他代理。
![](<../.gitbook/assets/image (171).png>)
### 注入键控参数
通常,缓存被配置为**仅在缓存键中包含特定的 GET 参数**。
例如,Fastly 使用 Varnish **缓存了请求中的 `size` 参数**,但如果你**同时**发送了**`siz%65`** 参数并带有错误值,**缓存键**将使用**正确书写的 size 参数**构建,但**后端**使用的是**URL 编码参数中的值**。
![](<../.gitbook/assets/image (180).png>)
对第二个 `size` 参数进行 URL 编码会导致缓存忽略它,但后端使用它。将参数值设置为 0 将导致可缓存的 400 Bad Request。
### 用户代理规则
由于像 FFUF 或 Nuclei 这样的工具生成的流量量很大,一些开发者决定阻止匹配其用户代理的请求。讽刺的是,这些调整可能会引入不希望的缓存投毒和 DoS 机会。
![](<../.gitbook/assets/image (167) (2).png>)
我发现这在多个目标上有效,使用来自不同工具或扫描器的用户代理。
### 非法头字段
头字段名称格式在 [RFC7230](https://datatracker.ietf.mrg/doc/html/rfc7230) 中定义如下:
![](<../.gitbook/assets/image (175) (2).png>)
理论上,如果头字段名称包含 **tchar** 列表中未列出的字符,则应以 400 Bad request 拒绝。然而,实际上,服务器并不总是遵守 RFC。利用这一细微差别的最简单方法是针对 Akamai,它不会拒绝无效的头字段,但会转发它们,并缓存任何 400 错误,只要没有 cache-control 头字段。
![](<../.gitbook/assets/image (163).png>)
发送包含非法字符 `\` 的头字段会导致一个可缓存的 400 Bad Request 错误。这是我在测试中发现的最常见的模式之一。
### 发现新头字段
[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/#using-http-request-smuggling-to-perform-web-cache-deception)。
## 参考资料
* [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)
\
使用 [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) 轻松构建并**自动化工作流程**,由世界**最先进**的社区工具提供支持。\
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
从零开始学习 AWS 黑客攻击,成为 htARTE (HackTricks AWS 红队专家)!
支持 HackTricks 的其他方式:
* 如果你想在 HackTricks 中看到你的**公司广告**或**下载 HackTricks 的 PDF** 版本,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* 发现[**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs**](https://opensea.io/collection/the-peass-family)系列
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram 群组**](https://t.me/peass) 或在 **Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享你的黑客技巧。