Buenas,
Hacia tiempo que tenia ganas de escribir sobre análisis forense de memoria un poco más en profundidad de lo que he publicado en otras ocasiones, así que aprovechando un rato libre os presento este caso práctico.
Requisitos
- Instalación funcional de Volatility 2.0. Se aconseja seguir las instrucciones disponibles en http://code.google.com/p/volatility/wiki/FullInstallation
- Una captura de memoria (en este caso, de una plataforma Microsoft Windows). En este ejemplo se trata del fichero memoria-shernando.mem
- Posibilidad de ejecutar scripts bash, con lo que se aconseja instalar Volatility en Linux, aunque esto es perfectamente realizable en Windows, y siempre te puedes hacer tus scripts en cualquier otro lenguaje
- Lectura pausada de los comandos principales de Volatility
Identificando la captura de memoria
Volatility tiene tres comandos asociados a la identificación de volcados de memoria: imageinfo, kdbgscan y kprcscan. Nosotros vamos a usar imageinfo como punto de partida. En esta fase pretendemos confirmar cual es el perfil recomendado para el análisis (Suggested Profile). En primera instancia, el comando imageinfo efectuara una búsqueda basada en estructuras de depuración del núcleo (KDBG) para determinar el perfil, aunque es igualmente posible identificar el sistema examinando los valores de Kernel Processor Control Region (KPCR). El núcleo de Windows emplea KPCR para almacenar información de cada procesador, y se puede localizar en la dirección de memoria virtual 0xffdff000 (ver captura), siendo otra fuente más para identificar el sistema.
python vol.py -f /home/shernando/memoria-shernando.mem imageinfo
Tomamos nota de los perfiles sugeridos, y escogemos el que nos parezca más adecuado. En este caso, WinXPSP3x86, un XP Service Pack 3 corriendo en una arquitectura convencional de 32 bits con 4 procesadores.
Se pueden consultar los perfiles KDBG y KPCR mediante los siguientes comandos:
python vol.py -f /home/shernando/memoria-shernando.mem kdbgscan
python vol.py -f /home/shernando/memoria-shernando.mem kpcrscan
Enumeración de procesos en ejecución
Quizás lo mas inmediato y típico al evaluar una imagen de memoria sea conocer que procesos estaban en ejecución en el momento de efectuar la captura. Emplearemos pslist especificando el perfil que hayamos identificado en el paso anterior:
python vol.py –profile=WinXPSP3x86 -f /home/shernando/memoria-shernando.mem pslist
Para cada proceso se obtiene un offset de memoria, el nombre del proceso, el identificador de proceso (PID) y el identificador del proceso del proceso padre (PPID), el número de hilos, número de handles y fecha/hora en la que el proceso se inició. El offset que se obtiene por defecto es el virtual, si se quiere obtener el offset físico hay que emplear el operador -P, tal y como se explica en la documentación de Volatility. La información se presenta de una manera legible:
Para ilustrar nuestro ejemplo seleccionamos, dentro de la lista de procesos, el correspondiente a la ejecución de Mozilla Firefox. Escogemos este ejemplo ya que en los navegadores es frecuente que exista uso de contraseñas, con lo que trataremos de localizar alguna en la memoria para ilustrar las capacidades de Volatility.
En este caso, el navegador se ejecuta con PID 4128, con PID padre 1668 (algo normal, ya que pende de explorer.exe)
Para quien esté interesado, el comando pstree muestra los procesos ordenados en árbol, con lo que es fácil deducir las dependencias para cada caso. El comando a ejecutar sería:
python vol.py –profile=WinXPSP3x86 -f /home/shernando/memoria-shernando.mem pstree
A modo de ejemplo, en este caso se observa como services.exe pende de winlogon.exe y smss.exe, lo que viene siendo algo normal en una plataforma Windows. Como es lógico, la gestión de servicios (services.exe) depende del gestor de sesiones, que a su vez pende del subsistema de gestión de sesiones (smss.exe). Todos pertenecen al grupo de procesos SYSTEM. En rojo, las relaciones entre PIDs padre e hijo a título informativo.
Volcado específico del proceso en estudio (Método 1: memdump)
Con este método podemos aislar la porción de memoria en uso para un proceso determinado. Esto facilita las cosas, ya que en equipos modernos las imágenes de memoria (coincidentes con la memoria física instalada) pueden alcanzar 4, 6 u 8 GB con facilidad. Cuanto mas acotemos, menos trabajo de inspección sera necesario. No olvidemos que examinar cadenas de texto en una imagen de memoria es un ejercicio que no tiene por que traer resultados satisfactorios de vuelta, de modo que cuanto más facilitemos la labor, mejor.
Afortunadamente, memdump permite realizar el volcado de todos los segmentos de memoria asociados a un proceso. Nótese que por la dependencia de procesos en un sistema operativo, esto acarreara que además de los segmentos propios de un proceso se vuelquen todos los que por una razón u otra pudieran estar en uso como consecuencia de las dependencias entre procesos. No obstante, el tamaño de dicho volcado sera normalmente menor. Para este ejemplo, de un total de 3 GB de memoria, la ejecución sobre el PID de Firefox en estudio originó un volcado de 550.8 MB.
python vol.py –profile=WinXPSP3x86 -f /home/shernando/memoria-shernando.mem -p 4128 memdump -D volcados
Una vez obtenido el volcado, extraemos las cadenas de texto para ser inspeccionadas. A pesar de la reducción por focalización nos enfrentamos a 30.7 MB de fichero de texto como resultado.
strings volcados/4128.dmp >> volcados/4128.dmp.txt
Un simple grep sobre la cadena Passwd servirá para localizar las credenciales que buscábamos:
cat volcados/4128.dmp.txt | grep Passwd
Volcado especifico del proceso en estudio (Método 2: Análisis del árbol VAD)
En el trabajo forense de imágenes de memoria de plataformas Windows es posible trabajar con el árbol de descriptores de direcciones virtuales (Virtual Address Descriptor, VAD). La idea es la siguiente: habida cuenta que las estructuras VAD proporcionan una abstracción a mas bajo nivel de la memoria, es posible emplearlas para realizar un análisis más enfocado. Técnicamente, el árbol VAD establece las relaciones de los distintos rangos de memoria empleados por un proceso determinado. A medida que el mecanismo de asignación VirtualAlloc asigna memoria en un proceso determinado, se van añadiendo entradas al arbol VAD, de modo que si obtenemos la estructura del árbol para un proceso, obtendremos todos los rangos de memoria en uso para dicho proceso.
Para trabajar con VADs, Volatility ofrece 4 comandos: vadwalk, que ofrece una visión general del árbol VAD, vadtree que muestra la información en forma de árbol propiamente dicho, vadinfo , que arroja información extendida de los nodos VAD y vaddump, que permite realizar volcados de la estructura VAD. En su mayoría admiten discriminación por PID. Los comandos a ejecutar, serian para cada caso, los siguientes:
python vol.py –profile=WinXPSP3x86 -f /home/shernando/memoria-shernando.mem -p 4128 vadwalk
python vol.py –profile=WinXPSP3x86 -f /home/shernando/memoria-shernando.mem -p 4128 vadtree
python vol.py –profile=WinXPSP3x86 -f /home/shernando/memoria-shernando.mem -p 4128 vadinfo
Para ilustrar nuestro ejemplo utilizaremos vaddump:
python vol.py –profile=WinXPSP3x86 -f /home/shernando/memoria-shernando.mem -p 4128 vaddump -D vads
Esta ejecución salvará, en el directorio vads, los distintos segmentos asociados al proceso. Aquí dejo un extracto del resultado, que en este caso contiene 346 elementos que totalizan 285.1 MB.
Habida cuenta que extraer cadenas de 346 elementos es inviable si se hace a mano, podemos escribir un pequeño script que automatice la extracción para nosotros:
#!/bin/sh
for filename in /home/sansforensics/volatility-2.0/vads/*
do
echo "Processing" $filename >> results.txt
echo >> results.txt
strings $filename >> results.txt
echo ------------------------------------------- >> results.txt
done;
Este script producirá un fichero consolidado results.txt, en este caso de 5.4 MB. Al igual que antes, la búsqueda de la cadena Passwd arroja, como no podía ser de otro modo, idénticos resultados. Esto es totalmente normal y esperado, ya que a fin de cuentas hemos inspeccionado las mismas porciones de memoria, con dos métodos distintos.
Graficando el árbol VAD
El comando vadtree permite la obtención de un fichero en formato Graphviz para el proceso en estudio. Con ayuda de kgraphviewer o cualquier programa similar, es posible visualizar el árbol VAD generado.
python vol.py –profile=WinXPSP3x86 -f /home/shernando/memoria-shernando.mem -p 4128 vadtree –output=dot –output-file=graficovad.dot
Si alguien tiene curiosidad, he dejado el fichero resultante aquí. También para curiosos, una impresión del gráfico en PDF generada con kgraphviewer. Dada la gran cantidad de nodos, y con la idea de mantener un tamaño PDF reducido, la resolución es pequeña, aunque sirve para hacerse una idea.
BONUS
Ademas de lo que hemos explicado, Volatility puede hacer muchas más cosas. Merece la pena probar sus funcionalidades. Os dejo un vídeo reciente sobre una de las muchas cosas que podéis hacer: Cracking Passwords with Volatility and John: Now With 34.3% Better Video!
Un saludo,
Como siempre un gran trabajo Sergio, me vendrá más que bien ;)