10,000 WordPress Sites Affected by High Severity Vulnerabilities in BookingPress WordPress Plugin

On July 2nd, 2024, during the 0-day Threat Hunt Promo of our Bug Bounty Program, we received a submission for an Arbitrary File Read to Arbitrary File Creation vulnerability in BookingPress, a WordPress plugin with over 10,000 active installations. This vulnerability makes it possible for authenticated threat actors to create arbitrary files populated with content of files from local or remote sources, allowing the execution of any PHP code in those files or the exposure of sensitive information. We later received a submission for an Arbitrary Options Update and Arbitrary File Upload vulnerability in the BookingPress plugin from another researcher. This vulnerability enables threat actors to update arbitrary options which can easily be leveraged for privilege escalation, and enables threat actors to upload arbitrary files which can be used for remote code execution.

Props to Arkadiusz Hydzik and shaman0x01, who discovered and responsibly reported these vulnerabilities through the Wordfence Bug Bounty Program. These researchers respectively earned bounties of $537.00 and $488.00 for their discoveries during the 0-day Threat Hunt Promo. Our mission is to Secure the Web, which is why we are investing in quality vulnerability research and collaborating with researchers of this caliber through our Bug Bounty Program. We are committed to making the WordPress ecosystem more secure, which ultimately makes the entire web more secure.

Wordfence Premium, Wordfence Care, and Wordfence Response users received a firewall rule to protect against any exploits targeting the Arbitrary File Read to Arbitrary File Creation vulnerability on July 8, 2024, and against the Arbitrary Options Update and Arbitrary File Upload vulnerability on July 12, 2024. Sites using the free version of Wordfence will receive the same protection 30 days later on August 7, 2024, and on August 11, 2024.

We provided full disclosure details to the BookingPress Team on July 4, 2024, and on July 10, 2024. The developer released a patch on July 12, 2024. We would like to commend the BookingPress Team for their prompt response and timely patch.

We urge users to update their sites with the latest patched version of BookingPress, which is version 1.1.6, as soon as possible.

Vulnerability Summary from Wordfence Intelligence

Description: BookingPress Appointment Booking <= 1.1.5 - Authenticated (Subscriber+) Arbitrary File Read to Arbitrary File Creation
Affected Plugin: Appointment Booking Calendar Plugin and Online Scheduling Plugin – BookingPress
Plugin Slug: bookingpress-appointment-booking
Affected Versions: <= 1.1.5
CVE ID: CVE-2024-6467
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Researcher/s: Arkadiusz Hydzik
Fully Patched Version: 1.1.6
Bounty Award: $537.00

The BookingPress – Appointment Booking Calendar Plugin and Online Scheduling Plugin plugin for WordPress is vulnerable to Arbitrary File Read to Arbitrary File Creation in all versions up to, and including, 1.1.5 via the ‘bookingpress_save_lite_wizard_settings_func’ function. This makes it possible for authenticated attackers, with Subscriber-level access and above, to create arbitrary files that contain the content of files (either on the local server or from a remote location), allowing the execution of any PHP code in those files or the exposure of sensitive information.

Description: BookingPress – Appointment Booking Calendar Plugin and Online Scheduling Plugin <= 1.1.5 - Missing Authorization to Authenticated (Subscriber+) Arbitrary Options Update and Arbitrary File Upload
Affected Plugin: Appointment Booking Calendar Plugin and Online Scheduling Plugin – BookingPress
Plugin Slug: bookingpress-appointment-booking
Affected Versions: <= 1.1.5
CVE ID: CVE-2024-6660
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Researcher/s: shaman0x01
Fully Patched Version: 1.1.6
Bounty Award: $488.00

The BookingPress – Appointment Booking Calendar Plugin and Online Scheduling Plugin plugin for WordPress is vulnerable to unauthorized modification of data that can lead to privilege escalation due to a missing capability check on the bookingpress_import_data_continue_process_func function in all versions up to, and including, 1.1.5. This makes it possible for authenticated attackers, with Subscriber-level access and above, to update arbitrary options on the WordPress site and upload arbitrary files. This can be leveraged to update the default role for registration to administrator and enable user registration for attackers to gain administrative user access to a vulnerable site.

Technical Analysis #1: Arbitrary File Read to Arbitrary File Creation

BookingPress is an appointment booking WordPress plugin, which can be used to set up a complete booking system on WordPress with many different settings.

Examining the code reveals that the plugin uses the bookingpress_save_lite_wizard_settings_func() function in the BookingPress class to save the wizard settings.

