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

viernes, 15 de julio de 2011

Análisis forense en XEN con LVM

Cada vez más las tecnologías de virtualización están más extendidas y prácticamente no se suelen encontrar servidores físicos dedicados. Es por ello que a la hora de gestionar un incidente que requiera de análisis forense detallado es necesario conocer el funcionamiento de cada tecnología de virtualización existente para poder tomar las evidencias necesarias para el estudio del caso. 

Normalmente, dentro del grupo de gestión de incidentes solemos encontrarnos con casos donde la tecnología de virtualización empleada es VMWare o Hyper-V. Pero en otras ocasiones, como la que veremos a continuación, nos encontramos con otro tipo de tecnología de virtualización que no es tan común. Para esta entrada explicaremos de forma sencilla y resumida los pasos necesarias para tomar las evidencias del sistema de ficheros de un entorno de virtualización XEN, el cual presenta la particularidad de disponer de volúmenes lógicos LVM. 


En primer lugar, es necesario exportar la máquina virtual desde Xen Server mediante la orden “xe vm-export”, almacenándola en un disco duro externo:

# xe vm-export vm=Nombre_VM filename=/media/XXX/maquina.xva

Una vez copiada la máquina virtual debemos crear la suma de comprobación para la cadena de custodia: 

# md5sum maquina.xva


Ya en el laboratorio de análisis forense de nuestra empresa debemos extraer los discos duros de la máquina virtual Xen. Para ello desempaquetaremos en primer lugar la máquina, generándose un fichero XML y un directorio Ref:XX que contiene el disco duro: 

# tar xf maquina.xva 2> /dev/null

En el siguiente paso se deberá emplear un script que permita crear el disco duro de la máquina virtual a partir del directorio Ref:XX. Este paso es delicado puesto que si empleamos la herramienta xenmigrate.py nos generará la imagen del disco duro sin tener en cuenta los ficheros sparse (copia en escritura), muy comunes en la virtualización. Esto funciona para discos duros con particiones estándar pero no en particiones LVM, donde al intentar montar los volúmenes lógicos, nos dará un error de entrada/salida. 

Debido a este problema tenemos que buscar una herramienta que soporte los ficheros sparse, de tal forma que al detectar un fichero de este tipo rellene con 0 los datos que realmente tiene asignados. Mi compañero Raúl encontró un script sencillo en bash, por supuesto hecho por un mago :) que permitía esta función: 

xenmigrate.sh: 

#!/bin/bash 

dd if=/dev/zero of=blank bs=1024 count=1k
test -f image.img && rm -f image.img
touch image.img 

max=`ls ???????? | sort | tail -n1` 

for i in `seq 0 $max`; do
        fn=`printf "%08d" $i`
        echo -n "$fn of $max"
        if [ -f "$fn" ]; then
                echo " - appending chunk"
                cat $fn >> image.img
        else
                echo " - filling blank"
                cat blank >> image.img
        fi
done 

rm -f blank 

echo "Done."

Gracias a esta herramienta ya podemos proceder a la extracción del disco duro de la máquina virtual empleando el script anterior:

# cd Ref\:11/
# ./xenmigrate.sh imagen

Como resultado se obtiene una imagen de 20GB, que en nuestro caso coincide con los asignados al disco duro virtual frente a los 6GB que ocupan los datos. Por tanto confirmamos que se han rellenado los ficheros sparse con datos (ceros); una vez obtenida la imagen comprobamos que realmente se ha extraído correctamente: 

# mv imagen ../
# cd ..
# mmls imagen

DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors
Slot Start End Length Description
00: Meta 0000000000 0000000000 0000000001 Primary Table (#0)
01: ----- 0000000000 0000000062 0000000063 Unallocated
02: 00:00 0000000063 0000208844 0000208782 Linux (0x83)
03: 00:01 0000208845 0041929649 0041720805 Linux Logical Volume Manager (0x8e)

El siguiente paso consiste en obtener la partición boot y la partición LVM:


# dd if=imagen bs=512 skip=63 count=208782 of=sda1
# dd if=imagen bs=512 skip=208845 count=41720805 of=lvm

A continuación se debe ya tratar la partición LVM como si de una partición raw LVM se tratara, creando por tanto los volúmenes lógicos: 
 
# losetup /dev/loop0 lvm
# losetup -f lvm
# losetup -a

/dev/loop0: [0861]:26132492 (/media/XXX/xen/lvm)
# kpartx -a -v /dev/loop0

Como vemos, las unidades lógicas del volumen VolGroup00 se han creado en el sistema de ficheros:


# pvdisplay
  --- Physical volume ---
  PV Name               /dev/loop0
  VG Name               VolGroup00
  PV Size               19,89 GiB / not usable 19,49 MiB
  Allocatable           yes (but full)
  PE Size               32,00 MiB
  Total PE              636
  Free PE               0
  Allocated PE          636
  PV UUID               XXXXX-XXXX-XXXX-XXXX-XXXX
# ls -l /dev/mapper/ 
total 0
brw-rw----. 1 root disk 253,   1 jul 12 18:04 VolGroup00-LogVol00
brw-rw----. 1 root disk 253,   2 jul 12 18:04 VolGroup00-LogVol01

A partir de aquí activamos las unidades lógicas para poder hacer el volcado:

# vgchange -ay
  2 logical volume(s) in volume group "VolGroup00" now active

Obtenemos las particiones contenidas en la unidad LVM:


# dd if=/dev/VolGroup00/LogVol00 bs=512 of=sda2
# dd if=/dev/VolGroup00/LogVol01 bs=512 of=swap

Una vez extraídas las particiones ya podemos desmontar la unidad lógica LVM:

# vgchange -a n /dev/loop0
# kpartx -d /dev/loop0
# losetup -d /dev/loop0

Por fin disponemos de las particiones en raw de la máquina virtual para poder usar las herramientas de análisis forense o montar el entorno en solo lectura para su tratamiento. Por tanto a partir de ahora ya podremos comenzar a analizar, desde un punto de vista forense, las particiones sda1, sda2 y swap de la máquina virtual extraída. 

Entrada publicada también en securityartwork.


Continuar...

domingo, 3 de julio de 2011

Mi proyecto de fin de carrera

Este mes hace justamente dos años desde que presente mi proyecto de fin de carrera y por tanto ya es un proyecto libre. El proyecto se basa en NetInVM, ¿qué que es NetInVM? pues es una máquina virtual VMWare con una SUSE a la que llamaremos BASE y dentro de ella corre una red virtual con máquinas Debian y dispositivos de red virtuales empleando la tecnología de virtualización User Mode Linux (UML). 

Realmente las máquinas Debian utilizan el mismo sistema de ficheros al que llamaremos fichero madre. Lo que hace NetInVM es aplicar una configuración durante su primer arranque para adaptarlas al requisito deseado. Las modificaciones efectuadas sobre éstas respecto al sistema de fichero original se guardan en un fichero de copia en escritura COW.

La red virtual UML constaba de tres subredes (externa, dmz, interna) conectadas por un router (linux con iptables). Cada subred disponía de un dispositivo de red de capa 2 donde se le conectaban un total de 6 equipos por subred. Esos equipos eran una Debian 4 con un servicio Web, FTP y SSH. Por cada máquina virtual UML se cargaba una consola base y 3 konsole para interaccionar con ella. Cada consola se lanza en uno de los 8 escritorios del KDE de la SuSE (Base).



El proyecto tenia como objetivo principal modularizar NetInVM permitiendo construir la red virtual en módulos, vamos como si de unas piezas de lego se tratase. Por tanto debía ser capaz de añadir y eliminar módulos que indicaran un elemento de la red: un router, un switch, un host, un servicio, una red etc.

Esto se realizo creando un modelo totalmente modular donde para cada módulo existía un script que permitía añadirlo o eliminarlo comprobando previamente sus dependencias, permitiendo agregar o sustraer las dependencias del módulo. Un diseño a bajo nivel de como se diseño es el siguiente:


A su vez se añadieron los siguientes requisitos adicionales:
  • Soportar más de una red distinta. 
  • Exportar el diseño de la red con un fichero XML. 
  • Exportar la red completa (Sistema base, COW, configuración) o parcial (COW y configuración). 
  • Añadir servicios adicionales como base de datos y servidor de aplicaciones. 
  • Poder seleccionar entre HUB o Switch para la conexión de los equipos de cada sub red. 
  • Firewall a nivel de Host y en router que fuera capaz de configurarse de forma dinámica dependiendo de los servicios que ofreciera.
  • Añadir la funcionalidad al router para generara perdidas de paquetes intencionadamente, para de esta forma, comprender como funcionan los protocolos cuando se producen fallos en la electrónica. 
  • Red de detección de intrusos(NIDS) con una equipo con las sondas Snort y otro equipo con un MySQL más un consola de analista. 
  • Módulo de alta disponibilidad(HA) en modo activo pasivo, de esta forma se podría aprender como funcionan la alta disponibilidad entre equipos forzando una caida de un servidor y viendo como el otro servicio se daba cuenta de la caída y tomaba el control. 
  • Interfaz gráfica que permita facilidad de uso.  
  • Herramientas auxiliares como por ejemplo cargar la red virtual en un sistema de fichero tmpfs (RAM) para aumentar su velocidad, un reconocedor de puertos, un gráfico de recursos de cada una de las máquinas virtuales UML, Sniffer, etc, etc. 
  • Crear documentación automática explicativa de la red en formato HTML. 
  • Independencia real de la red virtual UML con la SuSE (Base) al autoconfigurarse cada host y no depender del DHCP ni del DNS de Base como ocurre en el NetInVM original.  
  • Poder añadir módulos adicionales.
  • Módulo de actualización de la imagen madre UML.
Vamos bastantes cositas... a continuación veremos un ejemplo desde la GUI de como funcionaba el proyecto, todo sea dicho que yo no soy un programador Java pero lo que importaba era lo que había por debajo ya que la interfaz gráfica solo invocaba a los script dependiendo de la selección (y más cuando la interfaz se tuvo que hacer una vez pasado7 meses del inicio del proyecto). Esto es la consola nada más la ejecutábamos:


Podíamos ir pinchando en los dispositivos para ir añadiéndolos o eliminarlos. Veamos el resultado tras añadir una serie de dispositivos:


El nombre que aparece en rojo es el nombre que le ponemos a la red y está en rojo porque no hemos grabado la red, es decir, si cerramos el programa se pierde el diseño creado. Como vemos hemos seleccionado un router, un switch para la red externa y dmz, un hub para la red interna, una máquina en la red externa, una maquina de la red interna y dos máquinas de la red DMZ que aparece en azul su nombre, debido a que ambas máquinas están en alta disponibilidad entre ellas, se ha seleccionado las sondas del NIDS para la red externa y DMZ pero no para la red interna.

Si pinchamos sobre el icono de una máquina, en este caso DMZB, veremos que módulos tiene habilitado. Para el ejemplo vemos el nombre de la máquina y junto al nombre entre paréntesis un número que identifica el escritorio donde se ejecuta NetInVM, en este caso en el escritorio 2 de la SuSE. A su vez se muestra la IP del host, el módulo de servidor de aplicaciones habilitado, base de datos, servidor Web, FTP y adicionalmente se encuentra en alta disponibilidad con DMZA para los servicios Web y FTP donde la IP virtual de la alta disponibilidad es 10.5.1.9:


Otro ejemplo sería pinchar sobre un router, donde podemos configurarlo indicando que tipo de router queremos si con reglas de filtrado habilitadas, que dispositivos de red va a tener cada subred conectada a él, en que escritorio se va a ejecutar y si queremos que se generen perdidas de paquetes para comprobar el funcionamiento de los protocolos cuando esto ocurre:


Una vez configurado si pinchamos sobre él se muestra la configuración de éste:


Este diseño podía ser exportado con unas simples lineas de un fichero XML y llevado a otro NetInVM para que fuera cargado por la interfaz Gráfica:


La red virtual se podía ejecutar desde la propia interfaz web tal donde se irán ejecutando las máquinas virtuales en cada escritorio de la SuSE que se le haya indicado, se muestra en la barra inferior del KDE:


Si por ejemplo vamos al escritorio 8, que es donde hemos indicado que se lancen las máquinas virtuales del IDS, veremos que hay dos máquinas virtuales ( 2 consolas básicas y 6 Konsole). La primera es IDSA que es la máquina con las sondas y IDSF que es la máquina con la base de datos y la consola del analista. IDSA enviará las alertas a la base de datos de IDSF:


Desde la interfaz gráfica se podía parar una máquina en concreto, reiniciarla o forzar un halt (un halt de Unix no de Linux, es decir, tirar del cable) así como parar la red completa. A su vez se podía acceder a cada máquina virtual con un solo clip, obtener los recursos consumidos por la máquina virtual, escanear una máquina virtual, acceder a la consola del IDS, etc:


Os dejo la documentación del proyecto, son algo más de 200 hojas, por si alguien más está interesado:
http://www.megaupload.com/?d=SK9Z3Q9D

Fueron unas 10.000 lineas en shell script (seguí el "lenguaje" en el que había sido desarrollado el proyecto) y unas 12.000 en Java para la interfaz gráfica. Todo sea dicho, yo no era un experto programando y menos en Java, pero el trabajo realizado a bajo nivel creo que era bastante tedioso y más para un chaval de 5º de carrera que nunca había tocado la tecnología UML. Al final le dedique un año completo en exclusiva al proyecto que me permitió obtener una nota de 9.5 sobre 10.

Tengo que indicar que en el primer año después de presentar el proyecto actualice el núcleo UML a 2.6.30, las Debian a Lenny, cambie SuSE por una Kubuntu 9.04 con KDE 4, cambie de VMWare a VirtualBox, actualice la NIDS: Snort 2.8.4.1, Barnyard, Sguil y reglas de Emerging Threats, desplegué el WebGoat en el servidor de aplicaciones y añadí los servicios de DNS y Nagios.

Un año después de haber presentado vi que NetInVM no se había actualizo con mi proyecto (era difícil integrarlo por mi falta de experiencia en estas cosas), que UML empezaba a no estar soportada por el kernel y que cada 5 meses tenía un examen de las certificaciones de SANS por lo que me era imposible poder continuar con el proyecto, pero si que me gustaba despedirme de algo que me costo un año y que creo que estaba muy bien dejando esta pequeña entrada para el recuerdo. Si alguien quiere la última versión comentada con anterioridad me la puede pedir, eso si, ocupa 6GB comprimida en bz2, así como, si alguien quiere continuar con el proyecto que me lo diga y le paso las fuentes sin problemas :)

