viernes, 31 de agosto de 2012

Linux, volatility y sus perfiles

Si hay una herramienta en el campo del análisis forense que ha crecido exponencialmente en los últimos años esta es sin duda volatility, permitiendo actualmente el análisis de la memoria de prácticamente cualquier sistema Windows (ya sea de 32 o de 64 bits) y con soporte en las ramas de desarrollo para MacOS y Linux, tal como se indica en las FAQ.

En esta ocasión vamos a seguir los pasos necesarios para poder analizar un volcado de memoria de un sistema Ubuntu 12.04.1 LTS, pero para ello primero necesitaremos el volcado, y con eso es con lo que vamos a empezar.

fmem

Como parte de su master thesis Ivor Kollár desarrolló foriana, aka Forensic RAM dump image analyser. Básicamente se trata de una herramienta para el análisis de volcados de memoria de sistemas linux que no se basa en patrones, por lo que supuestamente funcionaría con cualquier tipo de sistema/kernel linux origen. Integrado en dicha herramienta se incluye un lkm (o Loadable Kernel Module) que crea un nuevo dispositivo (/dev/fmem) el cual permite acceder directamente a la memoria y, por lo tanto, obtener un volcado de la misma utilizando dd (más sobre el uso de dd), tal como antes de la rama 2.6 del kernel era posible hacer utilizando el dispositivo virtual /dev/mem.

Para poder compilar fmem es preciso tener instalados los headers del kernel de linux que estemos corriendo, así que ejecutaremos:

# apt-get install linux-headers-$(uname -r)

Descargamos y compilamos fmem:
# cd /usr/local/
# wget http://hysteria.sk/~niekt0/fmem/fmem_1.6-1.tgz
# tar xvzf fmem_1.6-1.tgz
# cd /usr/local/fmem_1.6-1
# make

Cargamos el módulo en memoria utilizando el script proporcionado para ello:
# ./run.sh 
Module: insmod fmem.ko a1=0xc1052af0 : OK
Device: /dev/fmem
----Memory areas: -----
reg00: base=0x000000000 ( 0MB), size= 1024MB, count=1: write-back
reg01: base=0x040000000 ( 1024MB), size= 512MB, count=1: write-back
reg02: base=0x060000000 ( 1536MB), size= 256MB, count=1: write-back
reg03: base=0x070000000 ( 1792MB), size= 128MB, count=1: write-back
reg04: base=0x0c0000000 ( 3072MB), size= 8MB, count=1: write-combining
-----------------------
!!! Don't forget add "count=" to dd !!!

Para que la imagen de la memoria sea correcta es preciso, tal como advierte el mensaje anterior, indicar la cantidad total de que dispone el sistema:
# free -m
total used free shared buffers cached
Mem: 1886 1509 377 0 245 733
-/+ buffers/cache: 530 1356
Swap: 1917 2 1915

Tras lo que, ahora sí, generamos el volcado:
# dd if=/dev/fmem of=ubuntu.12.04.1.raw bs=1MB count=1886
1886+0 registros leídos
1886+0 registros escritos
1886000000 bytes (1,9 GB) copiados, 28,53 s, 66,1 MB/s

Como resultado obtendremos un volcado de memoria en formato raw.

LiME

Sin duda una de las herramientas que más ha dado que hablar últimamente por su capacidad para realizar volcados de la memoria de dispositivos Android, aunque en esta ocasión esa no será su finalidad (espero pronto poder escribir algo sobre forensics de sistemas android).

Como el anterior se trata de un lkm (o Loadable Kernel Module) sólo que durante las opciones de carga del mismo ya estaríamos lanzando la orden para obtener el volcado. Para instalarlo obtendremos en primer lugar la última versión disponible a través de subversion:
# cd /usr/local/
# svn checkout http://lime-forensics.googlecode.com/svn/trunk/ lime-forensics

Una vez descargado, y dado que ya tenemos instalados los headers para el kernel de linux que estamos corriendo, ejecutamos:
# cd lime-forensics/src/
# make

y para cargar el módulo en memoria y de paso obtener el fichero de volcado en /var/tmp:
# insmod lime-3.2.0-29-generic.ko "path=/var/tmp/ubuntu.12.04.1.lime format=lime"

