Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -7,7 +7,7 @@ import json
|
|
| 7 |
from urllib.parse import urlparse
|
| 8 |
from requests.exceptions import RequestException
|
| 9 |
|
| 10 |
-
# --- Core Scanner Logic
|
| 11 |
|
| 12 |
def normalize_host(host: str) -> str:
|
| 13 |
"""Normalize host to include scheme if missing."""
|
|
@@ -157,9 +157,8 @@ def scan_target(url, safe_check, windows_mode, waf_bypass, vercel_bypass, custom
|
|
| 157 |
|
| 158 |
host = normalize_host(url)
|
| 159 |
timeout = 10
|
| 160 |
-
verify_ssl = True
|
| 161 |
|
| 162 |
-
# Determine Payload
|
| 163 |
if safe_check:
|
| 164 |
body, content_type = build_safe_payload()
|
| 165 |
check_func = is_vulnerable_safe_check
|
|
@@ -193,7 +192,6 @@ def scan_target(url, safe_check, windows_mode, waf_bypass, vercel_bypass, custom
|
|
| 193 |
target_url = f"{host}{path}"
|
| 194 |
logs.append(f"\nTesting: {target_url}")
|
| 195 |
|
| 196 |
-
# Test 1: Direct Path
|
| 197 |
resp, error = send_payload(target_url, headers, body, timeout, verify_ssl)
|
| 198 |
|
| 199 |
if error:
|
|
@@ -208,8 +206,6 @@ def scan_target(url, safe_check, windows_mode, waf_bypass, vercel_bypass, custom
|
|
| 208 |
return "\n".join(logs)
|
| 209 |
else:
|
| 210 |
logs.append("Result: Not Vulnerable")
|
| 211 |
-
|
| 212 |
-
# Test 2: Follow Redirect (if 1st failed)
|
| 213 |
redirect_url = resolve_redirects(target_url, timeout, verify_ssl)
|
| 214 |
if redirect_url != target_url:
|
| 215 |
logs.append(f"\nFollowing redirect to: {redirect_url}")
|
|
@@ -229,19 +225,37 @@ def scan_target(url, safe_check, windows_mode, waf_bypass, vercel_bypass, custom
|
|
| 229 |
|
| 230 |
# --- UI Setup ---
|
| 231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 232 |
with gr.Blocks(title="React2Shell Scanner") as demo:
|
| 233 |
gr.Markdown("# React2Shell Scanner (CVE-2025-55182)")
|
| 234 |
-
gr.Markdown("Web-based scanner for React Server Components / Next.js RCE.
|
| 235 |
|
|
|
|
|
|
|
|
|
|
| 236 |
with gr.Row():
|
| 237 |
url_input = gr.Textbox(label="Target URL", placeholder="https://example.com")
|
| 238 |
path_input = gr.Textbox(label="Custom Path (Optional)", placeholder="/_next", value="")
|
| 239 |
|
| 240 |
with gr.Row():
|
| 241 |
-
safe_check = gr.Checkbox(label="Safe Check
|
| 242 |
windows_mode = gr.Checkbox(label="Windows Mode", value=False, info="Use PowerShell payload.")
|
| 243 |
-
waf_bypass = gr.Checkbox(label="Generic WAF Bypass", value=False, info="Add junk data.")
|
| 244 |
-
vercel_bypass = gr.Checkbox(label="Vercel WAF Bypass", value=False)
|
| 245 |
|
| 246 |
scan_btn = gr.Button("Scan Target", variant="primary")
|
| 247 |
output_box = gr.Textbox(label="Scan Output", lines=10)
|
|
@@ -252,6 +266,6 @@ with gr.Blocks(title="React2Shell Scanner") as demo:
|
|
| 252 |
outputs=output_box
|
| 253 |
)
|
| 254 |
|
| 255 |
-
gr.Markdown("**Disclaimer:** This tool is for educational and authorized security testing purposes only. Do not scan targets you do not own
|
| 256 |
|
| 257 |
demo.launch()
|
|
|
|
| 7 |
from urllib.parse import urlparse
|
| 8 |
from requests.exceptions import RequestException
|
| 9 |
|
| 10 |
+
# --- Core Scanner Logic ---
|
| 11 |
|
| 12 |
def normalize_host(host: str) -> str:
|
| 13 |
"""Normalize host to include scheme if missing."""
|
|
|
|
| 157 |
|
| 158 |
host = normalize_host(url)
|
| 159 |
timeout = 10
|
| 160 |
+
verify_ssl = True
|
| 161 |
|
|
|
|
| 162 |
if safe_check:
|
| 163 |
body, content_type = build_safe_payload()
|
| 164 |
check_func = is_vulnerable_safe_check
|
|
|
|
| 192 |
target_url = f"{host}{path}"
|
| 193 |
logs.append(f"\nTesting: {target_url}")
|
| 194 |
|
|
|
|
| 195 |
resp, error = send_payload(target_url, headers, body, timeout, verify_ssl)
|
| 196 |
|
| 197 |
if error:
|
|
|
|
| 206 |
return "\n".join(logs)
|
| 207 |
else:
|
| 208 |
logs.append("Result: Not Vulnerable")
|
|
|
|
|
|
|
| 209 |
redirect_url = resolve_redirects(target_url, timeout, verify_ssl)
|
| 210 |
if redirect_url != target_url:
|
| 211 |
logs.append(f"\nFollowing redirect to: {redirect_url}")
|
|
|
|
| 225 |
|
| 226 |
# --- UI Setup ---
|
| 227 |
|
| 228 |
+
# Guide Content in Markdown
|
| 229 |
+
guide_content = """
|
| 230 |
+
### 📋 Recommended Workflow
|
| 231 |
+
1. **Safe Check (Start Here):** Non-destructive. Checks for side-channel indicators without executing code.
|
| 232 |
+
2. **Standard RCE:** If Safe Check is inconclusive, use this to attempt actual code execution (Safe Check must be OFF).
|
| 233 |
+
3. **Windows Mode:** If target is Windows-based and Standard RCE failed.
|
| 234 |
+
4. **WAF Bypass:** If you receive `403 Forbidden` errors.
|
| 235 |
+
|
| 236 |
+
### ℹ️ Mode Definitions
|
| 237 |
+
* **Safe Check:** Triggers a specific 500 error digest to confirm vulnerability without RCE.
|
| 238 |
+
* **Windows Mode:** Uses PowerShell payload (`powershell -c ...`) instead of Unix shell.
|
| 239 |
+
* **Generic WAF Bypass:** Pads the request with junk data to push payload past WAF inspection limits.
|
| 240 |
+
* **Vercel WAF Bypass:** Uses a specific multipart structure to bypass Vercel-specific defenses.
|
| 241 |
+
"""
|
| 242 |
+
|
| 243 |
with gr.Blocks(title="React2Shell Scanner") as demo:
|
| 244 |
gr.Markdown("# React2Shell Scanner (CVE-2025-55182)")
|
| 245 |
+
gr.Markdown("Web-based scanner for React Server Components / Next.js RCE.")
|
| 246 |
|
| 247 |
+
with gr.Accordion("📖 Help & Usage Guide", open=False):
|
| 248 |
+
gr.Markdown(guide_content)
|
| 249 |
+
|
| 250 |
with gr.Row():
|
| 251 |
url_input = gr.Textbox(label="Target URL", placeholder="https://example.com")
|
| 252 |
path_input = gr.Textbox(label="Custom Path (Optional)", placeholder="/_next", value="")
|
| 253 |
|
| 254 |
with gr.Row():
|
| 255 |
+
safe_check = gr.Checkbox(label="Safe Check", value=True, info="Side-channel check (Non-destructive).")
|
| 256 |
windows_mode = gr.Checkbox(label="Windows Mode", value=False, info="Use PowerShell payload.")
|
| 257 |
+
waf_bypass = gr.Checkbox(label="Generic WAF Bypass", value=False, info="Add junk data padding.")
|
| 258 |
+
vercel_bypass = gr.Checkbox(label="Vercel WAF Bypass", value=False, info="Specific structure for Vercel.")
|
| 259 |
|
| 260 |
scan_btn = gr.Button("Scan Target", variant="primary")
|
| 261 |
output_box = gr.Textbox(label="Scan Output", lines=10)
|
|
|
|
| 266 |
outputs=output_box
|
| 267 |
)
|
| 268 |
|
| 269 |
+
gr.Markdown("**Disclaimer:** This tool is for educational and authorized security testing purposes only. Do not scan targets you do not own.")
|
| 270 |
|
| 271 |
demo.launch()
|