sábado, 9 de mayo de 2009

Análisis de un caso ¿real?, #2

Esperemos romper con el tópico de que nunca segundas partes fueron buenas ...

Parece que le estoy pillando el gusto a esto del análisis de la memoria. Y gracias que existe gente como Hogfly, el cual pone a disposición de cualquier interesado volcados de la memoria física de sistemas ejecutando malware. Así podré jugar un rato a ver si aprendo algo.

La luz que entraba por la ventana presagiaba una calurosa tarde de domingo, recién comenzado el mes de mayo. Por la habitación campaban a sus anchas varios libros marcados por la mitad, lo que confirmaba el dicho: "el que mucho abarca, poco aprieta". Completaban el cuadro varios folios con anotaciones diseminados por el escritorio y sujetos por dos/tres discos duros, una CPU descubierta enseñando sus entrañas y un monitor de 19' con el interfaz de administración de un VMWare Server.

Descargaré primero el exemplar5 desde su skydrive, 6 ficheritos en el escritorio de mi ubuntu y tenemos:

$ ll
total 94284
-rw-r--r-- 1 neofito neofito 99 2009-05-01 12:57 about.txt
-rw-r--r-- 1 neofito neofito 41943040 2009-03-20 17:08 exemplar5.tar.gz.a
-rw-r--r-- 1 neofito neofito 41943040 2009-03-20 17:11 exemplar5.tar.gz.b
-rw-r--r-- 1 neofito neofito 12377584 2009-03-20 17:12 exemplar5.tar.gz.c
-rw-r--r-- 1 neofito neofito 414 2009-03-20 17:13 hashes.txt
-rw-r--r-- 1 neofito neofito 163047 2009-03-20 17:14 virustotal_software_exe.pdf

De momento reensamblaré el paquete con el dump y luego veré que contiene el resto:
$ cat exemplar5.tar.gz.* > exemplar5.tar.gz
$ ll exemplar5.tar.gz
-rw-r--r-- 1 neofito neofito 96263664 2009-05-01 14:10 exemplar5.tar.gz
$ tar xvzf exemplar5.tar.gz
exemplar5.vmem

Ya tengo el dump de la memoria, esta vez sin duda proviene de una máquina virtual bajo vmware cuya ejecución debió detenerse para congelar el estado del sistema. Comprobaré que no esté corrupto utilizando los hashes publicados:
$ grep "(exemplar5.vmem)" hashes.txt 
MD5 (exemplar5.vmem) = ecdc4abf76baac7dd3c4e4fb648bfdd1
$ md5sum -b exemplar5.vmem
ecdc4abf76baac7dd3c4e4fb648bfdd1 *exemplar5.vmem

Bueno, pues ahora solo falta algo fresquito y paciencia, mucha paciencia.

Con las manos en la masa

Vamos a ver que soy capaz de encontrar utilizando mi flamante instalación de volatility completamente tuneada:
$ cp exemplar5.vmem /usr/local/volatility/.
$ cd /usr/local/volatility

Primero comprobaré si el volcado de la memoria está soportado por volatility:
$ python volatility ident -f exemplar5.vmem
Image Name: exemplar5.vmem
Image Type: Service Pack 2
VM Type: pae
DTB: 0x7d0000
Datetime: Wed Jan 07 20:53:16 2009

