martes, 4 de mayo de 2010

Otro análisis más (y van 4) - Parte II

Continuando con el análisis de la imagen proporcionada como base para el Honeynet Forensic Challenge 2010/3, que iniciamos en la entrada anterior, comenzamos el segundo round.

Y fué la duda y la sospecha el día segundo

Según el documento de S21Sec, "Detectando un ZeuS", uno de los muchos síntomas de infeccion consistiría en la existencia de determinados mutex en el sistema. Se trata de un tipo especial de objetos que proporcionan un acceso exclusivo a un determinado recurso por parte del creador del mutex; en este caso servirían para impedir un intento de reinfección si se detecta que el sistema ya está infectado. El siguiente comando confirma este punto:

# python volatility mutantscan -f Bob.vmem | grep "_AVIRA_210[8|9]"
0x01ed9050 0x823c55e0 2 1 1 0x00000000 _AVIRA_2108
0x02424630 0x823c55e0 2 1 1 0x00000000 _AVIRA_2109

Seguimos con los síntomas y para ello comprobaremos si existen hooks en determinadas funciones, concretamente:
  • En ntdll.dll serían NtCreateThread, LdrLoadDll, LdrGetProcedureAddress y NtQueryDirectoryFile.
  • En user32.dll serían GetClipboardData y TranslateMessage.

Utilizaremos para ello el plugin apihooks de Michael Hale Ligh, el cual forma parte del paquete "Volatility Analyst Pack". Derivaremos la salida a un fichero de texto que analizaremos después, capturando los procesos que tengan hookeadas las funciones de ntdll.dll y user32.dll indicadas anteriormente:
# python volatility apihooks -f Bob.vmem -d apihooksdump/ | grep -v Memory > out.apihooks.txt
# awk '$5 ~ /(NtCreateThread|LdrLoadDll|LdrGetProcedureAddress|NtQueryDirectoryFile \
> |GetClipboardData|TranslateMessage)$/ {printf "%4s\t%s\n",$3,$2}' out.apihooks.txt | sort -u
1040 svchost.exe
1244 svchost.exe
1384 svchost.exe
1752 AcroRd32.exe
1756 explorer.exe
2024 alg.exe
688 services.exe
700 lsass.exe
880 svchost.exe
948 svchost.exe

Que chula me ha quedado la salida :), I love bash!!

Si seguimos buscando información sobre ZeuS aprenderemos mucho sobre su modus operandi, por ejemplo aquí. En el documento mencionan como el primer proceso del sistema en el que trata de inyectarse no es otro que winlogon (pid 644 en nuestro caso):
# python volatility files -p 644 -f Bob.vmem | grep 'sdra64\|lowsec'
File \WINDOWS\system32\sdra64.exe
File \WINDOWS\system32\lowsec\user.ds
File \WINDOWS\system32\lowsec\local.ds

Así que veamos si encontramos el proceso inyectado utilizando el plugin malfind2, de Michael Hale Ligh y en el "Volatility Analyst Pack":
# python volatility malfind2 -d winlogon_dump -p 644 -f Bob.vmem
 
######################### Malfind Report #########################
 
#
# winlogon.exe (Pid: 644)
#
 
[!] Range: 0x00a10000 - 0x00a2cfff (Tag: VadS, Protection: 0x6)
Dumping to winlogon_dump/malfind.644.a10000-a2cfff.dmp
PE sections: [.text, .data, .reloc, .data1, ]
 
[!] Range: 0x24990000 - 0x24993fff (Tag: VadS, Protection: 0x6)
Dumping to winlogon_dump/malfind.644.24990000-24993fff.dmp
Hexdump:
0x24990000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x24990010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 
Disassembly:
0x24990000 add [eax],al
0x24990002 add [eax],al
0x24990004 add [eax],al
0x24990006 add [eax],al
0x24990008 add [eax],al
0x2499000a add [eax],al
0x2499000c add [eax],al
0x2499000e add [eax],al
0x24990010 add [eax],al
0x24990012 add [eax],al
0x24990014 add [eax],al
0x24990016 add [eax],al
0x24990018 add [eax],al
0x2499001a add [eax],al
0x2499001c add [eax],al
0x2499001e add [eax],al
 