Continuar...

Usar ShellBags para análisis forense en Win

Durante las primeras fases del análisis forense de un sistema de ficheros es importante crear una línea de tiempo donde se identifiquen cuando los ficheros y directorios han sido modificaron, accedidos y eliminados para crear una trazabilidad de las acciones realizadas en el sistema.

Para crear esta linea de tiempo se suelen emplear herramientas que analizan el sistema de ficheros ordenando cronológicamente las operaciones indicadas con anterioridad, siempre y cuando, el sistema de ficheros lo permita.

Dicha linea de tiempo es cruzada con otros datos a los que llamaremos "añadidos" o "artifacts" cuyo objetivo es crear la super linea de tiempo, gracias a que permiten obtener información adicional sobre las operaciones realizadas sobre el sistema de ficheros, así mismo, permiten detectar desviaciones que identifiquen modificaciones temporales anti forenses.

Esos artifacts, en entornos Windows, suelen ser los metadatos del sistema de ficheros NTFS, el registro y los logs de las aplicaciones. Dentro del registro disponemos de multitud de entradas que aportan gran valor a un análisis forense. Para ésta entrada trataremos las Shellbags del registro Windows.

Las Shellbags son unas entradas o llaves en el registro que informan de los ficheros y directorios que han sido accedidos recientemente por un usuario desde el explorador de Windows, entendiendo accedido como leído, creado, eliminado y copiado. Permitiendo validad algunas trazas de la la linea de tiempo del sistema de ficheros y disponiendo de un orden de acciones efectuadas por cada usuario.

