# Proxy / WAF Protections Bypass {{#include ../banners/hacktricks-training.md}} ## 경로 조작을 통한 Nginx ACL 규칙 우회 기술 [이 연구에서](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies). Nginx 규칙 예: ```plaintext location = /admin { deny all; } location = /admin/ { deny all; } ``` Nginx는 우회 방지를 위해 경로 정규화를 수행합니다. 그러나 백엔드 서버가 Nginx가 제거하지 않는 문자를 제거하는 다른 정규화를 수행하는 경우, 이 방어를 우회할 수 있을 가능성이 있습니다. ### **NodeJS - Express** | Nginx Version | **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 Version | **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 Version | **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 규칙 우회 ### 경로 혼동 [**이 게시물**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)에서는 ModSecurity v3(3.0.12까지)가 접근된 경로(매개변수 시작까지)를 포함해야 하는 `REQUEST_FILENAME` 변수를 **부적절하게 구현했다**고 설명합니다. 이는 경로를 얻기 위해 URL 디코드를 수행했기 때문입니다.\ 따라서 mod security에서 `http://example.com/foo%3f';alert(1);foo=`와 같은 요청은 `%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 우회 ### 잘못된 헤더 [이 연구](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 우회 ### 요청 크기 제한 일반적으로 WAF는 요청을 확인하기 위한 특정 길이 제한이 있으며, POST/PUT/PATCH 요청이 이를 초과하면 WAF는 요청을 확인하지 않습니다. - AWS WAF의 경우 [**문서를 확인할 수 있습니다**](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
- [**Azure 문서**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**에서:** 구형 웹 애플리케이션 방화벽(Core Rule Set 3.1 이하)은 요청 본문 검사를 끔으로써 **128 KB**보다 큰 메시지를 허용하지만, 이러한 메시지는 취약점 검사를 받지 않습니다. 최신 버전(Core Rule Set 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. ### 난독화 ```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