Análisis forense con Volatility en Virtualbox y Ubuntu

En este artículo veremos cómo sería posible realizar un análisis forense de la memoria de una máquina virtual VirtualBox con un Ubuntu como sistema operativo invitado utilizando para ello Volatility Framework. A lo largo del artículo realizaremos una instalación básica de Volatility, la creación del perfil Linux necesario para realizar el análisis de la memoria, la adquisición de la memoria de la máquina virtual en vivo y los primeros pasos de un posterior análisis.

1. ¿Para qué realizar un análisis forense de la memoria?

Un análisis de la memoria es una parte de un análisis forense y la motivación es dispar: analizar una posible intrusión, obtener pruebas para probar un posible delito, existencia y comportamiento del malware, etc.

El análisis de memoria puede proporcionar información muy valiosa, ya que podemos ver el estado de la máquina en el momento de la captura. Esto puede mostrarnos conexiones de red existentes, claves criptográficas, procesos, ficheros abiertos, usuarios conectados…​ en definitiva, mucha información que con el apagado del sistema desaparecerá.

2. Qué es Volatility Framework

Volatility Framework es un conjunto de utilidades implementadas en Python cuyo objetivo es la extracción de la información de una captura de memoria RAM. El framework está mantenido por la Volatility Foundation, que es una fundación sin ánimo de lucro que promueve la existencia de herramientas forense para el análisis de memoria open source.

Es un Framework porque propone y define la estructura y las interfaces que las utilidades más específicas deberán implementar para poder integrarse y de ese modo beneficiarse de toda la funcionalidad que el framework proporciona. Además todo el framework puede utilizarse como librería, de modo que es factible utilizar Volatility dentro de otras herramientas. Hay que destacar que el framework se encarga exclusivamente de la fase de análisis, para el proceso de adquisición se deberán utilizar otras herramientas.

Aunque se trate de un framework, en un análisis forense generalmente se utilizará la utilidad de línea de comandos que proporciona ya que desde esta utilidad puede accederse a toda la funcionalidad.

La utilidad ofrece soporte para el análisis de distintos sistemas operativos como Linux, MacOS y Windows, formatos de paginación de diferentes arquitecturas como intel32, amd64 y ARM y formatos del espacio de direcciones en disco (que dependerán de la herramienta de adquisición). Esto lo veremos para el caso concreto que nos ocupa.

3. Instalación de Volatility

Ya existe un paquete en la distribución Ubuntu 16.04 con la versión 2.5 del framework. Sin embargo hace tiempo que está disponible la versión 2.6 que ofrece soporte a sistemas como Windows 10 y el soporte a Virtualbox que nos ocupa funciona correctamente. Por ello instalaremos la última versión disponible.

Debido a que en este artículo no vamos a analizar cómo funciona ni a incorporar nuevas funcionalidades, por simplicidad vamos a utilizar el paquete que viene con una versión ya compilada:

Instalando volatility en el sistema
$ wget http://downloads.volatilityfoundation.org/releases/2.6/volatility_2.6_lin64_standalone.zip
$ unzip volatility_2.6_lin64_standalone.zip
$ sudo mv volatility_2.6_lin64_standalone /opt/volatility
$ pushd /usr/local/bin
$ sudo ln -s ../../../opt/volatility/volatility_2.6_lin64_standalone volatility
$ popd

Podremos ver que funciona simplemente con:

$ volatility --help
Volatility Foundation Volatility Framework 2.6
Usage: Volatility - A memory forensics analysis platform.

Options:
  -h, --help            list all available options and their default values.
                        Default values may be set in the configuration file
                        (/etc/volatilityrc)
    ....

Si invocamos con la opción info veremos los perfiles de sistema que soporta así como los formatos del espacio de direcciones y plugins disponibles:

Salida recortada de la opción info
$ volatility --info | more
   ....
Profiles
 -------
VistaSP0x64                  - A Profile for Windows Vista SP0 x64
VistaSP0x86                  - A Profile for Windows Vista SP0 x86
VistaSP1x64                  - A Profile for Windows Vista SP1 x64
VistaSP1x86                  - A Profile for Windows Vista SP1 x86
   ....
Address Spaces
 -------------
AMD64PagedMemory              - Standard AMD 64-bit address space.
ArmAddressSpace               - Address space for ARM processors
FileAddressSpace              - This is a direct file AS.
   ....
VirtualBoxCoreDumpElf64       - This AS supports VirtualBox ELF64 coredump format
   ....
Plugins
 ------
amcache                    - Print AmCache information
apihooks                   - Detect API hooks in process and kernel memory
atoms                      - Print session and window station atom tables
atomscan                   - Pool scanner for atom tables
   ....
linux_apihooks             - Checks for userland apihooks
linux_arp                  - Print the ARP table
linux_aslr_shift           - Automatically detect the Linux ASLR shift
linux_banner               - Prints the Linux banner information
   ....

