El antiguo reto de la honeynet (II)

Tras la entrada introductoria y preparatoria del otro día, hoy vamos a empezar con el reto. Lo primero que suelo hacer una vez obtenido los datos iniciales (vistos en la anterior entrada) es crearme una línea de tiempo a nivel de sistemas de ficheros y luego le sumo los datos obtenidos con la lógica que contiene el sistema de ficheros… Seguramente se estarán preguntando que es eso de la lógica que contiene el sistema de ficheros. Es lo que normalmente se denomina “artifacts“. Por ejemplo un fichero ejecutable cuyo dueño ya no existe en el sistema pero el fichero sigue existiendo, un usuario creado con permisos de administración, shellbags, históricos, logs, etc.

Comencemos obteniendo la línea de tiempos del sistema de ficheros. Para ello nos crearemos un directorio, volcaremos la línea de tiempo a un fichero con la herramienta “fls”, unificaremos los datos con un “cat” puesto que el reto presenta distintas imágenes, para finalizar traduciendo y ordenando con “mactime”. Es importante recordar que se nos indicó que la hora del sistema era GMT+6 y este dato deberá ser introducido a la herramienta mactime. Por ello debemos obtener el timezone correspondiente a GMT+6, por ejemplo de esta web. Con el timezone ya podemos ejecutar las ordenes necesarias para obtener la línea de tiempo:

# mkdir /reto/carving/timeline
# for i in `ls honeypot.hda*`; do fls -rp -m / $i > /reto/carving/timeline/$i; done
# cd /reto/carving/timeline
# cat * >> timeline
# mactime -z CST -b timeline >> lineaTiempo

Una vez obtenida, tenemos que estudiar el fichero lineaTiempo muy a fondo. Es importante recordar la fecha del incidente y buscar ficheros cuyos metadatos y datos hayan sido modificados. Pese a que el atacante haya usado herramientas como wipe, srm, touch para borrar sin rastro o cambiar la fecha, es muy complicado que modifique todos los ficheros y directorios a los que ha tenido acceso. Recordemos que el incidente fue a las 23:11 del 7 de noviembre de 2000.

Para analizar la línea de tiempo es necesario entender un poco que se muestra en el fichero lineaTiempo. Cada línea indica un fichero y están ordenadas por fecha, de más antiguas a menos. La línea tiene una serie de columnas que identifican de izquierda a derecha la fecha, el tamaño, MACB, permisos, UID, GID, número de inodo (importantísimo) y nombre del fichero.

Teniendo en cuenta que el ataque fue realizado el 7 de noviembre por la noche, tenemos que buscar modificaciones realizadas por esa fecha. Analizando la línea de tiempo vemos que el 8 de noviembre, unas horas después de detectar el exploit, se han hecho modificaciones algo sospechosas sobre algunos ficheros. Principalmente me llama la atención lo siguiente:

Wed Nov 08 2000 14:25:53 2836    .a.. r/rr-xr-xr-x 0 0 17088 /bin/uptime
Wed Nov 08 2000 14:26:15 0       m.c. r/rrw-r--r-- 0 0 26217 /etc/hosts.deny
Wed Nov 08 2000 14:26:51 1024    .a.. d/drwxr-xr-x 0 0 62497 /etc/rc.d/init.d
Wed Nov 08 2000 14:29:27 63728   .a.. r/rrwxr-xr-x 0 0 16125 /bin/ftp
Wed Nov 08 2000 14:33:42 1024    .a.. d/drwx------ 2 2 58465 /spool/at
Wed Nov 08 2000 14:45:18 161     .a.. r/rrw-r--r-- 0 0 26216 /etc/hosts.allow
                         0       .a.. r/rrw-r--r-- 0 0 26217 /etc/hosts.deny
                         31376   .a.. -/rrwxr-xr-x 0 0 93839 /$OrphanFiles/
                                                             OrphanFile-93839 (deleted)
Wed Nov 08 2000 14:45:19 63      .a.. r/rrw-r--r-- 0 0 26573 /etc/issue.net
Wed Nov 08 2000 14:45:24 1504    .a.. r/rrw-r--r-- 0 0 18147 /etc/security/console.perms
Wed Nov 08 2000 14:51:37 2129920 m... -/rrw-r--r-- 500 500 8133 /$OrphanFiles/
                                                                OrphanFile-8133 (deleted)
                         5324    .a.. r/rrwxr-xr-x 1010 100 109808 /man/.Ci/sp.pl
                         132785  .a.. r/rrwxr-xr-x 1010 100 109809 /man/.Ci/qs
                         350996  .a.. r/rrwxr-xr-x 1010 100 109812 /man/.Ci/syslogd

