# 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는 검사하기 전에 경로 정규화(path normalization)를 수행합니다. 그러나 백엔드 서버가 다른 정규화(nginx가 제거하지 않는 문자를 제거하는 등)를 수행하면 이 방어를 우회할 수 있습니다. ### **NodeJS - Express** | Nginx 버전 | **Node.js Bypass Characters** | | ------------- | ----------------------------- | | 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 Bypass Characters** | | ------------- | -------------------------------------------------------------- | | 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 Bypass Characters** | | ------------- | --------------------------------- | | 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 규칙 우회 ### 경로 혼동 [**In this post**](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에서는 `%3f`가 `?`로 변환되어 URL 경로를 종료한다고 보고 경로를 `/foo`로 간주하지만, 실제로 서버가 받는 경로는 `/foo%3f';alert(1);foo=`입니다. `REQUEST_BASENAME`과 `PATH_INFO` 변수도 이 버그의 영향을 받았습니다. 비슷한 문제가 Mod Security 버전 2에서도 발생했는데, 백업 파일과 관련된 특정 확장자(예: `.bak`)에 대한 접근을 차단하는 보호를 우회할 수 있었고, 이는 점을 `%2e`로 URL 인코딩하여 전송하면 가능했습니다. 예: `https://example.com/backup%2ebak`. ## AWS WAF ACL 우회 ### 잘못된 Header [This research](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)에서는 AWS가 제대로 파싱하지 못했지만 backend server는 파싱한 "malformed" header를 전송함으로써 HTTP headers에 적용된 AWS WAF 규칙을 우회할 수 있었음을 언급합니다. 예를 들어, 헤더 X-Query에 SQL injection을 넣어 다음과 같은 요청을 보내는 경우: ```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 ``` It was possible to bypass AWS WAF because it wouldn't understand that the next line is part of the value of the header while the NODEJS server did (this was fixed). ## 일반적인 WAF 우회 ### Request Size Limits Commonly WAFs have a certain length limit of requests to check and if a POST/PUT/PATCH request is over it, the WAF won't check the request. - For AWS WAF, you can [**check the documentation**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
Application Load Balancer 및 AWS AppSync 보호에서 검사할 수 있는 웹 요청 본문 최대 크기8 KB
CloudFront, API Gateway, Amazon Cognito, App Runner 및 Verified Access 보호에서 검사할 수 있는 웹 요청 본문 최대 크기**64 KB
- From [**Azure docs**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:** Older Web Application Firewalls with Core Rule Set 3.1 (or lower) allow messages larger than **128 KB** by turning off request body inspection, but these messages won't be checked for vulnerabilities. For newer versions (Core Rule Set 3.2 or newer), the same can be done by disabling the maximum request body limit. When a request exceeds the size limit: If p**revention mode**: 요청을 기록하고 차단합니다.\ If **detection mode**: 제한까지 검사하고 나머지는 무시하며, `Content-Length`가 제한을 초과하면 로그를 남깁니다. - From [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:** By default, the WAF inspects only the first 8KB of a request. It can increase the limit up to 128KB by adding Advanced Metadata. - From [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:** Up to 128KB. ### Static assets inspection gaps (.js GETs) Some CDN/WAF stacks apply weak or no content inspection to GET requests for static assets (for example paths ending with `.js`), while still applying global rules like rate limiting and IP reputation. Combined with auto-caching of static extensions, this can be abused to deliver or seed malicious variants that affect subsequent HTML responses. Practical use cases: - Send payloads in untrusted headers (e.g., `User-Agent`) on a GET to a `.js` path to avoid content inspection, then immediately request the main HTML to influence the cached variant. - Use a fresh/clean IP; once an IP is flagged, routing changes can make the technique unreliable. - In Burp Repeater, use "Send group in parallel" (single-packet style) to race the two requests (`.js` then HTML) through the same front-end path. This pairs well with header-reflection cache poisoning. See: {{#ref}} cache-deception/README.md {{#endref}} - [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/) ### 난독화 ```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