function bookingpress_save_lite_wizard_settings_func(){
    global $wpdb, $BookingPress, $tbl_bookingpress_default_workhours, $tbl_bookingpress_services, $tbl_bookingpress_customize_settings;
    
    $response              = array();
    $wpnonce               = isset($_REQUEST['_wpnonce']) ? sanitize_text_field($_REQUEST['_wpnonce']) : '';
    $bpa_verify_nonce_flag = wp_verify_nonce($wpnonce, 'bpa_wp_nonce');
    if (! $bpa_verify_nonce_flag ) {
        $response['variant']        = 'error';
        $response['title']          = esc_html__('Error', 'bookingpress-appointment-booking');
        $response['msg']            = esc_html__('Sorry, Your request can not be processed due to security reason.', 'bookingpress-appointment-booking');
        echo wp_json_encode($response);
        exit;
    }

Unfortunately, it was found that the nonce is publicly accessible on the frontend of the site and there was no capability check in this function. This makes it possible for authenticated attackers with subscriber-level permission to invoke the AJAX action.

In addition to saving the settings, the function also contains file upload code to save the logo image setting.

$bookingpress_logo = $bookingpress_company_fields_data['logo_img'];
$bookingpress_logo_url = $bookingpress_company_fields_data['logo'];

if( !empty($bookingpress_company_fields_data['logo_img']) && !empty($bookingpress_company_fields_data['logo_img']) ){
    $bookingpress_upload_image_name = $bookingpress_logo;

    $upload_dir                 = BOOKINGPRESS_UPLOAD_DIR . '/';
    $bookingpress_new_file_name = current_time('timestamp') . '_' . $bookingpress_upload_image_name;
    $upload_path                = $upload_dir . $bookingpress_new_file_name;
    $bookingpress_upload_res    = $BookingPress->bookingpress_file_upload_function($bookingpress_logo_url, $upload_path);

    $bookingpress_file_name_arr = explode('/', $bookingpress_logo_url);
    $bookingpress_file_name     = $bookingpress_file_name_arr[ count($bookingpress_file_name_arr) - 1 ];
    if( file_exists( BOOKINGPRESS_TMP_IMAGES_DIR . '/' . $bookingpress_file_name ) ){
        @unlink(BOOKINGPRESS_TMP_IMAGES_DIR . '/' . $bookingpress_file_name);
    }

    $bookingpress_logo_url = BOOKINGPRESS_UPLOAD_URL . '/' . $bookingpress_new_file_name;
}

Unfortunately, insecure implementation of the plugin’s logo image file upload functionality allows for arbitrary file read and creation.

The bookingpress_file_upload_function() function in the BookingPress class is used for uploading the logo file.

function bookingpress_file_upload_function( $source, $destination )
{

$allow_file_upload = 1;
$allow_file_upload = apply_filters('bookingpress_allow_file_uploads', $allow_file_upload);
    if (empty($source) || empty($destination) || empty($allow_file_upload)) {
        return false;
    }

    if (! function_exists('WP_Filesystem') ) {
        include_once ABSPATH . 'wp-admin/includes/file.php';
    }

    WP_Filesystem();
    global $wp_filesystem;

    $file_content = $wp_filesystem->get_contents($source);

    $result = $wp_filesystem->put_contents($destination, $file_content, 0777);

    return $result;
}

Examining the code reveals that there is no restriction on the file extension. This means that a file can be copied from either a local or remote source to a destination with an arbitrary extension through the use of the put_contents() function. This makes it possible for attackers to upload arbitrary malicious PHP code from a remote source and then access the file to trigger remote code execution on the server. In addition, it also allows the attacker to copy a file from a local source to a readable extension, thereby leading to the exposure of sensitive information such as wp-config.php data.

Technical Analysis #2: Arbitrary Options Update and Arbitrary File Upload

The second vulnerability allowed for arbitrary options updates and arbitrary file uploads. Examining the code reveals that the plugin uses the bookingpress_import_data_process_func() function in the bookingpress_import_export class to save the import plugin’s data, and then uses the bookingpress_import_data_continue_process_func() to process the import data.

Unfortunately, it was again found that the nonce is publicly accessible on the frontend of the site and there was no capability check in this function. This makes it possible for authenticated attackers with subscriber-level permission to invoke the AJAX action.

The import function contains an option import, which is typically used to update options and settings related to a plugin.

$import_record_data = $bookingpress_import_data[$detail_import_detail_type];
$total_imported = 0;
$new_limit = $limit + $detail_import_last_record;
for($i=$detail_import_last_record; $i<$new_limit; $i++){
    if(isset($import_record_data[$i])){
        $single_import_record = array();                                                
        $key = (isset($import_record_data[$i]['key']))?$import_record_data[$i]['key']:'';
        $value = (isset($import_record_data[$i]['value']))?$import_record_data[$i]['value']:'';
        if($key == 'bookingpress_cart_order_id'){
            update_option($key,$value);
        }else{
            $import_data_v = $value;
            $import_data_v = $this->bookingpress_import_value_modified($import_data_v,$detail_import_detail_type,$key);
            update_option($key,$import_data_v);
        }                                                                                                   
        $total_imported++;                                          
    }
}

Unfortunately, examination of the code revealed that there are no restrictions on the option names that can be updated. This means that modifiable settings are not limited to the plugin’s settings, which makes it possible to update arbitrary option values by sending a direct request to the server with the option names and values that the attacker would like to change. WordPress site options control a variety of settings such as site urls, general settings, registration, and registration roles to name a few.

As with any Arbitrary Options Update vulnerability, this can be used to accomplish a complete site compromise by setting the default registration role to administrator and enabling user registration (if not already enabled). Once an attacker has edited the site options they can create an administrative account on the WordPress site and then, once registered and logged in, they can then manipulate anything on the targeted site, just like a normal administrator would. This includes the ability to upload plugin and theme files, which can be malicious zip files containing backdoors, and modifying posts and pages which can be leveraged to redirect site users to other malicious sites.

This function wasn’t just vulnerable to arbitrary options updates, it was also vulnerable to arbitrary file uploads. The import function contains a customer import with avatar image upload as shown below.

$file_name = basename($file_url);
$destination_path = $destination_dir . $file_name;
$result = $this->bookingpress_upload_file_func($file_url,$destination_dir);

The bookingpress_upload_file_func() function in the bookingpress_import_export class is used for uploading the file.

function bookingpress_upload_file_func($file_url,$destination_dir=""){
    $result = array('error'=>1,'msg'=>esc_html__('Failed to download the file.','bookingpress-appointment-booking'));
    if(!empty($file_url)){                
        if(!file_exists($destination_dir)) {
            mkdir($destination_dir, 0755, true);
        }
        $file_name = basename($file_url);    
        $destination_path = $destination_dir . $file_name;
        $file_content = file_get_contents($file_url);
        if ($file_content !== false) {
            $save_result = file_put_contents($destination_path, $file_content);
            if ($save_result !== false) {
                chmod($destination_path, 0755);                                                                        
                $result = array('error'=>0,'msg'=>esc_html__('success.','bookingpress-appointment-booking'));
            } else { 
                $result = array('error'=>1,'msg'=>esc_html__('Failed to save the file.','bookingpress-appointment-booking'));                      
            }                    
        }
    }
    return $result;
}

Similar to the previous vulnerability, the function does not include any file type or extension checks in the vulnerable version and utilizes file_put_contents() for the upload. This means that not only image files can be uploaded, but it is also possible to upload files with a .php extension. The file is uploaded to the WordPress uploads folder, which is publicly accessible. This makes it possible for attackers, with authenticated access such as subscribers, to upload arbitrary malicious PHP code and then access the file to trigger remote code execution on the server.

As with all arbitrary file upload vulnerabilities, this can lead to complete site compromise through the use of webshells and other techniques.

Disclosure Timeline

July 2, 2024 – We received the submission for the Arbitrary File Read to Arbitrary File Creation vulnerability in BookingPress via the Wordfence Bug Bounty Program.
July 3, 2024 – We received the submission for the Arbitrary Options Update and Arbitrary File Upload vulnerability in BookingPress via the Wordfence Bug Bounty Program.
July 3, 2024 – We validated the report and confirmed the proof-of-concept exploit for the first vulnerability
July 4, 2024 – We sent over the full disclosure details for the first vulnerability.
July 8, 2024Wordfence Premium, Care, and Response users received a firewall rule to provide protection against any exploits that may target the first Arbitrary File Read to Arbitrary File Creation vulnerability.
July 10, 2024 – We validated the report and confirmed the proof-of-concept exploit for the second vulnerability. We sent over the full disclosure details for the second vulnerability.
July 12, 2024Wordfence Premium, Care, and Response users received a firewall rule to provide protection against any exploits that may target the second Arbitrary Options Update and Arbitrary File Upload vulnerability.
July 12, 2024 – The fully patched version of the plugin, 1.1.6, is released.
August 7, 2024 – Wordfence Free users will receive the same protection against the Arbitrary File Read to Arbitrary File Creation vulnerability.
August 11, 2024 – Wordfence Free users will receive the same protection against the Arbitrary Options Update and Arbitrary File Upload vulnerability.

Conclusion

In this blog post, we detailed an Arbitrary File Read to Arbitrary File Creation vulnerability, and an Arbitrary Options Update and Arbitrary File Upload vulnerability within the BookingPress plugin affecting versions 1.1.5 and earlier. The Arbitrary File Read to Arbitrary File Creation vulnerability allows authenticated threat actors to create arbitrary files that contain the content of files from local or remote sources, resulting in a full site compromise. The Arbitrary Options Update and Arbitrary File Upload vulnerability allows authenticated threat actors to edit arbitrary site options which can be used to create administrator accounts, and allows threat actors to upload arbitrary files which can be used to execute malicious code on the server. The vulnerabilities have been fully addressed in version 1.1.6 of the plugin.

We encourage WordPress users to verify that their sites are updated to the latest patched version of BookingPress.

Wordfence users running Wordfence Premium, Wordfence Care, and Wordfence Response have been protected against the Arbitrary File Read to Arbitrary File Creation vulnerability as of July 8, 2024, and protected against the Arbitrary Options Update and Arbitrary File Upload vulnerability as of July 12, 2024. Users using the free version of Wordfence will receive the same protection 30 days later on August 7, 2024, and on August 11, 2024.

If you know someone who uses this plugin on their site, we recommend sharing this advisory with them to ensure their site remains secure, as this vulnerability poses a significant risk.

Did you enjoy this post? Share it!

Comments

No Comments