En este caso obtendremos un volcado de memoria en formato lime, el cual está perfectamente soportado por volatility.

Generando un profile para volatility

A diferencia de los que indicábamos acerca de foriana, volatility se basa en perfiles para poder localizar en el volcado los diferentes elementos que estructuran la memoria de los sistemas analizados, y es por ello que si no disponemos del perfil correspondiente al origen del volcado deberemos generarlo previamente. Avisar que los pasos indicados aquí están perfectamente documentados en el wiki de volatility, concretamente en la sección LinuxMemoryForensics.

Primero descargamos e instalamos dwarfdump, resoviendo las dependencias:
# cd /usr/local/
# apt-get install libelf-dev
# wget http://reality.sgiweb.org/davea/libdwarf-20091012.tar.gz
# tar -xvzf libdwarf-20091012.tar.gz
# cd dwarf-20091012/libdwarf/
# ./configure && make && make install
# cd ../dwarfdump
# ./configure && make && make install

Descargamos ahora la rama linux de volatility desde el repositorio subversion:
# cd /usr/local
# svn checkout http://volatility.googlecode.com/svn/branches/linux-trunk/ volatility-linux

y ahora, utilizando la herramienta incluida con volatility, generaremos el perfil y lo nombraremos adecuadamente:
# cd volatility-linux/tools/linux/
# make
# cd /usr/local
# zip volatility-linux/volatility/plugins/overlays/ubuntu.12.04.1-3.2.0-29-generic.zip \
> volatility-linux/tools/linux/module.dwarf /boot/System.map-3.2.0-29-generic

El comando anterior genera el perfil y lo ubica en el directorio adecuado. Si comprobamos ahora los perfiles disponibles con volatility confirmaremos que incluye el nuestro:
# cd volatility-linux/
# python vol.py --info | grep Linux
Volatile Systems Volatility Framework 2.2_alpha
LinuxDebian2632_zipx86 - A Profile for Linux Debian2632.zip x86
LinuxDebian2632x86 - A Profile for Linux Debian2632 x86
Linuxubuntu_12_04_1-3_2_0-29-genericx86 - A Profile for Linux ubuntu.12.04.1-3.2.0-29-generic x86
linux_arp - Print the ARP table
linux_cpuinfo - Prints info about each active processor
linux_dmesg - Gather dmesg buffer
linux_dump_map - No docs
linux_ifconfig - Gathers active interfaces
linux_iomem - Provides output similar to /proc/iomem
linux_lsmod - Gather loaded kernel modules
linux_lsof - Lists open files
linux_memmap - Dumps the memory map for linux tasks.
linux_mount - Gather mounted fs/devices
linux_netstat - Lists open sockets
linux_pidhashtable - Enumerates processes through the PID hash table
linux_proc_maps - gathers process maps for linux
linux_psaux - gathers processes along with full command line and start time
linux_pslist - Gather active tasks by walking the task_struct->task list
linux_pstree - shows the parent/child relationship between processes
linux_psxview - Find hidden processes with various process listings
linux_route - lists routing table
linux_route_cache - Lists routing table
linux_tmpfs - recovers tmpfs filesystems from memory

Y ya podemos empezar a analizar el volcado utilizando cualquiera de los dos formatos (raw o lime):
# python vol.py -f ubuntu.12.04.1.lime \
--profile=Linuxubuntu_12_04_1-3_2_0-29-genericx86 linux_pslist
Volatile Systems Volatility Framework 2.2_alpha
Offset Name Pid Uid Start Time
0xf4878000 init 1 0 Tue, 21 Aug 2012 12:31:07 +0000
0xf4878cb0 kthreadd 2 0 Tue, 21 Aug 2012 12:31:07 +0000
...

Y esto ha sido todo ... por ahora ;-)

2 comentarios:

Andrew Case dijo...

Hello,

Nice blog post! The only thing I would change is to check out 'trunk' instead of 'branches/linux-trunk'. Linux-trunk is very out of date and will be deleted soon. All development of Linux support is now done in trunk, and has many new plugins and bug fixes.

I think you will like some of the new plugins :)

neofito dijo...

Thanks for your recommendations and your hard work developping volatility!