...

Wed Nov 08 2000 14:52:09 9        m.c. l/lrwxrwxrwx 0 0 23 /.bash_history -> /dev/null
                         9        m.c. l/lrwxrwxrwx 0 0 46636 /root/.bash_history -> 
						              /dev/null

(Y un ejército de ficheros huérfanos...)

¿Os acordáis de las tablas realizadas en la primera entrada? Si las consultamos obtenemos que m-c corresponde a la modificación del contenido del fichero. Si analizamos que ficheros han sido modificados obtenemos que “/etc/hosts.deny” y los history han sido modificados. Por un lado tenemos el típico enlace dinámico del bash_history al /dev/null para evitar que registre (¿porque no usar unset HISTFILE que canta menos? El atacante sabrá…), por otro lado tenemos que el hosts.deny ha sido modificado, con lo que probablemente se habrá eliminado alguna restricción de conexión con otros hosts (estaría bien tener acceso a las copias de seguridad previas al incidente para ver la configuración del fichero). También llama la atención el directorio “/man/.Ci”, apuntamos para repasar.

A su vez, vemos que existe un fichero huérfano (fichero eliminado cuyo padre también ha sido eliminado), que indica que el propietario es el usuario 500. Apuntamos; es importante revisar si el usuario existe en /etc/passwd. Por otro lado hay que destacar que el enlace dinámico a /dev/null ha sido realizado después de eliminar el fichero, por lo que es posible que obtengamos las órdenes ejecutadas en el bash_history a partir de los bloques libres (tras la eliminación, el bloque ha quedado asignado como libre, pero la información no ha sido eliminada).

Vamos a obtener los bloques, en crudo o raw, no asignados a ningún inodo, y por tanto, los bloques libres con el objetivo de buscar en ellos órdenes, firmas de malware u otro tipo de documentos. Para ello primeramente nos crearemos el directorio “/reto/carving/unallocated”, y estando en el directorio “/reto/dd” volcaremos los bloques sin asignar en el directorio unallocated:

# mkdir /reto/carving/unallocated
# for i in `ls honeypot.hda*`; do blkls -f ext2 $i > ../carving/unallocated/$i; done

Ahora ya tenemos los bloques libres, veamos a ver si encontramos alguna orden referente a los bash_history o host.deny. Para ello nos creamos un fichero en /reto/etc/ficheros que contenga ficheros que vamos a ir necesitando para el caso:

# echo "bash_history" > /reto/etc/ficheros
# echo "hosts.deny" >> /reto/etc/ficheros
# cd /reto/carving/unallocated
# srch_strings -a -td -5 * | grep -i -f /reto/etc/ficheros

  723938826 rm -rf /root/.bash_history
  723938853 ln -s /dev/null /root/.bash_history
  723938889 rm -rf /.bash_history
  723938911 ln -s /dev/null /.bash_history
  723938942 rm -rf ~games/.bash_history

...

  32494603 chmod a-w ~/.bash_history
  92321290 rm -rf /root/.bash_history
  92321317 ln -s /dev/null /root/.bash_history

...

  92321564 ln -s /dev/null /usr/games/.bash_history
  211349515 chmod a-w ~/.bash_history

...

  160623032 rm -rf /etc/hosts.deny
  160623055 touch /etc/hosts.deny
  212043412 @@contents /etc/hosts.deny 8

A partir de los resultados anteriores, vemos claramente la orden de eliminación del fichero hosts.deny, así como la creación con posterioridad. Lo mismo para los bash_history. Con lo anterior sacamos la conclusión de que a las 14:26:15 del miércoles 8 de noviembre el fichero hosts.deny fue modificado y a las Wed Nov 08 2000 14:52:09 se borraron las huellas del history. Se podría intentar sacar el contenido antiguo del fichero hosts.deny intentando pensar qué texto podría contener. Si pensamos detenidamente un tag típico sería el ALL por lo que con la orden

# srch_strings -a -td -3 * | grep "ALL:"

