Incidente con Malware de posicionamiento en buscadores, SEO

Recientemente detectamos en un servidor una extraña conexión hacia un servidor que hizo saltar la alarma por un posible compromiso del mismo. La petición que se detectó desde dicho servidor fue únicamente la que se muestra a continuación:

GET /system/mngr.php?id=a5f99b82b662d6e2b98b30e3077606ba&md5=9e5d6df936986f0b4d5fd4794807824f HTTP/1.0
Host: manka11.com

Como única respuesta se recibió la palabra UNCHANGED.

Tras analizar las peticiones que recibe el servidor, no se aprecia ninguna sospechosa que pudiera indicar alguna webshell desde la que lanzar esa petición, ni ninguna orden dirigida a un recurso sospechoso o pasada como parámetro que llamase la atención, lo que nos hizo analizar el registro del servidor para ver qué actividad hubo.

Antes de pasar a analizar el log, buscamos los últimos ficheros modificados en el directorio del servidor y, por tratarse de un posible servidor web comprometido, especialmente aquellos ficheros con funciones que utiliza habitualmente el malware para ofuscarse (base64_decode, preg_replace, eval, error_reporting(0), etc.). En este caso ya empezamos a ver indicios que nos llevaban en la dirección correcta: unas carpetas que parecen ser módulos de Joomla! creados en fechas diferentes que contienen algunas de las funciones buscadas:

Módulo “mod_te”, creado el 28/08/13 20:53
Módulo “mod_tools”, creado el 08/07/13 16:16
Módulo “mod_404”, creado el 06/06/13 17:37

Como ya teníamos un indicio sobre el que basarnos, buscamos actividad dirigida hacia estos módulos para ver cuándo fueron subidos, por quién y cómo, así como comprobar si habían sido utilizados. Comenzamos a buscar peticiones a esos módulos así como otras hechas desde las direcciones IP, por si hubiera otros recursos que no hubiésemos detectado y poder determinar así la actividad del atacante. Como resultado de varios filtros de búsqueda obtuvimos las siguientes líneas:

nbelda@macbuc:~$ grep -e “37.1.195.XX\|178.158.214.XXX” access.log
178.158.214.XXX – – [08/Jul/2013:16:16:51 +0200] “GET /administrator/index.php HTTP/1.0” 200 3961
178.158.214.XXX – – [08/Jul/2013:16:16:53 +0200] “POST /administrator/index.php HTTP/1.0” 303 –
178.158.214.XXX – – [08/Jul/2013:16:16:53 +0200] “GET /administrator/index.php HTTP/1.0” 200 41515
178.158.214.XXX – – [08/Jul/2013:16:16:55 +0200] “GET /administrator/index.php?option=com_installer HTTP/1.0” 200 25276
178.158.214.XXX – – [08/Jul/2013:16:16:56 +0200] “POST /administrator/index.php HTTP/1.0” 303 486
178.158.214.XXX – – [08/Jul/2013:16:16:57 +0200] “POST /administrator/index.php?option=com_modules HTTP/1.0” 200 59449
178.158.214.XXX – – [28/Aug/2013:20:53:30 +0200] “GET /administrator/index.php HTTP/1.0” 200 3961
178.158.214.XXX – – [28/Aug/2013:20:53:32 +0200] “POST /administrator/index.php HTTP/1.0” 303 –
178.158.214.XXX – – [28/Aug/2013:20:53:32 +0200] “GET /administrator/index.php HTTP/1.0” 200 42057
178.158.214.XXX – – [28/Aug/2013:20:53:34 +0200] “GET /administrator/index.php?option=com_installer HTTP/1.0” 200 25276
178.158.214.XXX – – [28/Aug/2013:20:53:35 +0200] “POST /administrator/index.php HTTP/1.0” 303 486
178.158.214.XXX – – [28/Aug/2013:20:53:36 +0200] “POST /administrator/index.php?option=com_modules HTTP/1.0” 200 59460
37.1.195.XX – – [28/Aug/2013:22:21:27 +0200] “POST /modules/mod_te/mod_te.php HTTP/1.1” 200 10912
37.1.195.XX – – [28/Aug/2013:22:21:30 +0200] “POST /modules/mod_te/mod_te.php HTTP/1.1” 200 23793
37.1.195.XX – – [28/Aug/2013:22:21:33 +0200] “POST /modules/mod_te/mod_te.php HTTP/1.1” 200 8552
37.1.195.XX – – [28/Aug/2013:22:21:36 +0200] “POST /modules/mod_te/mod_te.php HTTP/1.1” 200 266497
37.1.195.XX – – [28/Aug/2013:22:21:41 +0200] “POST /modules/mod_te/mod_te.php HTTP/1.1” 200 9907
37.1.195.XX – – [28/Aug/2013:22:21:44 +0200] “POST /modules/mod_te/mod_te.php HTTP/1.1” 200 9978
37.1.195.XX – – [28/Aug/2013:22:21:54 +0200] “GET / HTTP/1.1” 200 1191879