Si observamos, en Plugins hay un montón que empiezan por linux_, estos serán los que tengamos a nuestra disposición para el análisis. En Address Spaces tenemos LinuxAMD64PagedMemory y VirtualBoxCoreDumpElf64 lo que nos permitirá analizar un volcado de memoria de una máquina virtual VirtualBox. Sin embargo…​ ¡no hay ningún Profile disponible con un perfil de Linux!. Esto se debe a que para cada compilación del núcleo será diferente y deberemos crearlo nosotros "a mano".

4. Creando un perfil de Ubuntu para Volatility

Llegados a este punto te preguntarás ¿qué es un perfil de Volatility? y…​ ¿por qué es necesario crearlo para cada compilación del núcleo?.

Pues bien, no se nos escapará que un volcado de memoria no es más que un bloque enorme de bits, para poder analizarlo es necesario en primer lugar estructurar e identificar las páginas de memoria (los sistemas operativos modernos hacen uso del sistema de memoria virtual que ofrecen las arquitecturas y que divide la memoria en páginas) y a continuación identificar las estructuras básicas del núcleo del sistema operativo en las que están albergadas la información de los procesos y su paginación. Para ello Volatility debe:

  1. Conocer dónde están esas estructuras

  2. Mapear la información a tipos de datos nativos de Volatility

Y esto es básicamente un perfil: dónde están las estructuras y cómo se mapean a los tipos de datos de Volatility. Los tipos de datos de Volatility son una abstracción que utiliza el framework que hacen posible trabajar con distintos tipos de sistemas operativos y arquitecturas.

Es obvio que las estructuras pueden cambiar entre versiones del kernel: el kernel está muy vivo y cambia continuamente (no ocurre lo mismo con su interfaz, que debe permanecer estable). Pero las estructuras también cambian cuando se realiza una compilación nueva, ya que existen mecanismos de seguridad que aleatorizan el contenido de dichas estructuras y la ubicación en memoria. Por todo ello es necesario crear un nuevo perfil para cada compilación.

Sin embargo tenemos la "ventaja" de que, al usar una distribución, los paquetes con los kernels distribuidos son genéricos e idénticos para todas las máquinas en las que se instalan, por ello es posible realizar un perfil para cada nuevo paquete de kernel. Existe un repositorio oficial de Volatility que contiene perfiles generados en https://github.com/volatilityfoundation/profiles , sin embargo no se encuentra actualizado y tendremos generarlos nosotros mismos.

Vamos a crear un perfil, podríamos hacerlo en cualquier máquina que tuviera el mismo kernel instalado que el de la máquina que queramos analizar. Sin embargo, por comodidad y para no ensuciar la máquina, lo que hago es:

  1. crear un snapshot

  2. instalar las herramientas necesarias para crear el perfil

  3. generar el perfil y copiarlo a la máquina de análisis

  4. restaurar el snapshot

Evidentemente en el mundo real NO será posible hacerlo así, es más:

Nunca se deberán instalar herramientas en un sistema del que se va a realizar un análisis forense, por ello en el mundo real habría que montar una máquina con el mismo núcleo y generar el perfil para poder realizar el análisis.
También es posible implementar un mecanismo de generación de perfiles automático, pero esto se encuentra fuera del ámbito del artículo.

Para crear el perfil tras tomar el snapshot habría que:

# apt-get install build-essential linux-headers-`uname -r`
# apt-get install dwarfdump volatility-tools
# cd /usr/src/volatility-tools/linux
# make
make -C //lib/modules/4.4.0-103-generic/build CONFIG_DEBUG_INFO=y M="/usr/src/volatility-tools/linux" modules
make[1]: se entra en el directorio '/usr/src/linux-headers-4.4.0-103-generic'
  CC [M]  /usr/src/volatility-tools/linux/module.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /usr/src/volatility-tools/linux/module.mod.o
  LD [M]  /usr/src/volatility-tools/linux/module.ko
make[1]: se sale del directorio '/usr/src/linux-headers-4.4.0-103-generic'
dwarfdump -di module.ko > module.dwarf
make -C //lib/modules/4.4.0-103-generic/build M="/usr/src/volatility-tools/linux" clean
make[1]: se entra en el directorio '/usr/src/linux-headers-4.4.0-103-generic'
  CLEAN   /usr/src/volatility-tools/linux/.tmp_versions
  CLEAN   /usr/src/volatility-tools/linux/Module.symvers
make[1]: se sale del directorio '/usr/src/linux-headers-4.4.0-103-generic'

# zip U1604_4.4.0-103-generic.zip module.dwarf /boot/System.map-4.4.0-103-generic

Con esto tendríamos el fichero U1604_4.4.0-103-generic.zip que tendríamos que copiar vía ssh o alguna carpeta compartida a nuestra máquina de análisis. Y devolveríamos al snapshot antes de "enmarranar" el sistema.

5. Adquisición de la memoria de la máquina virtual VirtualBox

El proceso de adquisición de memoria es una tarea compleja en máquinas físicas, pero en virtuales es coser y cantar. En el caso de VirtualBox, con la máquina obviamente encendida basta con:

Volcado de la ram de máquina virtual
$ vboxmanage debugvm "lamp" dumpvmcore --filename lamp.elf
$ ls -lah lamp.elf
-rw------- 1 luis luis 269M ene  3 17:57 lamp.elf

