# Proxy / WAF Protections Bypass {{#include ../banners/hacktricks-training.md}} ## Bypass Nginx ACL Rules with Pathname Manipulation 技术 [来自这项研究](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)。 Nginx 规则示例: ```plaintext location = /admin { deny all; } location = /admin/ { deny all; } ``` 为了防止绕过,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` | ### **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` | ### **Spring Boot** | Nginx 版本 | **Spring Boot 绕过字符** | | ---------- | -------------------------- | | 1.22.0 | `;` | | 1.21.6 | `;` | | 1.20.2 | `\x09`, `;` | | 1.18.0 | `\x09`, `;` | | 1.16.1 | `\x09`, `;` | ### **PHP-FPM** Nginx FPM 配置: ```plaintext location = /admin.php { deny all; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; } ``` Nginx 被配置为阻止对 `/admin.php` 的访问,但可以通过访问 `/admin.php/index.php` 来绕过此限制。 ### 如何防止 ```plaintext location ~* ^/admin { deny all; } ``` ## 绕过 Mod Security 规则 ### 路径混淆 [**在这篇文章中**](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` 也受到此错误的影响。 在 Mod Security 的版本 2 中发生了类似的情况,允许绕过一种保护,该保护阻止用户访问与备份文件相关的特定扩展名的文件(例如 `.bak`),只需通过发送点 URL 编码为 `%2e`,例如:`https://example.com/backup%2ebak`。 ## 绕过 AWS WAF ACL ### 格式错误的头部 [这项研究](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) 提到可以通过发送一个未被 AWS 正确解析但被后端服务器解析的“格式错误”的头部来绕过应用于 HTTP 头部的 AWS WAF 规则。 例如,发送以下请求,在头部 X-Query 中包含 SQL 注入: ```http GET / HTTP/1.1\r\n Host: target.com\r\n X-Query: Value\r\n \t' or '1'='1' -- \r\n Connection: close\r\n \r\n ``` 可以绕过AWS WAF,因为它无法理解下一行是头部值的一部分,而NODEJS服务器可以(这个问题已修复)。 ## 通用WAF绕过 ### 请求大小限制 通常,WAF对请求的长度有一定的限制,如果POST/PUT/PATCH请求超过该限制,WAF将不会检查该请求。 - 对于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
- 来自[**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或更高版本),可以通过禁用最大请求体限制来实现。当请求超过大小限制时: 如果是**预防模式**:记录并阻止请求。\ 如果是**检测模式**:检查到限制,忽略其余部分,并记录如果`Content-Length`超过限制。 - 来自[**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:** 默认情况下,WAF仅检查请求的前8KB。通过添加高级元数据,可以将限制提高到128KB。 - 来自[**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:** 最多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 "<" #using backticks instead of parenetheses java%0ascript:alert(1) #using encoded newline characters