Del resultado anterior pudimos sacar tres conclusiones. La primera, que el atacante accedió tres veces a la pantalla de administrador e instaló un módulo cada vez. La segunda, que al parecer el atacante sabía la contraseña ya que los módulos se instalan a través del panel de control y no a través de un RFI u otra vulnerabilidad que permita subir archivos sin autenticarse. La tercera, que la fecha de acceso e instalación coincide con la de los ficheros creados, aunque sólo se detecta acceso al último (mod_te), lo que explica que no saltaran las alarmas hasta que accedió al módulo subido.

Encontramos tres tipos de archivos subidos: asas.php, una carpeta por cada módulo subido y un archivo en una carpeta temporal.

El archivo asas.php se trata de código PHP sin ofuscar, del que vamos a ir desgranando su funcionamiento:

Lo primero que se ve es una lista de más de 8.000 direcciones IP y un listado de palabras relacionadas con buscadores. El código comprueba si las peticiones vienen de alguna de esas IPs o con alguno de esos “User Agent”, entonces marcará la variable “is_bot” como true y, en ese caso, se ejecutará el resto del código.

En el código, para simplificar, podemos apreciar 4 funciones principales.

  • fetch_remote_file: realiza una petición a dos servidores, uno ubicado en Ucrania y el otro no resuelve, pasándole tres parámetros: id, md5 y charset. El primero es un identificador único de la aplicación, mientras que el otro es el hash del fichero que se ha descargado previamente (links.db). Sirve para comprobar si tiene la última versión; en caso afirmativo, el servidor devolverá UNCHANGED (como veíamos en la petición capturada).
  • _read: se encarga de leer el fichero links.db.
  • _write: es la función que actualiza el fichero descargado en disco.
  • load_data: se trata de la función principal de la aplicación. Comprueba si el listado de enlaces está acualizado y los carga en memoria. Mostramos cómo construye la petición que envía al servidor.

Es curioso que los comentarios estén en inglés pero los mensajes de salida esté en ruso. En la siguiente captura vemos cómo se construye la petición HTTP.

Por último, otra de las funciones a destacar es “return_links” que inserta los enlaces del listado en la página html.

Ya hemos desvelado que el contenido del fichero links.db es un listado de enlaces sobre venta de productos seguramente ilegales (fundamentalmente programas con licencia), como se muestra a continuación:

Después de analizar detenidamente el código y el contenido del fichero descargado, junto con el hecho de que sólo se ejecutará cuando el visitante sea un crawler de los principales buscadores, nos da a entender que se trata de una herramienta de posicionamiento en buscadores sobre los enlaces mostrados con enlaces maliciosos o de productos ilegales.

Otro de los ficheros subidos parecía más complejo de analizar, sobre todo cuando lo abrimos para ver su contenido.

En este tipo de situaciones, lo primero que hago es acudir a servicios online de páginas para desofucar código, como la de UnPHP, que me devuelve fácil y rápidamente el código legible.

Este código es muy conocido por los que nos dedicamos a la gestión de incidentes, ya que se trata de la webshell WSO; concretamente, la versión 2.4 a tenor de lo que nos indica el código.

@define('WSO_VERSION', '2.4');

Se trata de una potente webshell con infinidad de funcionalidades. No obstante, basándonos en la poca actividad que se registró en el servidor y el bajo número de archivos modificados, podemos concluir que éste fue el módulo que se subió (tres veces aunque sólo se accedió la última vez) y la única acción que se realizó fue subir el código anterior (asas.php). Finalmente, como medidas de erradicación debido al propio compromiso y al hecho de disponer de la clave de acceso, se cambió la contraseña del administrador y se revisaron los usuarios existentes. Por precaución, también se actualizó la aplicación web.

Comments

  1. Interesante información. ¿Qué codificación o método habían empleado para generar un código tan monstruoso para algo tan simple? (te lo pregunto desde la completa ignorancia sobre php)

    Saludos