
Script para automatizar la captura y análisis de memoria de Linux
# Linux Memory Grabber Un script para volcar la memoria de Linux y crear perfiles de Volatility(TM). Hal Pomeranz ([email protected]), 2020-02-01 ¡AGRADECIMIENTOS! ======= "Si he visto más lejos es por estar sobre los hombros de gigantes." ~ Issac Newton Hay muchas personas que merecen agradecimiento por hacer posible esta pequeña herramienta: -- Las buenas personas de Microsoft por hacer disponible AVML -- Joe Sylve por su trabajo en LiME -- Todo el equipo de desarrollo de Volatility(TM) por su trabajo continuo. Me gustaría reconocer especialmente a Andrew Case, quien respondió varias preguntas molestas durante el desarrollo de mi herramienta. -- David Anderson por su apoyo continuo a libdwarf y dwarfdump -- Matt Suiche de MoonSols. Cuando estaba armando mi herramienta, mi objetivo de diseño era 'hacerla tan fácil de usar como DumpIt' (si necesitas capturar memoria de Windows, no conozco una herramienta más fácil de usar). Así que gracias por la inspiración, Matt! -- Personas que han proporcionado ideas y código para mejorar la herramienta: Julien -- Directorios alternativos de salida/compilación y etiquetas de ID de caso, abortar si no se ejecuta como root Jonathon Poling -- ideas similares a las de Julien Jeff Bryner -- Crear archivos volatilityrc para cada captura La comunidad es mejor gracias a todos estos esfuerzos. He elegido poner mi herramienta a disposición bajo la licencia Creative Commons "Atribución" (CC BY), para que esté lo más ampliamente disponible posible. ACERCA DE LA HERRAMIENTA ============== Para analizar la memoria de Linux, primero necesitas poder capturar la memoria de Linux. AVML funciona muy bien, pero si tu sistema no tiene /proc/kcore o /dev/crash, entonces necesitarás el Linux Memory Extractor (LiME) de Joe Sylve. Pero necesitas tener un módulo de LiME compilado para el kernel del sistema del cual deseas extraer la RAM. Volatility(TM) es excelente para analizar imágenes de memoria de Linux. Pero necesita un perfil que coincida con el sistema donde se capturó la memoria. Construir un perfil significa compilar un programa C en el sistema adecuado y usar dwarfdump para obtener las direcciones de las estructuras de datos importantes del kernel. También necesitas una copia del archivo System.map del directorio /boot. Ahora, si tienes un duplicado de tu sistema objetivo, puedes construir el perfil de Volatility(TM) en el clon y, si es necesario, construir LiME para capturar y analizar la memoria de tu objetivo. Pero hay muchas situaciones en las que no se dispone de un duplicado del sistema objetivo. Por lo tanto, es posible que debas construir tu perfil de Volatility(TM) y LiME en la máquina objetivo. Y esto no es para los débiles de corazón. Hay varios pasos y algunos comandos de Linux de bastante bajo nivel involucrados. Mi objetivo era crear un paquete que pudiera ser instalado (por un experto) en una memoria USB y distribuido a agentes en el campo. El usuario de la memoria USB debería poder enchufarla, ejecutar un solo comando y adquirir con éxito una imagen de memoria de la máquina objetivo y un perfil funcional de Volatility(TM). El resultado es mi script lmg (Linux Memory Grabber). SOBRE LA PUREZA FORENSE ================== Si eres un exigente con la pureza forense, probablemente esta no sea la herramienta para ti. Analicemos algunas de las formas en que mi herramienta interactúa con el sistema objetivo: Medios extraíbles -- La herramienta está diseñada para ejecutarse desde un dispositivo USB portátil, como una memoria USB. Vas a conectar un dispositivo de escritura en tu sistema objetivo, donde podría ser potencialmente atacado por usuarios maliciosos o malware en el sistema. El acto de conectar el dispositivo al sistema cambiará el estado de la máquina (por ejemplo, creará entradas de registro, entradas mtab, etc.). Si el dispositivo no es montado automáticamente por el sistema operativo, el usuario debe montar manualmente el dispositivo a través de un shell de root. Compilación -- Crear un perfil de Volatility(TM) implica compilar código en la máquina objetivo. También lo hace construir LiME cuando AVML no funciona. Así que se ejecutará gcc, se leerán archivos de cabecera, se enlazarán bibliotecas, etc. lmg intenta minimizar el impacto en el sistema de archivos de la máquina objetivo estableciendo TMPDIR en un directorio del dispositivo USB desde el que se ejecuta lmg. Esto significa que los archivos intermedios creados por el compilador se escribirán en la memoria USB en lugar de en el sistema de archivos local de la máquina objetivo. Dependencias -- Para compilar código del kernel en Linux, la máquina objetivo necesita un entorno de desarrollo funcional con gcc, make, etc., y todos los archivos de inclusión y bibliotecas compartidas adecuados. Y en particular, los archivos de cabecera del kernel deben estar presentes en la máquina local. Estas dependencias pueden no existir en el objetivo. En este caso, el usuario se enfrenta a la opción de instalar las dependencias adecuadas (si es posible) o no poder construir el perfil de Volatility(TM) para el sistema. Malware -- lmg usa /bin/bash, gcc, zip y una gran cantidad de otros programas de la máquina objetivo. Si el sistema ha sido comprometido, las aplicaciones que utiliza lmg pueden no ser confiables. Una solución más completa sería crear un entorno de ejecución seguro para lmg en el dispositivo USB portátil, pero estaba fuera del alcance de esta prueba de concepto inicial. Memoria -- Todos los comandos que se ejecuten causarán cambios en la memoria del sistema objetivo. El acto de capturar la RAM siempre creará artefactos, pero en este caso hay una compilación extensa, acceso al sistema de archivos, etc., además de ejecutar un volcador de RAM. Dicho todo esto, lmg es una herramienta muy conveniente para permitir que agentes menos hábiles capturen datos útiles de análisis de memoria de sistemas objetivo. Tenga en cuenta que si AVML falla, lmg buscará un módulo LiME ya existente en el dispositivo USB que coincida con la versión del kernel y la arquitectura del procesador de la máquina objetivo. Si lo encuentra, lmg no se molestará en recompilar. Del mismo modo, puede optar por que lmg no cree el perfil de Volatility(TM) para el objetivo para minimizar el impacto en el sistema objetivo. lmg usa rutas relativas al invocar programas como gcc y zip. Por lo tanto, si desea ejecutar estos programas desde un medio alternativo, simplemente actualice $PATH según corresponda antes de ejecutar lmg. USANDO LMG ========= Primero, prepare una memoria USB según las instrucciones en el documento INSTALL proporcionado con lmg. Cuando desee adquirir RAM, conecte la memoria USB a su sistema objetivo. En la mayoría de los sistemas Linux, los nuevos dispositivos USB se montan automáticamente en /media. Supongamos que el suyo termina en /media/LMG. Ahora, como root, ejecute "/media/LMG/lmg". Este es el modo interactivo y se le pedirá confirmación al usuario antes de que lmg construya un módulo LiME para el sistema y/o cree un perfil de Volatility(TM). Si no desea que se le pregunte, use "/media/LMG/lmg -y". Todo lo demás está automatizado. Después de que el script se ejecute, tendrá un nuevo directorio en la memoria USB llamado ".../capture/<hostname>-YYYY-MM-DD_hh.mm.ss" lmg soporta una opción -c para especificar un nombre de directorio de ID de caso que se usará en lugar del directorio predeterminado "<hostname>-YYYY-MM-DD_hh.mm.ss" directorio. Cualquiera que sea el nombre del directorio, el directorio contendrá: <hostname>-YYYY-MM-DD_hh.mm.ss-memory.lime -- la captura de RAM <hostname>-YYYY-MM-DD_hh.mm.ss-profile.zip -- perfil de Volatility(TM) <hostname>-YYYY-MM-DD_hh.mm.ss-bash -- copia de /bin/bash del objetivo volatilityrc -- archivo de configuración prototipo de Volatility El archivo volatilityrc define las ubicaciones adecuadas para la memoria capturada y el plugin. Consulte el EJEMPLO DE USO a continuación para saber cómo usar este archivo. La copia de /bin/bash es útil para determinar la dirección de la estructura de datos del historial del shell en la memoria de los procesos bash en la captura de memoria. Consulte https://github.com/volatilityfoundation/volatility/wiki/Linux-Command-Reference#linux_bash para obtener más detalles sobre cómo usar este ejecutable (o consulte el EJEMPLO DE USO a continuación). Tenga en cuenta que puede haber ocasiones en las que no desee escribir datos en el medio desde el que está ejecutando lmg, por ejemplo, si las herramientas de lmg están en un medio de solo lectura como un DVD-ROM. lmg soporta una opción -d para especificar un directorio de salida diferente. Por defecto, toda la compilación ocurrirá en el directorio de destino, pero el usuario puede especificar un directorio de compilación alternativo con -B. EJEMPLO DE USO ============= Aquí hay un ejemplo de uso de la herramienta lmg, que incluye usar Volatility(TM) directamente desde la memoria USB para analizar la imagen capturada. En mi máquina de prueba, la memoria USB estaba en /dev/sdb y no fue montada automáticamente por mi sistema operativo. Así que hice todo manualmente. 1) Obtener root y montar la memoria USB -------------------------------------------- [root@localhost ~]$ sudo -s [sudo] password for lab: [root@localhost lab]# mkdir -p /mnt/usb [root@localhost lab]# mount /dev/sdb1 /mnt/usb 2) Ejecutando lmg -------------- [root@localhost lab]# /mnt/usb/lmg -y AVML is /mnt/usb/avml/avml-x86_64 Dumping memory in "lime" format to /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55 This could take a while...Done! Grabbing a copy of /bin/bash...Done! Writing volatilityrc to /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55...Done! make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build M="/mnt/usb/volatility-master/tools/linux" clean make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' rm -f module.dwarf make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build CONFIG_DEBUG_INFO=y M="/mnt/usb/volatility-master/tools/linux" modules make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' CC [M] /mnt/usb/volatility-master/tools/linux/module.o Building modules, stage 2. MODPOST 1 modules WARNING: modpost: missing MODULE_LICENSE() in /mnt/usb/volatility-master/tools/linux/module.o see include/linux/module.h for more information CC /mnt/usb/volatility-master/tools/linux/module.mod.o LD [M] /mnt/usb/volatility-master/tools/linux/module.ko make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' dwarfdump -di module.ko > module.dwarf make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build M="/mnt/usb/volatility-master/tools/linux" clean make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' CLEAN /mnt/usb/volatility-master/tools/linux/.tmp_versions CLEAN /mnt/usb/volatility-master/tools/linux/Module.symvers make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' adding: module.dwarf (deflated 90%) adding: boot/System.map-4.18.0-147.3.1.el8_1.x86_64 (deflated 79%) 3) Ejecutando el plugin linux_banner para probar la captura, aprovechando el volatilityrc prototipo ------------------------------------------------------------------------------------- [root@localhost lab]# cd /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55 [root@localhost localhost.localdomain-2020-02-01_08.16.55]# ls localhost.localdomain-2020-02-01_08.16.55-bash localhost.localdomain-2020-02-01_08.16.55-memory.lime localhost.localdomain-2020-02-01_08.16.55-profile.zip volatilityrc [root@localhost localhost.localdomain-2020-02-01_08.16.55]# ../../volatility-master/vol.py --conf-file=volatilityrc linux_banner Volatility Foundation Volatility Framework 2.6.1 Linux version 4.18.0-147.3.1.el8_1.x86_64 ([email protected]) (gcc version 8.3.1 20190507 (Red Hat 8.3.1-4) (GCC)) #1 SMP Fri Jan 3 23:55:26 UTC 2020 4) Usar la copia capturada de /bin/bash para volcar el historial del shell con linux_bash --------------------------------------------------------------------------- [root@localhost localhost.localdomain-2020-02-01_08.16.55]# gdb localhost.localdomain-2020-02-01_08.16.55-bash GNU gdb (GDB) Red Hat Enterprise Linux 8.2-6.el8_0 Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from localhost.localdomain-2020-02-01_08.16.55-bash...Missing separate debuginfo for /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55/localhost.localdomain-2020-02-01_08.16.55-bash Try: dnf --enablerepo='*debug*' install /usr/lib/debug/.build-id/b6/858d77c486b7b596f22956149bbc9f8058d98d.debug Reading symbols from .gnu_debugdata for /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55/localhost.localdomain-2020-02-01_08.16.55-bash...(no debugging symbols found)...done. (no debugging symbols found)...done. (gdb) disass history_list Dump of assembler code for function history_list: 0x00000000000ccea0 <+0>: endbr64 0x00000000000ccea4 <+4>: mov 0x24b09d(%rip),%rax # 0x317f48 0x00000000000cceab <+11>: retq End of assembler dump. (gdb) quit [root@localhost localhost.localdomain-2020-02-01_08.16.55]# ../../volatility-master/vol.py --conf-file=volatilityrc linux_bash -H 0x317f48 Volatility Foundation Volatility Framework 2.6.1 Pid Name Command Time Command -------- -------------------- ------------------------------ ------- 13822 bash 2020-01-30 20:25:39 UTC+0000 uname -a 13822 bash 2020-01-30 20:25:39 UTC+0000 ls 13822 bash 2020-01-30 20:25:39 UTC+0000 sudo -s 13822 bash 2020-01-30 20:25:39 UTC+0000 fg [... more output not shown ...]