diff --git a/src/pentesting-web/cache-deception/README.md b/src/pentesting-web/cache-deception/README.md index 33ffcad96..2e3880710 100644 --- a/src/pentesting-web/cache-deception/README.md +++ b/src/pentesting-web/cache-deception/README.md @@ -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 ``` ### 从后端服务器引发有害响应 -通过识别的参数/头部检查它是如何被**清理**的,以及**在哪里**被**反映**或影响响应。你能以任何方式滥用它吗(执行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 被用户频繁使用,常规请求将清除缓存。 -### 生成带有分隔符、规范化和点的差异 +### 使用分隔符、规范化和点生成差异 检查: @@ -115,16 +115,16 @@ cache-poisoning-via-url-discrepancies.md ### 使用多个头部来利用 web 缓存污染漏洞 -有时您需要 **利用多个无键输入** 来滥用缓存。例如,如果您将 `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" +``` +操作提示: + +- 许多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}} diff --git a/src/pentesting-web/proxy-waf-protections-bypass.md b/src/pentesting-web/proxy-waf-protections-bypass.md index 0a4e7c514..7f2bdadb1 100644 --- a/src/pentesting-web/proxy-waf-protections-bypass.md +++ b/src/pentesting-web/proxy-waf-protections-bypass.md @@ -1,9 +1,9 @@ -# 代理 / WAF 保护绕过 +# Proxy / WAF Protections Bypass {{#include ../banners/hacktricks-training.md}} -## 通过路径名操作绕过 Nginx ACL 规则 +## Bypass Nginx ACL Rules with Pathname Manipulation 技术 [来自这项研究](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)**:** -
可以检查的应用负载均衡器和 AWS AppSync 保护的 web 请求体的最大大小8 KB
可以检查的 CloudFront、API Gateway、Amazon Cognito、App Runner 和 Verified Access 保护的 web 请求体的最大大小**64 KB
+
可以检查的应用负载均衡器和AWS AppSync保护的最大Web请求体大小8 KB
可以检查的CloudFront、API Gateway、Amazon Cognito、App Runner和Verified Access保护的最大Web请求体大小**64 KB
-- 来自 [**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。 -### 混淆 +### 静态资产检查漏洞 (.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/) + +### 混淆 ```bash # IIS, ASP Clasic <%s%cr%u0131pt> == #changing the case of the tag < #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}}