se podría obtener la línea del bloque donde se encuentra la información, pero en este caso, no da resultados. Ahora nos toca analizar más detenidamente la línea donde se ilustra la eliminación del fichero hosts.deny: “160623032 rm -rf /etc/hosts.deny”. Ese valor 160623032 identifica el byte donde la cadena fue encontrada. Como sabemos el tamaño del bloque es 1024 por tanto dividímos los 160623032 entre 1024 y nos quedamos con la parte entera, es decir, 156858. Ahora pensemos: estamos analizando los bloques libres de una imagen raw, por tanto necesitamos saber qué bloque real ocupa el bloque libre 156858 en la imagen completa, para ello usamos blkcalc:

# blkcalc /reto/dd/honeypot.hda8.dd -u 156858 
188701

Ahora ya sabemos que en el bloque de la imagen completa está la orden “rm -rf /etc/hosts.deny”. Veamos ahora el contenido del bloque, el cual debería corresponder con la parte del fichero “bash_history” que intentó ocultar el atacante:

# blkcat /reto/dd/honeypot.hda8.dd 188701

...

exit
uptime
rm -rf /etc/hosts.deny
touch /etc/hosts.deny
rm -rf /var/log/wtmp
touch /var/log/wtmp
killall -9 klogd
killall -9 syslogd
rm -rf /etc/rc.d/init.d/*log*
echo own:x:0:0::/root:/bin/bash >> /etc/passwd
echo adm1:x:5000:5000:Tech Admin:/tmp:/bin/bash >> /etc/passwd
echo own::10865:0:99999:7:-1:-1:134538460 >> /etc/shadow
echo adm1:Yi2yCGHo0wOwg:10884:0:99999:7:-1:-1:134538412 >> /etc/shadow
cat /etc/inetd.conf | grep tel
exit

Efectivamente, vemos que se trata del bash_history real, donde por un lado se ha hecho una purga de los logs y de los demonios que lo generan. Por otro lado se han creado dos usuarios, “own” y “adm1”. El primero con privilegios de root y el segundo con uid 5000. Con esto queda demostrado que el equipo ha sido comprometido.

El siguiente paso es comprobar que acciones adicionales han sido llevadas a cabo por el atacante y que utilidad estaba obteniendo éste del servidor. Para ello vamos a montar el entorno en forma de solo lectura y comenzar a comprobar las huellas obtenidas con anterioridad del sistema de ficheros:

  • ¿Initd sigue teniendo la puerta trasera?
  • Usuario 500, ¿quien es?
  • ¿Usuario own existe?
  • ¿Usuario adm1 (5000) existe?
  • ¿Que hay en el directorio /man/.Ci”

Para montar el sistema de ficheros he creado una script de forma que ejecutándolo monte o desmonte el sistema. Lo he creado en el directorio “/reto/dd” con nombre montar.sh y posteriormente le he asignado permisos de ejecución:

# touch /reto/dd/montar.sh
# chmod u+x /reto/dd/montar.sh
# vim /reto/dd/montar.sh

#!/bin/bash --
if [ "$1" == "1" ];
then
 /bin/mount -o loop,ro,noatime,noexec /reto/dd/honeypot.hda8.dd /reto/mnt/
 /bin/mount -o loop,ro,noatime,noexec /reto/dd/honeypot.hda1.dd /reto/mnt/boot/
 /bin/mount -o loop,ro,noatime,noexec /reto/dd/honeypot.hda6.dd /reto/mnt/home/
 /bin/mount -o loop,ro,noatime,noexec /reto/dd/honeypot.hda5.dd /reto/mnt/usr/
 /bin/mount -o loop,ro,noatime,noexec /reto/dd/honeypot.hda7.dd /reto/mnt/var/
else
 /bin/umount /reto/mnt/boot/
 /bin/umount /reto/mnt/usr/
 /bin/umount /reto/mnt/var/
 /bin/umount /reto/mnt/home/
 /bin/umount /reto/mnt/
fi

De esta forma, ejecutando “/reto/dd/montar.sh 1” monto el entorno y con “/reto/dd/montar.sh 0” lo desmonto. Así que ya sabéis, a montar el entorno toca:

# /reto/dd/montar.sh 1

Una vez montado comprobamos las consultas anteriores:

  • Las modificaciones en el servicio inetd durante el ataque no existe.
  • El usuario 500 es Drosen y existía antes del ataque.
  • El usuario own y adm1 no existen.
  • El directorio /man/.Ci existe:
    # find /reto/mnt/ -type d -name ".Ci"
    /reto/mnt/usr/man/.Ci

El siguiente paso consistirá en analizar el directorio “/reto/mnt/usr/man/.Ci” para revisar que hay dentro y ya les adelanto que nos encontramos una jungla:

# ls /reto/mnt/usr/man/.Ci
addn  backup  chmod-it  do  fix  killall  paki  q  rmS  snap  sniff.pid  syslogd
a.sh  addps  bx  clean  find  inetd  needz  pstree  qs  scan  snif  sp.pl  tcp.log

Empleemos con los ficheros anteriores la herramienta “file” que me permite clasificar los ficheros:

# file * | grep -v ELF | grep -v directory
a.sh: ASCII text
addps: POSIX shell script text executable
chmod-it: ASCII text
clean: ASCII text
do: ASCII text
needz: POSIX shell script text executable
rmS: POSIX shell script text executable
snap: POSIX shell script text executable
sniff.pid: ASCII text
sp.pl: a /usr/bin/perl script text executable
tcp.log: empty

Veamos que contienen los ficheros:

  • El fichero “a.sh” contiene la eliminación de binarios y parada de los servicios de esos binarios, todo apunta a que esto es el paso previo a la implantación de un RootKit a nivel de aplicación (porque como sea a nivel de núcleo difícil lo tenemos).
  • El fichero “addps” introduce en el fichero “/dev/ptyp” procesos, que según indica la propia documentación, son aquellos procesos que se quieren ocultar. Al mostrar el contenido del fichero vemos lo siguiente:
    ...
    2 snif
    2 pscan
    2 slice2
    2 snif
    2 pscan
    2 telnet
    2 x
    2 xscan
    2 ssh
    ...
  • El fichero “needz” muestra la dirección web de las herramientas pico y screen.
  • El fichero “rmS” elimina paquetes de software “ssh”, “wuftpd” y “nfs”.
  • El fichero “sp.pl” es un script en perl que levanta el sniffer “LinSniffer”, que escucha en una serie de puertos donde los password se transmiten en claro. Existe también un fichero Sniff.pid que contiene un número, que todo apunta a que se trata del PID del proceso, y por tanto, podemos creer que el sniffer llegó a ejecutarse…
  • El fichero “tcp.log” está vacío.
  • El fichero “do” contiene la eliminación de los usuarios “own” y “adm1” que encontramos al recuperar el bash_history real del usuario. Por tanto ya sabemos a ciencia cierta que el atacante creó dos usuarios, uno de ellos root, y que posteriormente los eliminó, por lo que todo indica que ha conseguido acceso a la máquina sin necesitar usuarios en el entorno.
  • El fichero “chmod” cambia permisos a varios binarios, volviéndolos igual o más restrictivos que los de serie en la distribución. Esto huele cada vez más a rootkit a nivel de aplicación.
  • El fichero “clean” ejecuta el fichero “snap” introduciéndole varias opciones. Ahora veremos que contiene “snap”.
  • El fichero “snap” es una shell en bash que dado una palabra quita todo rastro de esa palabra en los logs.

En cuanto a los directorios tenemos “backup”, “paki” y “scan”:

  • El directorio “backup” contiene los binarios de archivos importantes como ifconfig, ps o ls. He realizado una simple comprobación para ver si los binarios que están en backup son los mismos que los que tiene instalados el servidor, pero no, difieren:
    # md5sum backup/ls ../../../bin/ls
    5ec59b9c05706b4ce65adf44d0d3ab24 backup/ls
    06be0dbe8e41a0266eeeeeb1c1b4c818 ../../../bin/ls
  • El directorio “paki” contiene dos herramientas. La primera es el código del stream y la segunda es slice2 cuya finalidad es la denegación de servicio (DoS).
  • El directorio “scan” contiene un gran número de ficheros cuyo objetivo es escanear host de la red e intentar ejecutar exploits sobre la máquina y crear puertas traseras. Si analizamos el código del “amd” vemos que intenta explotar vulnerabilidades en el RPC. Curiosamente es la misma vulnerabilidad con que ha sido comprometido el servidor.

En definitiva se trata de un RootKit a nivel de aplicación que permite mantener el control de la máquina, sniffar el tráfico de esta, atacar otras máquinas, ocultar huellas, ocultar procesos, etc. Buscando un poco por internet por si fuera un RootKit conocido he encontrado esta entrada que detalla bastante bien el RootKit.

El último paso a llevar a cabo es comprobar cómo consigue el atacante conectar a la máquina. Acordaos que hemos visto ficheros que borraban los instaladores de varios servicios. A su vez un par de cuentas que luego fueron eliminadas. Algo raro, ¿verdad? Podría tratarse de una escalada de privilegios mediante ficheros suid, pero para ello necesitaría un usuario no privilegiado en el sistema, pero también lo ha borrado. Lo más recomendado es volver a la línea de tiempo por si pudiera proporcionarlos un poco más de información.

Si analizamos detenidamente la fecha de implantación del RootKit veremos las siguientes entradas:

Wed Nov 08 2000 14:53:12 343586 mac. r/rrwxr-xr-x 0 0 110004 /local/bin/ssh-agent1
                         10     mac. l/lrwxrwxrwx 0 0 110005 /local/bin/ssh-agent -> 
                                                             ssh-agent1
                         337617 mac. r/rrwxr-xr-x 0 0 110006 /local/bin/ssh-add1
                         8      mac. l/lrwxrwxrwx 0 0 110007 /local/bin/ssh-add -> ssh-add1
                         90424  mac. r/rrwxr-xr-x 0 0 110008 /local/bin/scp1
                         4      mac. l/lrwxrwxrwx 0 0 110009 /local/bin/scp -> scp1
                         21228  mac. r/rrwxr-xr-x 0 0 110010 /local/bin/
                                                             make-ssh-known-hosts1
                         21     mac. l/lrwxrwxrwx 0 0 110011 /local/bin/
                                                             make-ssh-known-hosts ->
                                                             make-ssh-known-hosts1
                         643674 m.c. r/rrwxr-xr-x 0 0 33115 /local/sbin/sshd1
                         5      m.c. l/lrwxrwxrwx 0 0 33116 /local/sbin/sshd -> sshd1

Ya con esto nos sobra para despejar dudas. Es lógico que si el atacante requiere un servicio que no está disponible en el sistema lo instale, pero que existiendo el servicio instale uno nuevo y adicionalmente añada al nombre del servicio un 1 y que los binarios del servicio original sean ahora simples enlaces dinámicos al servicio añadido por el atacante, nos indica una cosa: el servidor sobreescrito está modificado para permitir la autenticación directa del atacante sin pasar por los métodos tradicionales.

Accedamos al directorio “/reto/mnt/usr/local/bin” y analicemos los ficheros modificados por el atacante. Lo que primero nos llama la atención es el SUID del fichero ssh1. Pero más que eso nos interesa ver el servicio que se arranca el SSH (“sshd1”) que se encuentra en el “/reto/mnt/usr/local/sbin”. Una forma sencilla de poder analizar el binario sshd1 es usar de nuevo un srch_strings, aunque lógicamente lo mejor sería usar el gdb, pero esto requeriría varias entradas en el blog dedicadas únicamente al gdb. Bien veamos qué strings nos muestra esto:

# srch_strings -a -td sshd1
...
146880 d33e8f1a6397c6d2efd9a2aae748eb02
...
148316 /usr/tmp/nap
148352 +-[ User Login ]-------------------- --- --- - -
148416 | username: %s password: %s hostname: %s
148480 +----------------------------------- ----- --- -- -- -
...
543582 md5.h
...
550891 md5passwd:(0,30)=ar(0,1);0;32;(0,2)
550927 md:(126,2)
550938 md5buffer:(0,31)=ar(0,1);0;31;(0,11)
...

Me llaman la atención dos cosas: por un lado la primera entrada ya que esa forma de cadena me recuerda mucho al hash de un MD5, y la segunda el “/usr/tmp/nap” y el trozo de código a continuación. Veamos primero que hay en “/reto/mnt/usr/tmp/nap”:

# cat /reto/mnt/usr/tmp/nap
+-[ User Login ]-------------------- --- --- - -
| username: root password: tw1Lightz0ne hostname: c871553-b.jffsn1.mo.home.com
+----------------------------------- ----- --- -- -- -

Lo que pensaba: el SSH aparte de supuestamente permitir al atacante autenticarse sin necesidad de tener usuario en el sistema, está registrando los usuarios y contraseñas que acceden al SSH. Apuntamos el usuario y la contraseña. Revisamos la contraseña del usuario root del entorno y vemos que se trata de un MD5 ($1$), con semilla “eJ2yI2DF” y hash “0cXQKjrEYcYHM/qJu2X6Z”. Vamos a usar el John the Ripper para comprobar si el usuario de root identificado en el fichero es el mismo que el del sistema:

# apt-get install john
# cd /reto/aux/
# echo "tw1Lightz0ne" > passwd
# unshadow /reto/mnt/etc/passwd /reto/mnt/etc/shadow >> patata
# john --wordlist=passwd patata

Loaded 2 password hashes with 2 different salts (FreeBSD MD5 [32/32])
guesses: 0  time: 0:00:00:00 100%  c/s: 200  trying: tw1Lightz0ne

Curiosamente la contraseña guardada no pertenece al usuario root del sistema… Bueno dejemos esto apartado y recordemos el MD5 visto con anterioridad en el binario ssh1. Lo que vamos a ver es qué contraseña ha podido generar ese MD5. Se me ocurre una cosa bárbara y es que la contraseña guardada en el fichero sea la contraseña del atacante y el registro de contraseña no tenga una comprobación para evitar que la propia contraseña del atacante se registre… veamos a ver:

# echo "tw1Lightz0ne" | md5sum -
367d375770a5775c4a63d1862e2fceaf  -

No hay suerte. Algo se escapa… mmm claro, el salto de línea que añade el echo:

# echo -n "tw1Lightz0ne" | md5sum
d33e8f1a6397c6d2efd9a2aae748eb02

Bueno, pues al final el hash que hay en el servicio corresponde con el MD5 que está guardado en el fichero, y por tanto, el propio atacante ha dejado el registro de su acceso en el log de usuarios y contraseñas. Podemos apuntar el hostname “c871553-b.jffsn1.mo.home.com” como posible origen del atacante.

Para finalizar con el SSH vamos a comprobar si el servicio se inicia en caso de que el sistema se reinicie, para ello buscaremos en los scripts de arranque:

# grep ":initdefault" /reto/mnt/etc/inittab
id:3:initdefault:
# ls -l /reto/mnt/etc/rc.d/rc3.d/
...
lrwxrwxrwx 1 root root 11 Nov  5  2000 S99local -> ../rc.local

No vemos ningún enlace que identifique al SSH, pero si analizamos todos los enlaces del directorio anterior encontramos que al final el enlace dinámico “S99local”, el cual apunta al fichero “rc.local”, es el encargado de arrancarlo:

# grep -i ssh /reto/mnt/etc/rc.d/rc.local
/usr/local/sbin/sshd1

Una vez finalizado la manera que tiene el atacante de acceder al servidor, vamos a seguir analizando la línea de tiempo:

314    ..c. r/rrw-r--r-- 0 0 16195 /etc/pam.d/ftp
314    ..c. r/rrw-r--r-- 0 0 16195 /etc/pam.d/ftp-RPMDELETE (deleted-realloc)
8928   ..c. r/rrwxr-xr-x 1 1 17487 /bin/ftpcount
8928   ..c. r/rrwxr-xr-x 1 1 17488 /bin/ftpwho
8928   ..c. r/rrwxr-xr-x 1 1 17488 /bin/ftpwho-RPMDELETE (deleted-realloc)
484    ..c. r/rrw------- 0 0 26548 /etc/ftpaccess
456    ..c. r/rrw------- 0 0 26549 /etc/ftpconversions
39     ..c. r/rrw------- 0 0 26550 /etc/ftpgroups 1
04     ..c. r/rrw------- 0 0 26551 /etc/ftphosts
79     ..c. r/rrw------- 0 0 26552 /etc/ftpusers
180703 ..c. r/rrw-r--r-- 1010 100 109865 /man/.Ci/nfs-utils-0.1.9.1-1.i386.rpm (deleted)

Claramente se ha instalado un servidor FTP y un servidor NFS cuyo propósito es la transferencia sencilla de ficheros por parte del atacante. ¿Aunque, teniendo el SCP para que usar FTP? No pierdo mucho el tiempo en analizar estos servicios. Seguimos con la línea de tiempo:

Wed Nov 08 2000 14:54:25 547    .a.. r/rrw-r--r-- 0 0 26245 /etc/named.conf
                         33392  .a.. r/rrwxr-xr-x 0 0 30251 /bin/cp
                         525412 .a.. r/rrwxr-xr-x 0 0 33119 /local/sbin/named
                         5      mac. r/rrw-r--r-- 0 0 34293 /run/named.pid
                         2769   .a.. r/rrw-r--r-- 0 0 62498 /named/named.ca
                         422    .a.. r/rrw-r--r-- 0 0 62499 /named/named.local
                         525412 mac. r/rrwxr-xr-x 0 0 92809 /sbin/named

Esto es interesante: se ha instalado un servicio de DNS y se trata de algo crítico, puesto que un DNS puede usarse para una multitud de funciones. Si seguimos analizando la línea de tiempo veremos cómo el atacante una vez instalado los servicios indicados con anterioridad eliminó las fuentes de instalación:

Wed Nov 08 2000 14:56:08 18698240 ..c. r/rrw-r--r-- 1010 100 109791 /man/.Ci/
                                                    ssh-1.2.27.tar (deleted)
                         4096     m.c. d/drwxr-xr-x 1010 100 109798 /man/.Ci
                         1153     ..c. r/rrwxr-xr-x 1010 100 109801 /man/.Ci/
                                                    install-sshd1 (deleted)
                         1076     ..c. r/rrwxr-xr-x 1010 100 109802 /man/.Ci/
                                                    install-sshd (deleted)
                         80       ..c. r/rrwxr-xr-x 1010 100 109803 /man/.Ci/
                                                    install-named (deleted)
                         106      ..c. r/rrwxr-xr-x 1010 100 109864 /man/.Ci/
                                                    install-statd (deleted)
                         180703   ..c. r/rrw-r--r-- 1010 100 109865 /man/.Ci/
                                                    nfs-utils-0.1.9.1-1.i386.rpm (deleted)
                         195637   ..c. r/rrw-r--r-- 1010 100 109866 /man/.Ci/
                                                    wuftpd.rpm (deleted)
                         71       ..c. r/rrwxr-xr-x 1010 100 109867 /man/.Ci/
                                                    install-wu (deleted)

Podemos recuperar las herramientas que usó el atacante aprovechando que el sistema de ficheros es Ext2. Recordar que cuando eliminamos ficheros en Ext2, a diferencia de Ext3 y Ext4, los “punteros” (enlaces directos e indirectos) del inodo hacia los bloques donde se almacena los datos no se eliminan. Por tanto somos capaces de, sabiendo el inodo del fichero eliminado, recuperar su contenido, siempre y claro está que el contenido no haya sido sobreescrito por otro fichero. Por ejemplo, para el demonio de ssh:

# istat honeypot.hda5.dd 109791
inode: 109791
Not Allocated
Group: 7
Generation Id: 640190586
uid / gid: 1010 / 100
mode: rrw-r--r--
size: 18698240
num of links: 0
Inode Times:
Accessed: Wed Nov  8 15:52:59 2000
File Modified: Wed Aug  9 21:52:37 2000
Inode Modified: Wed Nov  8 15:56:08 2000
Deleted: Wed Nov  8 15:56:08 2000
Direct Blocks:
238256 238257 238258 238259 ...

Esos datos que se muestran al final del “Direct Blocks” es la diferencia con Ext3/4. En Ext3 o 4 no se mostrarían los números de bloques. Recuperemos el fichero y veamos si contiene las modificaciones en el SSHD vistas con anterioridad:

# icat honeypot.hda5.dd 109791 >> /reto/evidencia/ssh-1.2.27.tar
# ls -l /reto/evidencia/ssh-1.2.27.tar
-rw-r--r-- 1 root root 18698240 Feb 18 00:16 /reto/evidencia/ssh-1.2.27.tar
# file /reto/evidencia/ssh-1.2.27.tar
/reto/evidencia/ssh-1.2.27.tar: POSIX tar archive (GNU)
# tar xvf /reto/evidencia/ssh-1.2.27.tar
# grep -R "\[ User Login \]" *
ssh-1.2.27/sshd.c: fprintf(fp,"+-[ User Login ]-------------------- --- --- - -\n");
# grep -R "d33e8f1a6397c6d2efd9a2aae748eb02" *
config.h:#define USE_GLOBAL_PASS "d33e8f1a6397c6d2efd9a2aae748eb02"

Ya tenemos un ssh troyanizado para la colección. Volvamos con la línea de tiempo. Las siguientes entradas que me llaman la atención son las que se encargan de modificar binarios del sistema, lógicamente se trata de los binarios modificados para implantar el Rootkit:

Wed Nov 08 2000 14:56:57     4096 .a.. d/drwxr-xr-x 1010 100 109798 /man/.Ci
Wed Nov 08 2000 14:56:59    35168 ..c. r/rrwx------ 0    0   15639  /bin/chage
                            36756 ..c. r/rrwx------ 0    0   15641  /bin/gpasswd
                            33288 ..c. r/rrwx------ 0    0   15827  /bin/at
                           531516 ..c. r/rrwx------ 0    0   16523  /bin/sperl5.00503
                           531516 ..c. r/rrwx------ 0    0   16523  /bin/suidperl
                             5640 ..c. r/rrwx------ 0    0   17453  /bin/newgrp
                             5760 .a.. r/rrwxr-xr-x 0    0   30288  /bin/sleep
                            17968 ..c. r/rrwx------ 0    0   30293  /bin/ping
                            45388 ..c. r/rrwx------ 0    5   48410  /sbin/dump
                            67788 ..c. r/rrwx------ 0    5   48412  /sbin/restore
                            34751 ..c. r/rrwx------ 0    0   76969  /libexec/pt_chown
                             5896 ..c. r/rrwx------ 0    0   93297  /sbin/usernetctl
                            16488 ..c. r/rrwx------ 0    1   93846  /sbin/traceroute

Ya para finalizar vemos algo raro y que no esperaba: el “bash_history” y el home de Drosen se han creado durante los 15 minutos en los que se implantó el Rootkit:

Wed Nov 08 2000 14:59:07 4096 m.c. d/drwx------ 500 500 15395 /drosen
                         52   mac. r/rrw------- 500 500 15401 /drosen/.bash_history

Esto requiere contradecir lo expuesto con anterioridad: es muy posible que el usuario Drosen no sea tan legítimo como habíamos pensado en un principio. Vamos a proceder por ello a un análisis lógico del contenido del sistema de fichero para ver si podemos obtener más información de la intrusión:

# cat /reto/mnt/home/drosen/.bash_history
gunzip *
tar -xvf *
rm tpack*
cd " "
./install
exit

Nos hemos dejado algo en el análisis forense. El acceso a un directorio cuyo contenido es el espacio en blanco es una técnica bastante conocido de intentar ocultar información dentro de un directorio (junto con la “. ” o “.. “). Vemos que descomprime un fichero, elimina el fichero, accede al directorio en blanco, instala algo y por último cierra la sesión. No es un comportamiento muy normal:

# cat /reto/mnt/etc/passwd | grep drosen | awk -F':' {'print $3'}
500
# find /reto/mnt/home/drosen/ -type f -uid 500 2> /dev/null

(no sale nada interesante)

Veamos a ver si encontramos algo que coincida con tpack:

# find /reto/mnt/ -type f -iname "*tpack*"

(No hay suerte)

Llegado a este punto, podría decir que no sé qué fichero instaló el usuario. Seguramente si se analizara la línea de tiempo con más detenimiento podríamos obtener dicho fichero.

Como análisis superficial del incidente podemos tener una estimación de cuándo se hizo, cómo se hizo, qué se implantó en el servidor, cómo se conectaba el atacante al equipo y como intentó el atacante ocultar sus huellas. Para finalizar la entrada quiero indicar que aunque normalmente se emplea en cualquier análisis forense uno de mis packs de herramientas favoritas: foremost, sorter, md5depp y hfind, , debido a la antigüedad de este reto me ha sido imposible usarlo en este caso. El objetivo de estos programas es generar una lista blanca a partir de un entorno no comprometido con una configuración similar, lo que nos permitirá eliminar supuestos, adicionalmente combinarlo con una lista negra de malware, permitiendo reducir drásticamente los ficheros a tratar.

Espero que les haya gustado, y todo sea dicho, si se han leído toda la entrada se merecen un premio. Nos vemos en la próxima entrada.

Comments

  1. Espectacular post Ximo