Lobbydesires botnet
Recientemente, Oxydian recibió una alerta sobre el mal funcionamiento de varios sitios WordPress. Tras examinarlos, se descubrió que estaban infectados por un pequeño botnet desconocido y muy reciente. Este tipo de compromiso de un sitio web forma parte de los objetivos que se verifican en una auditoría intrusiva. A continuación se presenta el análisis:
EDIT 14/07/20: estos son los scripts que permiten detectar y limpiar este malware:
https://github.com/Guiomuh
/WP_Redirect_Botnet_Cleaner
Análisis general
Todo empezó con el descubrimiento del siguiente payload JavaScript sospechoso en un sitio WordPress:
Rápidamente se comprueba que el sitio https://lobbydesires[.]com es un servidor C&C (Command and Control) que aloja el código malicioso de este malware. Esto permite al atacante modificar a su antojo las funcionalidades del botnet.
Empecemos por el análisis general de este malware. En primer lugar, un simple WHOIS sobre el nombre de dominio utilizado revela que el sitio está alojado en los Países Bajos y que se registró el 29 de junio de 2020, es decir, hace 4 días. ¡Y en tan pocos días ya se han infectado numerosos sitios!
En efecto, puede utilizarse la siguiente búsqueda de Google para listar la parte de los sitios infectados que se han indexado desde su infección:
intext:lobbydesires[.]com/location.js
En este momento aparecen 260 sitios, pero la cifra real debe de ser muy superior, dado el tiempo que tardan los bots de Google en volver a indexar un sitio web.
Análisis técnico: location.js
Este es el código del fichero location.js, que se descarga del sitio lobbydesires.com y se ejecuta en cada visita a una página infectada.
Como recordatorio, aquí se trata de código JavaScript: el código se ejecuta, por tanto, en el navegador de la persona que visita el sitio y no en el propio sitio
Se observa que el código está ofuscado; hará falta algo de trabajo para hacerlo comprensible.
Tras una pequeña limpieza, se encuentran en este fichero 3 funciones JS:
check_adm()
make_theme()
reqListener()
reqListener()
La última función, reqListener() está vacía, lo que sugiere que el botnet no está terminado; este punto se retoma más adelante.
check_admin()
Esta es la función principal de este malware, la que se ejecuta tras la definición de las funciones. Se encarga de comprobar, mediante las cookies, si el usuario que visita la página infectada es el administrador del sitio WordPress. Si no lo es, el usuario es redirigido a la página de login. Si se trata del administrador, se llama entonces a la función make_theme() .
El principio de este comportamiento es bloquear la página hasta que el administrador la visite, algo bastante retorcido, en efecto.
make_theme()
Esta función empieza haciendo una petición GET a la siguiente dirección:
http://[victime.com]/wp-admin/theme-editor.php?file=header.php
Esta es la página de WordPress que permite al administrador modificar el tema actual, y en concreto aquí el fichero header.php del tema.
El malware obtiene entonces algunos datos de la página mediante expresiones regulares. Estos datos le serán necesarios para interactuar con la página más adelante.
i = /name=”newcontent”.*?[>]([\/\s\/\S]*?)<\/textarea/g.exec(n),
d = /
- i[1] contiene el contenido de header.php antes de la modificación
- d[1] contiene el nombre del tema utilizado
- p[2] contiene el valor del nonce que se utilizará en las siguientes peticiones
A continuación, la función comprueba si el tema ya está infectado buscando la presencia de la cadena “sdfsd23” (presente en el 2.º payload (PHP), que se muestra más abajo). Si el tema no está infectado todavía, se le añaden 2 payloads al principio. Uno en JavaScript, similar al anterior:
Y otro que contiene código PHP: (simplificado aquí para facilitar su comprensión)
Este código PHP se ejecuta, por tanto, en el servidor en cada carga de página. Pero ¿qué hace?
Análisis técnico: persistencia en el tema de WP
El payload PHP anterior se encarga de descargar y ejecutar el fichero https://lobbydesires[.]com/n.txt
Este fichero es un script PHP codificado en base64
Como recordatorio, aquí se trata de código PHP: el código se ejecuta, por tanto, en el servidor infectado
El núcleo de este fichero contiene varias funciones, pero, en resumen, busca ficheros concretos desde la raíz del servidor para infectarlos.
¡Esto implica que los demás sitios alojados en el mismo servidor también pueden resultar infectados!
Esta búsqueda puede dividirse en 4 partes:
- La búsqueda del fichero wp-config.php
- La búsqueda de ficheros cuyo nombre contiene “.ph” o “.htm”
- La búsqueda de ficheros cuyo nombre contiene “index.” y (“.ph” o “.htm”)
- La búsqueda de ficheros cuyo nombre contiene “.js”
Aunque el método de búsqueda no es óptimo, se aprecia claramente que el malware apunta a los ficheros JS, PHP y HTML. En cada caso se añade al fichero encontrado un payload JavaScript similar a los anteriores, salvo en el caso de wp-config.php
En efecto, una vez encontrado, este fichero se recorre en busca de las credenciales de la base de datos SQL de WordPress. Estas se utilizan después para añadir el payload JavaScript a todos los artículos de WordPress.
¿Un botnet en pañales?
Como ya se ha indicado, este botnet no parece terminado. Además de no disponer todavía de cargas útiles que permitan lanzar ataques, algunas funcionalidades están incompletas.
Por citar solo un ejemplo, puede mencionarse el fichero rebut.log :
Este fichero, creado durante la ejecución del código PHP malicioso, contiene la fecha de su última ejecución. Se utiliza al inicio de la ejecución para comprobar si la última ejecución se produjo hace más o menos de 6400 segundos, seguramente para evitar que el malware se vuelva a ejecutar en cada carga de página, lo que puede ralentizar gravemente el sitio. Sin embargo, en ambos casos se ejecuta lo mismo, lo cual es incoherente.
El nombre de este fichero, rebut.log (en francés, «desecho»), parece un indicio de que el atacante es francófono.
Por otra parte, puede observarse que los payloads JavaScript tienen un parámetro no utilizado que indica desde dónde se han llamado. En resumen:
location.js?i=1 -> from index.php
location.js?s=1 -> from .php .htm or JS
location.js?qs=1 -> from SQL DB article
location.js?v=1 -> from Infected Theme (header.php)
Además, se observa una importante redundancia de código, lo que puede ser un indicio de la inexperiencia de su creador.
Por último, cabe señalar la ausencia de redundancia del servidor de control. Normalmente, en este tipo de malware se utilizan varios servidores infectados en redundancia para almacenar los ficheros de código, de modo que el atacante pueda mantener el control de su botnet aunque el servidor sea denunciado.
En este caso solo se utiliza un servidor, y ya ha sido denunciado 😀, por lo que es cuestión de tiempo que este botnet quede inutilizable.
EDIT (05/07/2020): a día de hoy, el servidor ya no está disponible
Conclusión
Aunque actualmente es inofensivo, este virus es muy persistente y se actualiza en cada visita a una página infectada. Esto puede cambiar en breve y el botnet podría revelar pronto su verdadera función. Por tanto, es esencial limpiar cualquier sitio que haya resultado infectado. Con este fin, Oxydian ha publicado un script que permite realizar una limpieza completa de este malware. En efecto, este malware es muy persistente y olvidar una sola página bastaría para provocar una reinfección completa de los sitios alojados en el servidor.
Mientras tanto, una corrección rápida consistiría en bloquear el dominio lobbydesires[.]com en el cortafuegos o, en su defecto, añadirlo al fichero hosts. Sin embargo, esta corrección no es completa: solo evita la descarga y, por tanto, la actualización del payload PHP insertado en el tema.
Cabe preguntarse también cómo se produjo la primera infección. Una hipótesis sería la presencia de una vulnerabilidad XSS almacenada (Stored XSS) en un WordPress o un plugin sin actualizar. Este tipo de vulnerabilidades son habituales y permitirían inyectar el payload JS inicial, infectando así la primera página, que a su vez infectará todo el sitio si la visita el administrador. La misma familia de vulnerabilidades se busca en el análisis de mitm6, una toma de control de la red interna a través de IPv6.
Recomendaciones: para protegerse de este tipo de ataque, es imprescindible mantener actualizados el sitio WordPress y sus plugins.