Perfecto. Ahora un concienzudo listado de los procesos en ejecución:
$ python volatility psscan -f exemplar5.vmem 
No. PID PPID Time created Offset PDB Remarks
---- ------ ------ ------------------------ ---------- ---------- ----------------
1 0 0 0x00551b80 0x007d0000 Idle
2 1928 2000 Thu Jan 08 01:49:12 2009 0x01690920 0x03800220 explorer.exe
3 1232 656 Thu Jan 08 01:47:55 2009 0x016aa3c0 0x03800160 svchost.exe
4 336 984 Thu Jan 08 01:49:00 2009 0x016cf728 0x03800200 wuauclt.exe
5 1516 656 Thu Jan 08 01:47:56 2009 0x016e3020 0x038001a0 spoolsv.exe
6 668 612 Thu Jan 08 01:46:59 2009 0x016ee9a0 0x038000a0 lsass.exe
7 872 984 Thu Jan 08 01:52:23 2009 0x016f9020 0x03800140 wmiadap.exe
8 412 656 Thu Jan 08 01:49:22 2009 0x017df020 0x03800240 msiexec.exe
9 984 656 Thu Jan 08 01:47:02 2009 0x018068b0 0x03800100 svchost.exe
10 516 4 Thu Jan 08 01:46:50 2009 0x0180f600 0x03800020 smss.exe
11 888 656 Thu Jan 08 01:47:02 2009 0x0183c388 0x038000e0 svchost.exe
12 656 612 Thu Jan 08 01:46:59 2009 0x01859b38 0x03800080 services.exe
13 1048 984 Thu Jan 08 01:49:13 2009 0x018bc988 0x03800260 wscntfy.exe
14 1020 656 Thu Jan 08 01:47:02 2009 0x019db628 0x03800120 svchost.exe
15 408 656 Thu Jan 08 01:48:23 2009 0x01a3d020 0x038001e0 alg.exe
16 224 1020 Thu Jan 08 01:48:17 2009 0x01a41860 0x038001c0 wmiprvse.exe
17 1304 656 Thu Jan 08 01:47:56 2009 0x01b0cd50 0x03800180 svchost.exe
18 588 516 Thu Jan 08 01:46:56 2009 0x01b12170 0x03800040 csrss.exe
19 612 516 Thu Jan 08 01:46:56 2009 0x01b2d2d8 0x03800060 winlogon.exe
20 4 0 0x01bcc7f8 0x007d0000 System

NOTA: Se ha eliminado la columna 'Time exited' en aras de una mejor legibilidad. Contenia el valor 'Thu Jan 08 01:50:36 2009' para el procesos 'smss.exe'.

A simple vista no soy capaz de ver nada raro, probaré con los sockets abiertos:
$ python volatility connscan -f exemplar5.vmem
Local Address Remote Address Pid
------------------------- ------------------------- ------
192.168.30.128:1039 192.168.30.129:80 1980
192.168.30.128:1047 213.133.103.113:80 984
192.168.30.128:1046 72.167.232.230:80 984
192.168.30.128:1050 213.133.103.113:80 984

Según soy capaz de interpretar veo 3 conexiones abiertas por el servicio svchost y, ¿una sesión de navegación web contra un servidor de la red local?

Bueno, más tarde retomaré ese camino, de momento voy a consultar los ficheros abiertos por cada uno de los procesos ejecutándose en el sistema. Guardaré el resultado en un fichero para poder revisar su contenido más cómodamente:
$ python volatility files -f exemplar5.vmem > files.txt

Ahora toca dejarse los ojos:
$ less files.txt
...
************************************************************************
Pid: 612
...
File \WINDOWS\system32\twain32\user.ds
File \WINDOWS\system32\twain32\local.ds
...
File \WINDOWS\system32\twex.exe
...

Creo que lo he encontrado. Las entradas anteriores se corresponderían con ficheros abiertos por el proceso con PID 612, que si consultamos el listado obtenido mediante volatility sería winlogon.exe, y si hacemos una simple búsqueda en Google por twex.exe:

http://alerta-antivirus.inteco.es/virus/detalle_virus.html?cod=8588

Vale, ya sabemos qué buscar. Confirmaré la infección consultando la clave del registro winlogon, y para ello nada mejor que un combinado de volatility/regripper.

Vayamos por partes, primero obtendré la ubicación en memoria para las estructuras CMHIVE:
$ python volatility hivescan -f exemplar5.vmem
Offset (hex)
34786144 0x212cb60
35029896 0x2168388
36798472 0x2318008
52190048 0x31c5b60
61227776 0x3a64300
62263304 0x3b61008
62692192 0x3bc9b60
78032904 0x4a6b008
117499936 0x700e820
117721952 0x7044b60
118016032 0x708c820
181174280 0xacc8008
182220832 0xadc7820