Esto genera un fichero lamp.elf con el contenido de la memoria máquina virtual lamp. Este fichero usa una estructura ELF64 y puedes obtener más información aquí.

6. Analizando la memoria

Para poder analizar la memoria, primero hay que instalar el perfil. Por sencillez y para que esté disponible para más usuarios de la máquina, vamos a copiarlo dentro del directorio antes creado:

# mkdir -p /opt/volatility/profiles
# cp donde_lo_tengamos/U1604_4.4.0-103-generic.zip /opt/volatility/profiles

Crearemos un fichero básico de configuración .volatilityrc para nuestro usuario que ubicaremos en nuestro home:

Fichero .volatilityrc
[DEFAULT]
PLUGINS=/opt/volatility/profiles

Con esto le estaremos indicando a volatility que tenga en cuenta los plugins que se encuentran en dicho directorio. Podemos ejecutar con la opción info y comprobar que el perfil se encuentra disponible:

$ volatility --info | more
    ....
Profiles
 -------
LinuxU1604_4_4_0-103-genericx64 - A Profile for Linux U1604_4.4.0-103-generic x64
VistaSP0x64                     - A Profile for Windows Vista SP0 x64
    ....

Con esto instalado, ya podemos realizar el análisis de memoria de nuestra captura. En primer lugar, comprobaremos utilizando el plugin vboxinfo que nuestra imagen está soportada:

$ volatility -f lamp.elf vboxinfo
Volatility Foundation Volatility Framework 2.6
Magic: 0xc01ac0de
Format: 0x10003
VirtualBox 5.0.40 (revision 115130)
CPUs: 1

FileOffset Memory Offset Size
    0x24e0           0x0 0x10000000
0x100024e0    0xe0000000   0x800000
0x108024e0    0xf0400000   0x400000
0x10c024e0    0xf0800000     0x4000
0x10c064e0    0xffff0000    0x10000

Podemos obtener un listado de los plugins que tenemos disponibles con:

Obtener listado de plugins disponibles para el análisis de Linux
$ volatility --info | grep ^linux_
Volatility Foundation Volatility Framework 2.6
linux_apihooks             - Checks for userland apihooks
linux_arp                  - Print the ARP table
linux_aslr_shift           - Automatically detect the Linux ASLR shift
linux_banner               - Prints the Linux banner information
linux_bash                 - Recover bash history from bash process memory
    ....

Ahora vemos a utilizar nuestro profile recién creado, para ello indicaremos el nombre del perfil junto al plugin que deseamos utilizar:

$ volatility -f lamp.elf --profile=LinuxU1604_4_4_0-103-genericx64 linux_cpuinfo
Volatility Foundation Volatility Framework 2.6
Processor    Vendor           Model
------------ ---------------- -----
0            GenuineIntel     Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz

Si queremos evitar estar indicando el profile y el fichero de imagen en cada comando, podemos exportar las variables de entorno:

$ export VOLATILITY_PROFILE=LinuxU1604_4_4_0-103-genericx64
$ export VOLATILITY_LOCATION=file:///home/luis/tmp/today/lamp.elf
Esto podría hacerse también en el fichero de configuración visto anteriormente eliminando el prefijo VOLATILITY_.

Ahora basta ejecutar el comando con el plugin, a continuación algunos ejemplos de la potencia de esta herramienta:

Visualizando los procesos del sistema analizado
$ volatility linux_psaux
Volatility Foundation Volatility Framework 2.6
Pid    Uid    Gid    Arguments
1      0      0      /sbin/init
2      0      0      [kthreadd]
    ....
1361   1000   1000   /lib/systemd/systemd --user
1367   1000   1000   (sd-pam)
1370   1000   1000   -bash
1373   0      1000   sudo -s
1374   0      0      /bin/bash
1375   0      0      vi /etc/shadow
1376   0      0      sshd: luisadm [priv]
1406   1000   1000   sshd: luisadm@pts/0
1407   1000   1000   -bash
Visualizando los sockets abiertos
$ volatility linux_netstat
Volatility Foundation Volatility Framework 2.6
UNIX 9894               systemd/1     /run/systemd/notify
    ....
TCP      10.0.2.15       :   22 10.0.2.2        :51900 ESTABLISHED                  sshd/1376
TCP      10.0.2.15       :   22 10.0.2.2        :51900 ESTABLISHED                  sshd/1406
    ....
Visualizando los puntos de montajes
$ volatility linux_mount
Volatility Foundation Volatility Framework 2.6
udev                      /dev                                devtmpfs     rw,relatime,nosuid
/dev/sda1                 /                                   ext4         rw,relatime
    .....

Y con esto creo que ya vale por hoy, como habrás podido comprobar realmente no hemos hecho más que rascar la superficie de lo que podemos hacer con esta potentísima herramienta. Es posible que en el futuro haga algún artículo más avanzado, pero si quieres profundizar te recomiendo encarecidamente el excelente libro: The Art of Memory Forensics.

Espero que poder realizar el análisis de la memoria de una máquina virtual te haya hecho más feliz, si es así comparte si te ha gustado y…​ ¡ happy hacking ! ;)