DEFCON 2018 DFIR CTF – Reto forense (Intro + Nivel 1)

Comentaban unos alumnos del curso de análisis forense hace unas cuantas semanas la dificultad de conseguir experiencia en forense y respuesta ante incidentes, no sin parte de razón. En muchas ocasiones yo comparo, salvando las obvias distancias, el trabajo de DFIR (Digital Forensics and Incident Response) con el de un bombero: gran parte del tiempo de relajación mezclado con una pequeña parte de tiempo de intensidad y stress máximos.

Aquí estamos, sin embargo, no siendo del todo exactos: ¿qué hacen los bomberos cuando no se deslizan por el tubo y salen corriendo a salvar gente? La respuesta es muy sencilla: ENTRENAN.

En el mundo DFIR el entrenamiento es fundamental, ya que en muy pocos trabajos se está el 100% del tiempo “en harina” (hay que tener en cuenta que estar en un incidente a máxima capacidad de trabajo durante un periodo largo de tiempo cuesta, y mucho). El entrenamiento, además, permite detectar carencias y áreas de mejora, así como afianzar conceptos y aprender nuevas formas de hacer las cosas.

Una forma sencilla de entrenarse en DFIR es jugando retos forenses (tenéis una buena pila en http://aboutdfir.com/challenges-ctfs/). Aprovechando que tenía un fin de semana entero disponible, decidí sacar del cajón de retos; uno al que le tenía echado el ojo desde hace un par de meses: el reto DFIR de la DEFCON 2018.

El reto consta de tres imágenes de equipos, cada uno con tres niveles de preguntas (básico, avanzado y experto). Aquí tenéis los datos básicos por si queréis jugarlo:

A lo largo de tres artículos vamos a ir contando mi solución al reto. En algunos casos existen varias formas de resolver las preguntas, así que siéntete libre de aportar tu visión en los comentarios ¡Vamos al lío!

Servidor de RRHH – Nivel básico

1. ¿Qué software se empleó para crear la imagen del servidor de RRHH?

Dos pulgares oponibles, saber leer y abrir un fichero comprimido nos dan la respuesta. Dentro del .zip nos encontramos con el fichero HRServer_Disk0.txt, en el que podemos leer tal cual la respuesta:

* Respuesta: X-Ways Forensics

2. ¿Qué versión de software ha sido usada para crear la imagen del servidor de RRHH? (Respuesta en formato n:n)

Sí que llevan tiempo en el tema del forense estos de X-Ways que les ha dado para hacer una pila de versiones…

* Respuesta: 19.6

3. ¿Cuál es el nombre de fichero de la entrada de la MFT 168043?

Empezamos a meternos un poco en harina. La extensión .e01 parece indicar que estamos en una imagen en formato de Encase, así que vamos a tirar de FTK Imager para montarlo en nuestro Windows.

Una vez montado podemos acceder a la carpeta [root] donde encontraremos el sistema de ficheros, y copiamos el fichero $MFT que contiene (oh, sorpresa) la MFT (Master File Table, una especie de índice de todos los ficheros del disco duro).

La MFT está en formato binario, así que tenemos que parsearla a un formato más comprensible, algo que podemos hacer con la herramienta mftdump.exe.

Como nos piden un dato muy concreto, podemos tirar de grep (sí, hay Powershell en Linux, y grep en Windows. Corren tiempos extraños, gente) para sacar el flag.

* Respuesta: pip3.7.exe

4. ¿Cuál es el número de la entrada de la MFT del fichero: \xampp\mysql\bin\mysql.exe [respuesta en formato de entero]

Grep sigue siendo nuestro amigo. Sin embargo, la salida es un poco confusa:

La forma más sencilla de tener la respuesta es volcar la salida del grep a un .csv y abrirlo con LibreOffice, donde las cosas se ven mucho más claras.

* Respuesta: 115322

5. ¿Cuál es el Attibute ID de la MFT del atributo de datos $J para la entrada de la MFT con el nombre de fichero $UsnJrnl?

Me niego a meterme en semejante berenjenal por tan solo 2 puntos. Cuando termine con todas las preguntas “del rosco” (que son 63, ojo al dato), si me apetece vuelvo.

[UPDATE: No, no me ha apetecido volver xDDDD]

[UPDATE: Mierda, es la única pregunta que me falta para completar el reto y ya que hemos llegado hasta aquí, vamos a terminar el reto joer]

Después de investigar un rato sobre la estructura interna de NTFS (yuhu), descubrimos que Sleuth Kit es maravilloso ya que te muestra el Attribute ID como parte de su salida:

Según fls, los tres valores se interpretan de esta forma: ADDR-TYPE-ID.

  • ADDR is the metadata address,
  • TYPE is the attribute type
  • ID is the attribute id

¿Has visto qué 3 tannnn bonito? Son solo dos puntos pero saben a gloria …

* Respuesta: 3

6. ¿Cuál era la dirección IP del cliente que intentó acceder a través de SMB mediante un anonymous logon a las 2018-08-08 18:10:38.554(UTC)?

Esa información debería residir en un log de eventos del sistema, así que nos vamos a la carpeta de logs de Windows (C:\Windows\system32\winevt\logs). Ahí encontramos una buena pila de logs, pero uno que nos suena interesante:

Podemos abrir el fichero con el Visor de Eventos de nuestro equipo sin problemas, pero cuando buscamos la fecha exacta, no encontramos un mojón ¿Qué es lo que está pasando? Que estamos buscando en el sitio oportuno… pero no en el momento adecuado.

El Visor de Eventos de Windows muestra siempre los logs en la Timezone del equipo (en nuestro caso, España peninsular). Pero vete tú a saber dónde estaba el que hizo el reto cuando se puso a ello, así que se lo vamos a tener que preguntar al registro de Windows (situado en C:\Windows\system32\config). La clave que guarda la timezone es:

por lo que podemos abrir el SYSTEM con Registry Explorer y obtener la timezone, que en este caso es Pacific Standard Time (UTC-8).

Pero como es viernes y no me apetece trabajar, no me estoy leyendo bien la pregunta: te están especificando el acceso YA en UTC, por lo que únicamente tendríamos que sumar una hora y buscar por las 19:10:38…. pero no hay nada. Dándole una vuelta más nos damos cuenta de que, aunque el reto lo estemos haciendo en Noviembre, se publicó en Agosto, lo que significa una cosa: horario de verano, en el que España hay una hora más, lo que significa que estamos en UTC+2.

Está claro que toca abrir una cerveza para despejarnos. Buscamos en nuestro Visor de Eventos a las 20:10:38 y ahí tenemos nuestro evento:

* Respuesta: 80.81.110.50

7. ¿Qué nombre tiene el fichero .bat guardado por el usuario mpowers? [la respuesta es el path completo empezando por c:****]

Ya que tenemos la MFT, vamos a lanzar un grep en busca de los ficheros de mpowers que terminen en .bat. Algo tan simple como:

grep mpowers mft_parseada.csv |grep bat

nos devuelve un resultado igual de simple: cero. Vamos a tener que currárnoslo un poco más. Si buscamos únicamente por los .bat nos encontramos con que tenemos 174 resultados, así que vamos a tener que afinar un poco más.

Una vía alternativa es la de buscar los últimos documentos abiertos por el usuario mpowers, información que se guarda en los MRU (Most Recent Used) y que en el disco está en el fichero NTUSER.dat, localizado en el directorio raíz del usuario.

En este caso podemos usar RegRipper con el plugin runmru… pero no nos da resultados (raro raro). Podemos sin embargo buscar la información tirando de los UserAssist, que guardan las últimas aplicaciones, accesos directos y documentos abiertos por el usuario. Un poquito de grep y… ¡bingo!

* Respuesta: C:\Production\update_app.bat

8. ¿Cuál es el nombre de la aplicación de gestión de RRHH que tiene un servidor web?

Antes hemos visto un xampp en C:\ (xampp es un conocido combo de Apache+MySQL+PHP+Perl open source que funciona estupendamente bajo Windows), así que vamos a ver si tenemos algo en la configuración de Apache. No tenemos suerte, así que vamos a buscar qué programas tenemos instalados en el equipo.

Para ello visitamos tanto “C:\Archivos de Programa” como “Program Files (x86)”, y lo único que destaca es el OrangeHRM. Ahora que lo pensamos, si estamos en el servidor de Recursos Humanos, tiene su lógica encontrar un HRM (Human Resources Management). Tantos años en el mundo TIC te dan canas, experiencia y la capacidad de adivinar ATL (Acrónimos de Tres Letras) al vuelo. Si abrimos la carpeta comprobamos que tiene dentro otro xampp, lo que nos da la respuesta que queremos.

* Respuesta: OrangeHRM

9. ¿Cuál es la URL pública para el portal de RRHH? [formato: http://****]

Si tenemos un Apache soportando la aplicación, lo lógico es que estuviera en el httpd.conf, situado en xampp\apache\conf. Ahí tenemos como valor una IP… que no es el correcto. Buscamos en toda la carpeta por si tenemos otros valores de configuración, y encontramos un orangehrm.localhost en el fichero orangehrlm-4.1\symfony\config\vhost.sample, que tampoco es válido.

Después de un par de intentos queda claro que lo que quieren no es el servername (lee bien la maldita pregunta, Antonio) sino la URL real sobre la que se accede, que será la IP + el resto de la URI. Nos toca tirarnos a los logs y ver qué podemos sacar en claro. Un poquito de observación permite identificar que hay peticiones que siempre redirigen a una URL, que además es la de login:

Sumando ambos valores obtenemos la respuesta.

* Respuesta: http://74.118.139.108/orangehrm-4.1/symfony/web/index.php/auth/login

10. ¿Cuál es el nombre del fichero que tuvo un cambio guardado con un USN (Updated Sequence Number) de 368701440?

Los cambios en ficheros se quedan guardados en el USN Journal (Update Sequence Number Journal), que guarda un log de los cambios que se hacen en un volumen NTFS. En nuestro caso lo tenemos en C:\$Extend\$UsrJrnl, del que podemos extraer el log con FTK Imager:

Este journal lo podemos parsear con la herramienta NTFS Log Tracker (y puedes encontrar más info sobre el forense de $UsnJrnl en esta presentación), obteniendo nuestra respuesta.

* Respuesta: Microsoft-Windows-SMBServer%4Security.evtx

11. ¿Cuál es el nombre del fichero borrado con un reference number de 12947848928752043?

Esta pregunta te deja así como torcido, pero la experiencia te enseña que “no hay que saberlo todo, solo hay que saber dónde encontrarlo”, así que tiro del libro “Filesystem Forensics Analysis”… pero solo nos dice que el número de referencia pertenece a cada fichero de la MFT, nada de cómo calcularlo.

Por lo menos nos sirve para acotar la búsqueda en Google, ya que encontramos este breve pero ilustrativo artículo: https://jmharkness.wordpress.com/2011/01/27/mft-file-reference-number/

Al parecer todas las entradas de la MFT tienen un reference number, compuesto por el número de la entrada MFT (6 bytes) y el número de secuencia (2 bytes) en hexadecimal.

Usando un convertidor online de entero a hexadecimal obtenemos el valor:

12947848928752043 (int)  --> 2E00000000F1AB (hex)

Como el valor son 8 bytes, tenemos que añadir un 0x00 al valor: 0x002E00000000F1AB, que ya podemos dividir en sus dos partes:

Entrada MFT: 00000000F1AB
Número de secuencia: 0x002E

Con el convertidor anterior pasamos de hexadecimal a entero, obteniendo el valor 61867 que corresponde a la entrada de la MFT, que ya tenemos de preguntas anteriores.

* Respuesta: _MEI78882

Servidor de RRHH – Nivel avanzado

12. Qué usuario inició sesión en el equipo a las 2018-07-30 22:31:33 UTC, qué tipo de inicio de sesión usó, y cuál es el nombre del proceso empleado? [formato: {TargetUserName} – {LogonType} – {LogonProcessName} – {IpAddress}]

Esta pregunta está chupada, porque es justo la información que tendría que estar en el log de Security de Windows (recuerda que toca mirar 2h más tarde). Por desgracia el log ha sido deleznablemente borrado por los atacantes el 8 de Julio (eliminando los registros anteriores) así que no podemos obtener fácilmente esa información. Y tiene que estar ahí porque por lo que solicitan es el único lugar del que se puede obtener con esos campos.

La teoría es que el atacante puede haber entrado en el equipo y luego borrado los logs. Si tuviéramos una máquina del tiempo lo podríamos resolver con facilidad, pero el Delorean está en el taller, así que poco podemos hacer.

Si existiera alguna forma de que Windows de vez en cuando guardara una copia de los ficheros que nos interesaran cada vez que se hiciera algo y los copiara en un lugar fresquito y seco, bien a la sombra por si acaso nos hiciera falta recuperarlos… estás pensando lo mismo que yo, ¿verdad? Las shadow copies nos van a dar la respuesta.

Comenzamos arrancando nuestro fiel SIFT y copiando la imagen en un .e01. Con mmls identificamos el inicio de la partición y con ewfmount montamos la imagen en raw.

SIFT viene con varias utilidades para trabajar con shadow copies, de las que nos interesan vshadowinfo y vshadowmount (para obtener información y montar shadow copies respectivamente). Empezamos por ver si tenemos shadow copies en el equipo con vshadowinfo (recordad que hay que poner el offset del inicio de partición, 1026048*512 = 525336576):

Tenemos una copia, así que podemos montarla con vshadowmount y extraer el event log de Security sin problemas:

Si recuperamos el fichero comprobamos con alegría que tenemos los resultados en la hora indicada (recuerda que el Visor de Eventos está en hora local):

El evento se ve un poco descarajado porque nos falta información para presentarlo correctamente (posiblemente porque el equipo origen esté en inglés). Sin embargo, si nos quedamos con los detalles del evento lo veremos mucho más claro:

Referencias:

* Respuesta: mpowers – 10 – User32 – 74.118.138.195

13. ¿Qué tarea se inició a las 2018-07-27 02:42:43 (UTC)?

Después de la currada de la pregunta anterior, esta supone un respiro. La ejecución de una tarea programada deja un registro en el log de eventos, en el Task Scheduler. Tan simple como abrirlo en el Visor de Eventos (recuerda que estamos en UTC+2) y localizar la fecha y hora concretas:

* Respuesta: “Throw Taco”

14. ¿Qué dirección IP estuvo accediendo al portal de OrangeHRM usando 68.0.3440.84?

Tenemos los logs localizados gracias a una pregunta anterior, así que es cuestión de tirar de nuevo de grep:

grep 68.0.3440.84 logs\* > chrome.csv

*Respuesta: 74.118.139.108

15. ¿Qué version de Apache se está usando? [format: n.n]5

Tenemos el Apache en la carpeta C:\Archivos de Programa\OrangeHRM\4.1\apache, así que es cuestión de buscar la versión. Pero es tarde y estoy vago, así que puedo permitirme el lujo de subir el httpd.exe a VirusTotal y que me diga la versión (niños, niñas, recordad: nunca hagáis esto con vuestras muestras de APT).

Bueno, venga, por vergüenza torera vamos a buscarlo como $deity manda. En 2 min de rebuscar encontramos el CHANGES.txt que nos muestra el changelog de Apache, y lo primero que indica es la versión actual.

* Respuesta: 2.4

16. ¿Cuál es el valor entero del reason code que ofrece un registro USN v2 cuando los flags del registro tienen los siguientes motivos: USN_REASON_CLOSE | USN_REASON_DATA_EXTEND | USN_REASON_FILE_CREATE?

Aquí el reto nos tiende una emboscada con otra pregunta árida de teoría. Bueno, no estamos en un examen, así que podemos hacer una búsqueda rápida de Google y aprender un poco de paso. Aquí tenéis un documento estupendo en el que cuentan más acerca de la estructura del USN_JOURNAL_DATA:

https://msdn.microsoft.com/en-us/library/windows/desktop/hh802706(v=vs.85).aspx

Los flags de un registro de USN se acumulan para crear una máscara, por lo que tenemos:

USN_REASON_CLOSE = 0x80000000
USN_REASON_DATA_EXTEND = 0x00000002
USN_REASON_FILE_CREATE = 0x00000100
Total: 0x80000102

Lo convertimos de hexadecimal a entero con un convertidor online: y listo para responder.

* Respuesta: 2147483906

Servidor de RRHH – Nivel experto

17. ¿Qué dirección IP se comunicó en más ocasiones con el servidor web?

Con los logs de Apache localizados, cuesta más arrancar de nuevo la VM de SIFT que responder a la pregunta:

$ cut -d" " -f1 /media/sansforensics/7C4604634604208E/access.log |sort |uniq -c |sort -nr|less

* Respuesta: 74.118.138.195

18. ¿Cuántas peticiones HTTP se hicieron al servidor web en las que la URL solicitada contenía un comando de wget embebido?

Si me dieran un € por cada vez que he tirado un cut/grep/awk…

$ grep wget  /media/sansforensics/7C4604634604208E/access.log |wc

* Respuesta: 101

Ya es la una y pico de la mañana, pero hemos cumplido el objetivo de un nivel al día. Al catre a descansar las neuronas, que al día siguiente toca el nivel 2…