Utilizaré ahora el comando hivelist para obtener las direcciones virtuales de las diferentes partes del registro cargadas en memoria:
$ python volatility hivelist -f exemplar5.vmem -o 0x212cb60
Address Name
0xe179e008 [no name]
0xe1a58b60 \Documents and Settings\foo\NTUSER.DAT
0xe1548008 [no name]
0xe1535820 \Documents and Settings\LocalService\NTUSER.DAT
0xe1095820 [no name]
0xe107e820 \Documents and Settings\NetworkService\NTUSER.DAT
0xe13a3008 \WINDOWS\system32\config\software
0xe1397300 \WINDOWS\system32\config\default
0xe13a0b60 \WINDOWS\system32\config\SECURITY
0xe1362b60 \WINDOWS\system32\config\SAM
0xe11c2008 [no name]
0xe1018388 \WINDOWS\system32\config\system
0xe1008b60 [no name]

Y por último, veamos el contenido de la clave del registro winlogon:
$ perl rip.pl -r exemplar5.vmem@0xe13a3008 -p winlogon
Launching winlogon v.20080415
Microsoft\Windows NT\CurrentVersion\Winlogon
LastWrite Time Thu Jan 8 01:50:36 2009 (UTC)
...
Shell = Explorer.exe
VmApplet = rundll32 shell32,Control_RunDLL "sysdm.cpl"
Userinit = C:\WINDOWS\system32\userinit.exe,C:\WINDOWS\system32\twex.exe,
 
Analysis Tips: The UserInit and Shell values are executed when a user logs on.

Sin duda un resultado revelador, y una clara confirmación de una infección mediante el malware Zbot.JVE.

Saltando de rama en rama

Vamos ahora con donde buscar. Si pudiese volcar el malware desde la memoria ... pero no tiene un PID asociado, ni conozco el ofset para su posición, así que no podré utilizar el comando procdump de volatility. Voy a leer un poco:

Locating Hidden Clampi DLLs (VAD-style)
Recovering CoreFlood Binaries with Volatility
Malfind Volatility Plug-In

Por lo que he entendido el bicho que busco se ha inyectado en otro proceso, y la única forma de localizarlo sería recorriendo la memoria virtual del proceso anfitrión. Una vez localizado podremos volcarlo utilizando para ello el plugin de volatility malfind.

Allá por el año 2007 B. Dolan Gavitt planteó una nueva capa de abstracción para la organización de la memoria en sistemas Windows mediante el arbol VAD, cuyos nodos se corresponderían con los diferentes rangos de direcciones asignados a un proceso. Recorriendo este "árbol" sería posible detectar dlls maliciosas inyectadas que, de otra forma, permanecerían ocultas. Parece ser que, en su momento, publicó un set de herramientas para ilustrar su método, las vadtools. Y no contento con eso, y dada su participación en el proyecto del framework volatility, adaptó esas herramientas para integrarlas en él.

Más recientemente, este mismo año pasado, Michael Hale extiende esta funcionalidad desarrollando un plugin que permite detectar ficheros "sospechosos" de forma automática y volcar su contenido directamente, valiéndose para ello del arbol vad.

Si reviso lo visto hasta el momento parece que el primer proceso susceptible de ser
analizado es winlogon.exe, con PID 612:
$ python volatility malfind -p 612 -d dump/ -f exemplar5.vmem
 
#
# winlogon.exe (Pid: 612)
#
 
+ VAD node @815af818 Start 00ae0000 End 00af6fff Tag VadS Flags 18
- Status: dumping dump//winlogon.exe.612.ae0000.exe
+ VAD node @814e83c8 Start 00fe0000 End 00feffff Tag VadS Flags 18
+ VAD node @812db7c0 Start 18ef0000 End 18ef3fff Tag VadS Flags 6
+ VAD node @813f5050 Start 29170000 End 29173fff Tag VadS Flags 6
+ VAD node @8140a108 Start 28470000 End 28473fff Tag VadS Flags 6
+ VAD node @816fa9c0 Start 3cc10000 End 3cc13fff Tag VadS Flags 6
+ VAD node @815cf710 Start 49910000 End 49913fff Tag VadS Flags 6
+ VAD node @81472760 Start 70680000 End 70683fff Tag VadS Flags 6
+ VAD node @815be4c0 Start 75fa0000 End 75fa3fff Tag VadS Flags 6
+ VAD node @8147dfa8 Start 79640000 End 79643fff Tag VadS Flags 6
+ VAD node @81290128 Start 7f2d0000 End 7f2d3fff Tag VadS Flags 6
 
Found 11 suspicious Vad entries

