BackWPup <= 5.6.6 - Authenticated (Administrator+) Local File Inclusion via 'block_name' Parameter
Description
The BackWPup plugin for WordPress is vulnerable to Local File Inclusion via the `block_name` parameter of the `/wp-json/backwpup/v1/getblock` REST endpoint in all versions up to, and including, 5.6.6 due to a non-recursive `str_replace()` sanitization of path traversal sequences. This makes it possible for authenticated attackers, with Administrator-level access and above, to include arbitrary PHP files on the server via crafted traversal sequences (e.g., `....//`), which can be leveraged to read sensitive files such as `wp-config.php` or achieve remote code execution in certain configurations. Administrators have the ability to grant individual users permission to handle backups, which may then allow lower-level users to exploit this vulnerability.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:HTechnical Details
What Changed in the Fix
Changes introduced in v5.6.7
Source Code
WordPress.org SVNThis research plan outlines the steps to exploit a Local File Inclusion (LFI) vulnerability in the BackWPup plugin for WordPress. ### 1. Vulnerability Summary The BackWPup plugin (<= 5.6.6) is vulnerable to Local File Inclusion via the `block_name` parameter in its REST API endpoint `/wp-json/backw…
Show full research plan
This research plan outlines the steps to exploit a Local File Inclusion (LFI) vulnerability in the BackWPup plugin for WordPress.
1. Vulnerability Summary
The BackWPup plugin (<= 5.6.6) is vulnerable to Local File Inclusion via the block_name parameter in its REST API endpoint /wp-json/backwpup/v1/getblock. The vulnerability exists because the plugin attempts to sanitize the block_name using a non-recursive str_replace() on the ../ sequence. By using a crafted sequence like ....//, an attacker can bypass the filter (the filter reduces ....// to ../). Since the endpoint includes the resulting path as a PHP file, an authenticated administrator (or user with backup permissions) can execute arbitrary PHP files or read files using PHP wrappers.
2. Attack Vector Analysis
- Endpoint:
/wp-json/backwpup/v1/getblock - Method:
POST - Vulnerable Parameter:
block_name - Required Authentication: Administrator (or users granted specific backup permissions).
- Nonce Requirement: Required (
X-WP-Nonceheader). The nonce is tied to thewp_restaction for the REST API. - Preconditions: The plugin must be active. The attacker needs valid Administrator credentials.
3. Code Flow
- Entry Point: The REST route
backwpup/v1/getblockis registered (likely insrc/Infrastructure/Rest/Route/GetBlock.php, inferred from plugin structure). - Handler: The callback function for this route retrieves the
block_nameandblock_typeparameters from the request. - Sanitization: The code performs a check like
$block_name = str_replace( '../', '', $block_name );. - File Construction: The plugin constructs a file path:
$file = BACKWPUP_PLUGIN_DIR . '/src/View/' . $block_type . '/' . $block_name . '.php';(pathing inferred frombackwpup-admin.jsusage). - Sink: The plugin uses
includeorrequireon the constructed path.
4. Nonce Acquisition Strategy
The REST API endpoint requires a standard WordPress REST nonce. This is exposed to the admin dashboard via the backwpupApi object.
- Access Dashboard: Navigate to the BackWPup "Jobs" or "Settings" page in the WordPress admin area.
- Locate Variable: The plugin localizes data into the
backwpupApiJavaScript object. - Extraction:
- Use
browser_navigatetohttp://localhost:8080/wp-admin/admin.php?page=backwpupjobs. - Use
browser_evalto extract the nonce:window.backwpupApi?.nonce
- Use
- Endpoint Discovery: Also extract the base REST URL if needed:
window.backwpupApi?.getblock.
5. Exploitation Strategy
We will attempt to include wp-config.php using a PHP filter wrapper to read its content in Base64 format, bypassing the limitation that include usually executes PHP rather than displaying source.
Step-by-Step Plan:
- Login: Authenticate as an administrator.
- Get Nonce: Extract the
backwpupApi.nonceusing the strategy above. - Craft Payload:
- The target file is
wp-config.php, typically located 3 levels up from the plugin's view directory (wp-content/plugins/backwpup/src/View/...). - Using
....//to bypassstr_replace('../', '', $input). - Payload:
php://filter/convert.base64-encode/resource=....//....//....//....//wp-config(The.phpextension is likely appended by the plugin).
- The target file is
- Execute Request:
POST /wp-json/backwpup/v1/getblock Header: X-WP-Nonce: [EXTRACTED_NONCE] Header: Content-Type: application/x-www-form-urlencoded block_name=php://filter/convert.base64-encode/resource=....//....//....//....//wp-config&block_type=component - Decode Output: The response body will contain the Base64 encoded content of
wp-config.php.
6. Test Data Setup
- Plugin: Install and activate BackWPup version 5.6.6.
- User: Create an admin user (e.g.,
admin/password). - Target File: Ensure
wp-config.phpexists in the standard location.
7. Expected Results
- The REST API should return a
200 OKresponse. - The body should contain a Base64 string.
- When decoded, the string should contain the PHP code of
wp-config.php, includingDB_NAME,DB_USER, andDB_PASSWORD.
8. Verification Steps
- HTTP Check: Verify the
http_requestresponse status and content. - Base64 Decoding: Decode the result and verify the presence of the
<?phptag and WordPress database constants. - Comparison: Use
wp-clito check the actualwp-config.phpcontent for verification:cat /var/www/html/wp-config.php
9. Alternative Approaches
- Direct Traversal: If the PHP filter wrapper is blocked or fails, try direct traversal to a non-PHP file (if the plugin doesn't strictly append
.php):....//....//....//....//....//etc/passwd. - RCE via Upload: If the attacker can upload a file (e.g., via the "Backups" feature or media library), they can include that file using the LFI to gain Remote Code Execution.
- Log Poisoning: If the server logs (like
access.log) are reachable, poison the logs with PHP code and include the log file. - Block Type Manipulation: Try different
block_typevalues if the directory structure differs (e.g.,component,children,alerts). Based onbackwpup-admin.js,componentandchildrenare validblock_typevalues.
Summary
The BackWPup plugin for WordPress is vulnerable to Local File Inclusion via the 'block_name' parameter in the '/wp-json/backwpup/v1/getblock' REST endpoint. This vulnerability stems from a non-recursive str_replace() filter that fails to properly sanitize path traversal sequences, allowing authenticated administrators (or users with backup permissions) to include arbitrary PHP files. Attackers can bypass the filter using crafted sequences like '....//' to read sensitive files such as 'wp-config.php' or achieve remote code execution.
Vulnerable Code
// src/Infrastructure/Rest/Route/GetBlock.php public function handle( \WP_REST_Request $request ) { $block_name = $request->get_param( 'block_name' ); $block_type = $request->get_param( 'block_type' ); // Vulnerable: Non-recursive str_replace allows bypasses like ....// // Line number inferred $block_name = str_replace( '../', '', $block_name ); $file = BACKWPUP_PLUGIN_DIR . '/src/View/' . $block_type . '/' . $block_name . '.php'; if ( file_exists( $file ) ) { include $file; } }
Security Fix
@@ -15,1 +15,3 @@ - $block_name = str_replace( '../', '', $block_name ); + while ( strpos( $block_name, '../' ) !== false ) { + $block_name = str_replace( '../', '', $block_name ); + }
Exploit Outline
To exploit this vulnerability, an attacker with Administrator-level access (or a user granted backup management permissions) must first obtain a valid REST API nonce. This nonce is typically exposed in the admin dashboard within the 'backwpupApi' JavaScript object. The attacker then sends a POST request to the '/wp-json/backwpup/v1/getblock' endpoint with the 'block_name' parameter set to a crafted path traversal payload. By using a sequence like '....//', the attacker bypasses the plugin's non-recursive 'str_replace' filter, which reduces the sequence to '../'. This allows the attacker to traverse directories and include arbitrary PHP files. For example, using a PHP filter wrapper like 'php://filter/convert.base64-encode/resource=....//....//....//....//wp-config' allows the attacker to read the contents of 'wp-config.php' in Base64 format.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.