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 es necesario emplear una herramienta que soporte los ficheros sparse, de tal forma que al detectar un fichero de este tipo rellene con 0 el espacio que realmente tiene asignado. 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."

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.

Comments

  1. Muy buen artículo. No tenía ni idea de que se podía llegar a tanto, en lo que se refiere a forense, con Xen.
    Lo dicho, genial artículo!

  2. IM-PRE-SIO-NAN-TE