Con -p especifico el PID del proceso, pero si no lo incluyo se realizará el volcado de los nodos de la VAD sospechosos para todos los procesos localizados en el dump. El flag -d me permite indicar un directorio de destino para los volcados.

Analizando el resultado parece que de todos los nodos sospechosos el @815af818 es el único que contiene un ejecutable, el cual se ha volcado en un fichero con extensión .exe. El resto de nodos, incluyendo el anterior, también se han volcado, pero con extensión .dmp:
$ ll dump/winlogon.exe.612.ae0000.exe 
... 94208 2009-05-07 20:30 winlogon.exe.612.ae0000.exe
$ ll dump/winlogon.exe.1b2d2d8.00ae0000-00af6fff.dmp
... 94208 2009-05-07 20:29 winlogon.exe.1b2d2d8.00ae0000-00af6fff.dmp

Voy a jugar un rato, pero esta vez con mi Windows. ¡Gran invento éste de las máquinas virtuales! Arrancaré el sistema XP que utilizo en mi laboratorio y asi pruebo gt2. Parece que permite detectar el tipo de un fichero analizando su cabecera en lugar de confiar en su extensión:
C:\>gt2.exe winlogon.exe.1b2d2d8.00ae0000-00af6fff.dmp
gt2 0.35 (c) 1999-2006 by PHaX (philip[at]helger.com)
 
- 612\winlogon.exe.1b2d2d8.00ae0000-00af6fff.dmp (94208 bytes) - binary
 
Is a Win32 executable
Size of header 00000040h / 64
File size in header 00000490h / 1168
Entrypoint 00000040h / 64
Overlay size 00016B70h / 93040
No relocation entries
 
PE EXE at offset 00000120h / 288
Entrypoint 000049FFh / 18943
Entrypoint RVA 000055FFh
Entrypoint section .text
Calculated PE EXE size 00012800h / 75776
Calculated overlay size 00004800h / 18432
Image base 00400000h / 4194304
Required CPU type 80386
Required OS 4.00 - Win 95 or NT 4
Subsystem Windows GUI
Linker version 9.00
Stack reserve 00100000h / 1048576
Stack commit 00001000h / 4096
Heap reserve 00100000h / 1048576
Heap commit 00001000h / 4096
Flags:
Relocation info stripped from file
File is executable
Machine based on 32-bit-word architecture
 
Processed/created with:
Seems to be linked with Microsoft linker 9.0 (??)
 
- next level at 75776/00012800h for 18432/00004800h (80.44%)
 
Unknown binary file format (0x4E 0x6C 0x00 0x00)

Ahora sí parece que tenemos al bichito. Veamos que lleva dentro:


Los últimos coletazos

El bueno se Hogfly se lo ha currado y ha subido el malware a Offensive Computing, de forma que, previo registro y posterior búsqueda por software.exe, lo descargo en un zip con password 'infected':


Snapshot al canto del sistema Windows que utilizaré para las pruebas (en VMWare Server mediante Snapshot, Take Snapshot...) y autoinfección. Vamos a sacar el bichito a pasear.

Una vez confirmada la creación de las claves del registro, regmon, y del directorio oculto twain32 así como todo su contenido, filemon, reiniciaré a ver que hace.

Ok, arrancado y ejecutandose la sesion en Windows. Comprobaré los sockets abiertos:
OpenPorts - DiamondCS Console Tools (www.diamondcs.com.au)
---
SYSTEM [4]
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING
TCP 192.168.83.128:139 0.0.0.0:0 LISTENING
UDP 192.168.83.128:137 0.0.0.0:0 LISTENING
UDP 192.168.83.128:138 0.0.0.0:0 LISTENING
UDP 0.0.0.0:445 0.0.0.0:0 LISTENING
lsass.exe [488]
UDP 0.0.0.0:500 0.0.0.0:0 LISTENING
UDP 0.0.0.0:4500 0.0.0.0:0 LISTENING
svchost.exe [636]
TCP 192.168.83.128:1026 72.167.232.230:80 ESTABLISHED
...

Parece que intenta conectarse con un servidor web americano, utilizando para ello el proceso svchost. Ahora cobra sentido la conexión detectada por volatility.

Varios refrescos más tarde ...

