14 Jun 2024

WordPress Isn’t Warning Users of Plugin With Unfixed Vulnerability That Is Being Exploited

This week, our Plugin Vulnerabilities Firewall plugin has blocked several attempts across our websites to exploit a vulnerability in a WordPress plugin. In investigating the attacks, we found that the vulnerability exists in the most recent version of the BuddyPress Cover plugin. That plugin was closed on the WordPress Plugin Directory on May 28:

No explanation is given there for the closure.

In WordPress itself, there is no notification that the plugin has been closed, much less a warning that it contains a vulnerability you would expect to be exploited or warning that it is being exploited:

That isn’t just a problem with this plugin, there is a general lack of warning about known vulnerable and exploited plugins. As we noted with another situation this week, where there is no warning for the many websites using a vulnerable version of a plugin, despite a fix being available.

Providing warnings about these situations could help a lot to reduce the number of WordPress websites being hacked.

Arbitrary File Upload Vulnerability

Here was what was logged when the attacks were stopped:

That provides a roadmap to what was attempting to be exploited. The request is trying to access code that would run when an AJAX request is made to WordPress with the “action” set to “bp_caver_avatar_handle_upload.” We found only one plugin that would apply to, BuddyPress Cover. The plugin makes the function bp_caver_avatar_handle_upload() in the file /bp-cover.php AJAX accessible to those logged in to WordPress as well as those not logged in:

373
374
add_action('wp_ajax_bp_caver_avatar_handle_upload', 'bp_caver_avatar_handle_upload');
add_action( 'wp_ajax_nopriv_bp_caver_avatar_handle_upload', 'bp_caver_avatar_handle_upload' );

The exploit attempts sent base 64 encoded PHP code with the POST input “encodedimg.” The base 64 decodes that POST input and saves it to a file with the name set based on the POST input “imgname”:

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
function bp_caver_avatar_handle_upload() {
  global $bp;
   if( $_POST['encodedimg'] ) {
      $user_id = !empty( $_POST['user_id'] ) ? $_POST['user_id'] : bp_displayed_user_id() ; 
      $imgresponse = array();
      $uploaddir = bp_core_avatar_upload_path() . '/avatars'; 
      if( ! file_exists( $uploaddir ) ) { 
            mkdir( $uploaddir ); 
      }     
      $img = $_POST['encodedimg'];
      $img = str_replace('data:'.$_POST['imgtype'].';base64,', '', $img);
      $img = str_replace(' ', '+', $img);
      $data = base64_decode($img);  
      $filepath = $uploaddir . '/' . $user_id;
      if( ! file_exists( $filepath ) ) { 
            mkdir( $filepath ); 
      }
      $imgname = wp_unique_filename( $uploaddir, $_POST['imgname'] );         
      $fileurl = $filepath . '/' . $imgname;
      $siteurl = trailingslashit( get_blog_option( 1, 'siteurl' ) );
      $url = str_replace(ABSPATH,$siteurl,$fileurl);   
      $success = file_put_contents($fileurl, $data);

If the attack was successful, then malicious code would be saved to a file on the website. We are going to look at the code that would be in the file more closely in a follow up post, but the short version is that the code would create a new admin account on the website and place another file on the website.

Free Warning

As this vulnerability looks to be targeted by hackers, we are adding accurate data on it to the free data that comes with our Plugin Vulnerabilities plugin.

Leave a Reply

Your email address will not be published.