Bastionado, seguridad en sistemas: El antiguo reto de la honeynet (II) pre { background:#eeeeee; border:1px solid #A6B0BF; font-size:120%; line-height:100%; overflow:auto; padding:10px; color:#000000 } pre:hover { border:1px solid #efefef; } code { font-size:120%; text-align:left; margin:0;padding:0; color: #000000;} .clear { clear:both; overflow:hidden; }

Bienvenido al blog

Bienvenidos al blog de seguridad en sistemas

lunes, 14 de febrero de 2011

El antiguo reto de la honeynet (II)

Buenas de nuevo, 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 os estaréis 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, etc.

Comencemos obteniendo la linea de tiempos del sistema de ficheros. Para ello nos crearemos un directorio, volcaremos la línea de tiempo con la herramienta "fls", unificaremos los datos con un "cat" para finalizar traduciendo y ordenando con "mactime". Es importante recordar que se nos indico 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 >> lineaTiemp
o
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 el 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 linea de tiempo es necesario entender un poco que se muestra en el fichero lineaTiempo. Cada línea indica un fichero y están ordenada por fecha, de más antiguos a menos. La línea tienen 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 modificado ciertos ficheros algo sospechoso, 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 ejercito de ficheros huérfanos...)
¿Os acordais 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, es decir, 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 fijaros, el enlace dinámico a /dev/null ha sido realizado después de eliminar el fichero, por tanto es posible que contengamos las ordenes ejecutadas en el bash_history en los bloques libres (datos donde el fichero ha sido "eliminado", el bloque 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 ordenes, firmas de malware o cierto tipos 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 razón 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 noviembr el fichero hosts.deny fue modificado y a las Wed Nov 08 2000 14:52:09 se borro las huellas del history. Se podría intentar sacar el contenido antiguo del fichero hosts.deny intentando pensar que 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". Bien ese 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. Bien ahora pensemos, estamos analizando los bloques libres de una imagen raw, por tanto necesitamos saber que 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 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 intento 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"
Par montar el sistema de ficheros me 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 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 contiene 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 jodido lo llevamos).
  • El fichero "addps" introduce en el fichero "/dev/ptyp" procesos, que según indica la propia documentación, 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 herramienta 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 llego a ejecutarse... 
  • El fichero "tcp.log" está vació. 
  • El fichero "do" contiene la eliminación de los usuarios "own" y "adm1" que encontramos buscando en las zonas del sistema de ficheros libres. Por tanto ya sabemos a ciencia cierta que el atacante creo dos usuarios, uno de ellos root, y que posteriormente los elimino, es decir, 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 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 indicadas para la generación de DoS.
  • El directorio "scan" contiene un gran número de ficheros cuyo objetivo es escanear host de la red y 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 como consigue el atacante conectar a la máquina. Acordaros que hemos visto ficheros que borraban los instaladores de varios servicios. Lo más recomendado es volver a la línea de tiempo por si pudiera proporcionarlos un poco más de información. Pero esto ya en la siguiente entrada. 

No hay comentarios:

Publicar un comentario