[!] Range: 0x42e60000 - 0x42e63fff (Tag: VadS, Protection: 0x6)
Dumping to winlogon_dump/malfind.644.42e60000-42e63fff.dmp
Hexdump:
0x42e60000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x42e60010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 
Disassembly:
0x42e60000 add [eax],al
0x42e60002 add [eax],al
0x42e60004 add [eax],al
0x42e60006 add [eax],al
0x42e60008 add [eax],al
0x42e6000a add [eax],al
0x42e6000c add [eax],al
0x42e6000e add [eax],al
0x42e60010 add [eax],al
0x42e60012 add [eax],al
0x42e60014 add [eax],al
0x42e60016 add [eax],al
0x42e60018 add [eax],al
0x42e6001a add [eax],al
0x42e6001c add [eax],al
0x42e6001e add [eax],al
 
[!] Range: 0x26200000 - 0x26203fff (Tag: VadS, Protection: 0x6)
Dumping to winlogon_dump/malfind.644.26200000-26203fff.dmp
Hexdump:
0x26200000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x26200010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 
Disassembly:
0x26200000 add [eax],al
0x26200002 add [eax],al
0x26200004 add [eax],al
0x26200006 add [eax],al
0x26200008 add [eax],al
0x2620000a add [eax],al
0x2620000c add [eax],al
0x2620000e add [eax],al
0x26200010 add [eax],al
0x26200012 add [eax],al
0x26200014 add [eax],al
0x26200016 add [eax],al
0x26200018 add [eax],al
0x2620001a add [eax],al
0x2620001c add [eax],al
0x2620001e add [eax],al
 
[!] Range: 0x7a330000 - 0x7a333fff (Tag: VadS, Protection: 0x6)
Dumping to winlogon_dump/malfind.644.7a330000-7a333fff.dmp
Hexdump:
0x7a330000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x7a330010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 
Disassembly:
0x7a330000 add [eax],al
0x7a330002 add [eax],al
0x7a330004 add [eax],al
0x7a330006 add [eax],al
0x7a330008 add [eax],al
0x7a33000a add [eax],al
0x7a33000c add [eax],al
0x7a33000e add [eax],al
0x7a330010 add [eax],al
0x7a330012 add [eax],al
0x7a330014 add [eax],al
0x7a330016 add [eax],al
0x7a330018 add [eax],al
0x7a33001a add [eax],al
0x7a33001c add [eax],al
0x7a33001e add [eax],al
 
[!] Range: 0x7fc00000 - 0x7fc03fff (Tag: VadS, Protection: 0x6)
Dumping to winlogon_dump/malfind.644.7fc00000-7fc03fff.dmp
Hexdump:
0x7fc00000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x7fc00010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 
Disassembly:
0x7fc00000 add [eax],al
0x7fc00002 add [eax],al
0x7fc00004 add [eax],al
0x7fc00006 add [eax],al
0x7fc00008 add [eax],al
0x7fc0000a add [eax],al
0x7fc0000c add [eax],al
0x7fc0000e add [eax],al
0x7fc00010 add [eax],al
0x7fc00012 add [eax],al
0x7fc00014 add [eax],al
0x7fc00016 add [eax],al
0x7fc00018 add [eax],al
0x7fc0001a add [eax],al
0x7fc0001c add [eax],al
0x7fc0001e add [eax],al

De todos los ficheros obtenidos solo nos interesan los que, al menos, parezcan ejecutables:
# file winlogon_dump/*
winlogon_dump/malfind.644.24990000-24993fff.dmp: data
winlogon_dump/malfind.644.26200000-26203fff.dmp: data
winlogon_dump/malfind.644.42e60000-42e63fff.dmp: data
winlogon_dump/malfind.644.7a330000-7a333fff.dmp: data
winlogon_dump/malfind.644.7fc00000-7fc03fff.dmp: data
winlogon_dump/malfind.644.a10000-a2cfff.dmp: PE32 executable for MS Windows (GUI) Intel 80386 32-bit

Si subimos el fichero sospechoso a virustotal obtenemos el siguiente resultado.

Posteriormente parece ser que también trata de inyectarse en el proceso svchost con el pid más bajo (880 en nuestro caso) a través del cual se descarga un fichero de configuración cifrado:
# python volatility files -p 880 -f /usr/local/forensics/img/honeynet3/Bob.vmem | grep lowsec
File \WINDOWS\system32\lowsec\user.ds.lll

Ésta confirmación también nos ayuda a entender mejor la referencia sospechosa de la timeline que obtuvimos en la entrada anterior. Parece que poco a poco van encajando las piezas.

Si seguimos probando con el plugin malfind2 para el resto de procesos del sistema encontraremos siempre un fichero inyectado con el mismo tamaño (unos 116K), excepto para System (pid: 4), smss.exe (pid: 548) y csrss.exe (pid: 612); resultará mucho más fácil entenderlo si obtenemos el árbol genealógico de los procesos:
# python volatility psscan2 -d -f Bob.vmem | dot -Tpng -o procesos.png