Bueno, creo que por hoy he terminado. Lo he encontrado cargado en la memoria del proceso svchost con PID 984 y en la del proceso explorer, con PID 1928. Aunque, casi seguro que lo encontraré enganchado a alguno más. Una sesion ssh en la máquina virtual linux y una última comprobación:
$ python volatility malfind -d dump/ -f exemplar5.vmem > maldfind.cmd.txt
$ grep dumping maldfind.cmd.txt | awk '{ print $4; }' | awk -F // \
> '{ print "dump/"$2; }' | xargs ls -l
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:48 dump/alg.exe.408.7b0000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:49 dump/explorer.exe.1928.ef0000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:49 dump/msiexec.exe.412.870000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:46 dump/services.exe.656.40000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:48 dump/spoolsv.exe.1516.eb0000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:48 dump/svchost.exe.1020.ca0000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:48 dump/svchost.exe.1232.8b0000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:48 dump/svchost.exe.1304.a30000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:46 dump/svchost.exe.888.890000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:48 dump/svchost.exe.984.14a0000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:46 dump/System.4.150000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:46 dump/System.4.170000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:46 dump/System.4.400000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:46 dump/winlogon.exe.612.ae0000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:49 dump/wmiadap.exe.872.400000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:48 dump/wmiprvse.exe.224.780000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:49 dump/wscntfy.exe.1048.800000.exe
-rw-r--r-- 1 neofito neofito 94208 2009-05-08 22:48 dump/wuauclt.exe.336.1000000.exe

Sin duda hay más candidatos. Bién, pues hasta aquí soy capaz de llegar sin conocer "the ancient art of reversing". Empezaré leyendo el paper de Secure Science Corporation que seguro resulta interesante.

Casi lo olvido, recuperaré el sistema Windows al momento anterior a la infección (de nuevo en VMWare Server mediante Snapshot, Revert to snapshot).

Addendum 10/05/09:

Vaya bronca me ha echado mi compañero hilario, aka hjmf, cuando le he enviado un mail con lo que estuve haciendo ayer. Linuxero hasta la médula y de los que usan vim para programar, the "Lord of Commands", sin duda :-D

Aunque tengo que reconocer que su comando es mas 'compacto'
$ python volatility malfind -d dump/ -f exemplar5.vmem \
| sed -n 's@.*\(dump\)//\(.*\)$@\1/\2@p' | xargs ls -l

Y esto ha sido todo, en breve más, y mejor, espero.

10 comentarios:

conexioninversa dijo...

Me ha encantado,muy pero que muy bueno...

Saludos

neofito dijo...

Gracias!! Me alegro de que te haya gustado :-)

Saludos

Homo libris dijo...

Genial, como siempre.

Enhorabuena por entradas como ésta. Un saluduo.

Anónimo dijo...

Buen artículo!, He aprendido un montón leyendolo :)

Sigue así ;)

neofito dijo...

Me alegra mucho. ¡Bienvenido a estos lares!

Saludos

https://fambernad.org dijo...

Una maravilla.

inidyu dijo...

hola neofito. Estoy empezando en este mundo y no consigo los mismos datos que tu. No puedo seguir tu ejemplo porque hay resultados que difieren Hablas del proceso twex.exe. que en mi ejemplo no sale, pero sí otros dos procesos sospechosos, postcard.exe y qnx.exe. Por favor, necesito tu ayuda con urgencia. A ver si se ha modificado el archivo desde que publicaste la entrada. Si es así, me puedes ayudar, por favor?
Un saludo, gracias por tu atencion

neofito dijo...

No lo he vuelto a probar desde que lo escribí, pero en principio, y si descargaste el mismo fichero que menciono en el artículo, los resultados deberían ser similares.

A ver si consigo sacar un rato y puedo revisarlo.

Saludos

Anónimo dijo...

Te lo agradeceré en el alma. Seguro que he hecho algo "no del todo bien", pero no veo que puede ser.

Un saludo

neofito dijo...

Si comparas el md5 correspondiente al volcado de memoria en el fichero hashes.txt disponible online con el que calculo al principio del artículo salta a la vista que no son el mismo, por lo que es normal que te salgan cosas distintas.

Si tienes alguna duda concreta y crees que puedo serte de ayuda añádele un gmail.com a mi nick y me mandas un correo electrónico.

Saludos