Como se ha descrito anteriormente, el Shellbags se encuentran en el registro de Windows, y en concreto en los fichero NTUSER.DAT (Win XP) o USRCLASS.DAT (Vista/7) de cada usuario. Lo recomendado es copiarlos desde la imagen RAW del sistema de ficheros, por supuesto de la copia y no del original, y analizarlo desde un editor de registro como regview.py (gratuito y creado con 200 lineas de python XD).

Las Shellbags se encuentran en el fichero NTUSER.DAT o USRCLASS.DAT en la llave "Shell -> BagMRU":

Vista o Win 7:
Local Settings -> Software -> Microsoft -> Windows -> Shell -> BagMRU
Desde Win XP:
Software -> Microsoft -> Windows -> Shell -> BagMRU


PD: si accedemos desde un regedit de un Win en ejecución se debe acceder primeramente a Classes:
HKEY_USERS ->  UID Usuario -> Software  -> Classes


Una vez accedido se mostrara un arbol de carpetas y registros con una estructura numérica, donde se identifica cada número con un directorio del explorar de Windows. Esta estructura cambia de Win XP a Vista y 7. Un ejemplo en Win7 sería que "BagMRU" identifica a "Desktop", la hoja hija "0" del árbol es "Mi PC", si desplegamos veremos que el "0" hijo identifica la unidad C y así con todo. Cada nodo tiene una serie de registros asociados que contiene la información que nos interesa, lógicamente encodeada (acaba de morir un gatito). Tenéis más información sobre el funcionamiento de las shellbags en este paper.



Como habreis podido comprobar el problema radica en la dificultad de entender el arbol. Para ello existe herramientas que nos traducen el arbol y nos lo muestran en formato sencillo. MiTeC Windows Registry Analyzer, permitía volcar todos los datos del ShellBag, por desgracia solo soportaba WinXp y no Vista/Win7.