y el resultado:


In-memory carving

Tenemos al malo, el troyano bancario zbot, el bueno que somos nosotros, el móvil la pasta, como casi siempre, y solo nos falta el cuerpo del delito. Si releemos con atención el resumen de los acontecimientos:

"One of their employees had received an email from a fellow co-worker that pointed to a PDF file. Upon opening, the employee did not seem to notice anything, however recently they have had unusual activity in their bank account."

Asi que necesitamos el maldito PDF, porque no podemos analizar lo que ni siquiera podemos tocar.

Seguro que nos resultará familiar el término file carving. De forma resumida y poco ortodoxa, el proceso consistiría en excarvar a bajo nivel un área de datos en busca de ficheros, utilizando para ello características propias de los mismos. Por bajo nivel quiero decir que no se confía en estructuras complejas, como podrían ser el sistema de ficheros subyacente, analizándose directamente los datos en crudo. Como características usaríamos las cabeceras o headers de los ficheros, los pies o footers o una combinación de ambos, entendiendo estos como secuencias de bytes concretas y predefinidas que servirían para acotar un determinado tipo de fichero. Algunos ejemplos típicos de cabeceras: 'MZ' para binarios de Windows, 'GIF87a' o 'GIF89a' para gif, etc.

Asimilado el concepto, ¿por qué no aplicarlo a un volcado de la memoria de un sistema? O mejor aún, ¿por qué no aplicarlo a una determinada porción de ese volcado que se correspondería con el área de la memoria perteneciente a un determinado proceso?

Sabiendo que el PID para el proceso de Acrobat Reader es 1752 utilizaremos foremost:
# python volatility memdmp -p 1752 -f Bob.vmem
# foremost -t pdf -i 1752.dmp
Processing: 1752.dmp
|****|
# ll output/pdf/
total 684
-rw-r--r-- 1 root root 419 2010-04-30 21:39 00445397.pdf
-rw-r--r-- 1 root root 419 2010-04-30 21:39 00446730.pdf
-rw-r--r-- 1 root root 425 2010-04-30 21:39 00578749.pdf
-rw-r--r-- 1 root root 425 2010-04-30 21:39 00583952.pdf
-rw-r--r-- 1 root root 425 2010-04-30 21:39 00599312.pdf
-rw-r--r-- 1 root root 60124 2010-04-30 21:39 00599696.pdf
-rw-r--r-- 1 root root 607083 2010-04-30 21:39 00600328.pdf

Analizaremos de forma automatizada el contenido de cada uno de los ficheros anteriores sin necesidad de abrirlos, evitándonos así posibles "problemas" derivados de un exceso de confianza. Para ello utilizaremos el comando pdfid, que forma parte del paquete PDF Tools desarrollado por Didier Stevens y actualizado hace muy poco para detectar el uso de la acción /Launch utilizada para ejecutar "algo" de forma automática al abrir un documento PDF.

Como resultado del uso de esta herramienta localizamos un fichero cifrado:
# python pdfid.py 00599696.pdf
PDFiD 0.0.11 00599696.pdf
PDF Header: %PDF-1.4
obj 104
endobj 104
stream 34
endstream 34
xref 2
trailer 2
startxref 2
/Page 8
/Encrypt 1
/ObjStm 0
/JS 0
/JavaScript 0
/AA 0
/OpenAction 0
/AcroForm 0
/JBIG2Decode 0
/RichMedia 0
/Launch 0
/Colors > 2^24 0

y otro fichero muy sospechoso:
# python pdfid.py 00600328.pdf
PDFiD 0.0.11 00600328.pdf
PDF Header: %PDF-1.3
obj 6
endobj 6
stream 1
endstream 1
xref 2
trailer 2
startxref 1
/Page 1
/Encrypt 0
/ObjStm 0
/JS 1
/JavaScript 1
/AA 1
/OpenAction 0
/AcroForm 0
/JBIG2Decode 0
/RichMedia 0
/Launch 0
/Colors > 2^24 0

¿por qué? Contiene código javascript (etiquetas /JS y /JavaScript) y ejecuta algo de forma automatizada al abrir el documento (etiqueta /AA).

Pero mejor seguimos otro día ;)

2 comentarios:

conexioninversa dijo...

Muy bien currado...Como siempre eres un crack tío!!!

neofito dijo...

Gracias!!