La única herramienta que he encontrado gratuita para ShellBags en Vista/Win7 es sbag de TZWorks. Para probar la herramienta primeramente he arrancado con un live de Linux y he copiado de una imagen raw de Windows el fichero c:\Users\miusuario\USRCLASS.DAT para luego tratarlo con sbag con la siguiente orden:

C:\Users\miusuario\Desktop> sbag64.exe USRCLASS.DAT > resultado

Obteniendo como resultado lo siguiente:

NTUSER.DAT\Software\Microsoft\Windows\Shell\BagMRU\
 bag |  Regkey modtime [UTC] |      folder name          | createdate |   ctime  | modifydate |   mtime  | accessdate |   atime  |  full path
   1 | 07/02/11 10:20:45.305 | Desktop                   |            |          |            |          |            |          | Desktop\
     | 07/02/11 10:20:45.305 | {CLSID_Network}           |            |          |            |          |            |          | Desktop\{CLSID_Network}\
   2 | 07/02/11 10:20:46.815 | \\XXXXXX\public\Folder Share |            |          |            |          |            |          | Desktop\{CLSID_Network}\\XXXXXX\public\
  23 | 07/02/11 10:08:24.966 | Vídeos                    | 02/02/2011 | 09:28:52 | 02/02/2011 | 09:28:52 | 05/26/2011 | 20:10:34 | Desktop\{CLSID_Network}\\XXXXXX\public\Vídeos\
  33 | 06/25/11 20:56:45.406 | HDTV                      | 04/03/2011 | 14:15:08 | 04/03/2011 | 14:15:08 | 05/29/2011 | 14:29:40 | Desktop\{CLSID_Network}\\XXXXXX\public\Vídeos\HDTV\

...

Al ejecutarlo parece ser que no se ha mostrado todos los datos que contiene el Shellbag, de hecho se aprecian los saltos en el identificador de bag, y creo que es debido a que empleo la versión limitada y gratuita de sbag.  Así que volví a la carga buscando alternativas.

Encontré otro programa que recomendaban y que te puedes descargar gratuitamente, aunque en modo demo, es "Registry Viewer" de AccessData (un clasico en forense). Cuando intente explorar el registro en la zona del BagMRU peto el programa... sin comentarios xD.



Buscando un poquito más encontré que RegRipper tiene dos plugins (bagtest y bagtest2) que son capaces de tratar las Shellbags de un Win7, en concreto y la que me funciono es la bagtest.

C:\Users\xxxxx\Desktop\Nueva carpeta>rip -p bagtest -r USRCLASS.DAT
Launching bagtest v.20090828
Software\Microsoft\Windows\Shell\BagMRU

\0\0
\0\0\0                     \\XXXXXXXX\public (Microsoft Network,Folder Share)
\0\0\1                     \\XXXXXX\admin (Microsoft Network)
\0\0\2                     \\XXXXXXXX\backup (Microsoft Network,Folder Share)
\0\0\0\0                   Imagenes
\0\0\0\1                   V+¡deos
\0\0\0\2                   Software
\0\0\0\3                   ISO
\0\0\0\4                   M+¦sica
\0\0\0\0\0                 Fondos
\0\0\0\0\0\0               Anime
\0\0\0\0\0\1               Fantasia
\0\0\0\0\0\2               Animales
\0\0\0\0\0\3               Paisaje
\0\0\0\0\0\4               Peliculas
\0\0\0\1\0                 HD
\0\0\0\1\1                 HDTV
\0\0\0\2\0                 Windows
\0\0\0\4\0                 Platero.y.tu
\0\0\0\4\1                 Extremoduro
\0\0\1\0                   Documentacion

...

Comparando los resultados con "sbag" vemos que el regripper parece mostrar algunas entradas más, peeero no muestra los metadatos temporales que existen en cada entrada del arbol y que es justamente la parte que más nos interesa para el análisis forense.

Por tanto, y a día de hoy, si no tenemos presupuesto recomiendo usar sbag para obtener casi la totalidad de la estructura y sus metadatos temporales. Adicionalmente emplearía RegRipper por si sbag no mostrara todo el árbol, para tener en cuenta que ese directorio o fichero fue accedido desde el explorar de Windows recientemente por el usuario correspondiente. 

Hasta la próxima entrada... y tened en cuenta que son las 3:00 de un sábado, no seáis crueles con las faltas de ortografía y la redacción... 


Continuar...