> For the complete documentation index, see [llms.txt](https://hacking-3.gitbook.io/barre/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-3.gitbook.io/barre/write-up/forense/gotham-hustle.md).

# Gotham Hustle

<figure><img src="/files/Ue6MqXccZLFUeDivNIxK" alt=""><figcaption></figcaption></figure>

{% embed url="<https://github.com/Azr43lKn1ght/DFIR-LABS/tree/main/Gotham%20Hustle>" %}

> **Challenge Description:** Gotham’s underbelly trembles as whispers spread—The Riddler’s back, leaving cryptic puzzles across the city’s darkest corners. Every clue is a trap, every answer another step into madness. Think you can outsmart him? Step into Gotham’s shadows and prove it. Let the Batman's Hustle get its recognition!

***

## 1. Identificación del Sistema (`imageinfo`)

El primer paso en cualquier análisis de memoria con Volatility es identificar el perfil correcto del sistema operativo. Esto nos da una visión más clara del activo que vamos a analizar y define cómo Volatility interpretará las estructuras de memoria crudas.

```bash
vol2 -f gotham.raw imageinfo
```

```bash
INFO    : volatility.debug    : Determining profile based on KDBG search...
          Suggested Profile(s) : Win7SP1x64, Win7SP0x64, Win2008R2SP0x64, Win2008R2SP1x64_24000, Win2008R2SP1x64_23418, Win2008R2SP1x64, Win7SP1x64_24000, Win7SP1x64_23418
                     AS Layer1 : WindowsAMD64PagedMemory (Kernel AS)
                     AS Layer2 : FileAddressSpace (/home/barre/Labs/forensic/gotham/gotham.raw)
                      PAE type : No PAE
                           DTB : 0x187000L
                          KDBG : 0xf80002a48120L
          Number of Processors : 6
     Image Type (Service Pack) : 1
                KPCR for CPU 0 : 0xfffff80002a4a000L
                KPCR for CPU 1 : 0xfffff880009ea000L
                KPCR for CPU 2 : 0xfffff88002ea8000L
                KPCR for CPU 3 : 0xfffff88002f24000L
                KPCR for CPU 4 : 0xfffff88002fa0000L
                KPCR for CPU 5 : 0xfffff88002fdc000L
             KUSER_SHARED_DATA : 0xfffff78000000000L
           Image date and time : 2024-08-06 18:37:19 UTC+0000
     Image local date and time : 2024-08-06 11:37:19 -0700
```

El comando escanea los bloques KDBG del kernel para identificar la arquitectura y versión del sistema operativo. Utilizaremos el perfil sugerido `Win7SP1x64` para el resto de la investigación, ya que es la coincidencia más probable.

## 2. Mapeo de Procesos

Una vez identificado el sistema, se procede a evaluar el estado general de la máquina en el momento de la captura: necesitamos saber qué se estaba ejecutando.

### Listado de procesos (`pslist`)

Con esto ya podemos ver qué procesos estaban abiertos en el momento exacto en el que se realizó el volcado (DUMP) de memoria.

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 pslist
```

```bash
Offset(V)          Name                    PID   PPID   Thds     Hnds   Sess  Wow64 Start                          Exit                          
------------------ -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------
[... Procesos del sistema cortados por brevedad visual en este bloque ...]
0xfffffa80044c3b00 chrome.exe             4456   4464     32     1296      1      0 2024-08-06 16:36:45 UTC+0000                                 
0xfffffa8004403b00 cmd.exe                3944   1172      1       20      1      0 2024-08-06 16:45:56 UTC+0000                                 
0xfffffa8003c9c4f0 notepad.exe            2592   1172      1       58      1      0 2024-08-06 16:47:20 UTC+0000                                 
0xfffffa80039c2490 mspaint.exe            2516   1172      7      142      1      0 2024-08-06 18:35:09 UTC+0000                                 
0xfffffa8003bcf420 DumpItog.exe           4960   1172      5       56      1      1 2024-08-06 18:37:17 UTC+0000
```

### Árbol de procesos (`pstree`)

Con esto tenemos una visión más clara de la jerarquía de los procesos, lo que ayuda a identificar ejecuciones anómalas (por ejemplo, un proceso padre sospechoso lanzando herramientas del sistema).

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 pstree
```

```bash
Name                                                  Pid   PPid   Thds   Hnds Time
-------------------------------------------------- ------ ------ ------ ------ ----
0xfffffa8006bbeb00:explorer.exe                     1172   2024     32   1017 2024-08-06 15:49:58 UTC+0000
. 0xfffffa8003c9c4f0:notepad.exe                     2592   1172      1     58 2024-08-06 16:47:20 UTC+0000
. 0xfffffa80039c2490:mspaint.exe                     2516   1172      7    142 2024-08-06 18:35:09 UTC+0000
. 0xfffffa8004403b00:cmd.exe                         3944   1172      1     20 2024-08-06 16:45:56 UTC+0000
. 0xfffffa8003bcf420:DumpItog.exe                    4960   1172      5     56 2024-08-06 18:37:17 UTC+0000
0xfffffa80044c3b00:chrome.exe                       4456   4464     32   1296 2024-08-06 16:36:45 UTC+0000
```

`pstree` permite observar que herramientas de usuario final como Chrome, Notepad, Paint y CMD dependen del proceso `explorer.exe` (PID 1172). Esto marca estos procesos interactivos como nuestros principales puntos de interés.

## 3. Análisis de Línea de Comandos (`consoles`)

El plugin `consoles` reconstruye el texto impreso en las ventanas de comandos y los inputs del usuario. Descubrimos una serie de comandos ejecutados y una cadena de texto codificada interesante.

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 consoles
```

```bash
Cmd #0 at 0x12f7c0: whoami
Cmd #1 at 0x130110: dir
Cmd #2 at 0x12f800: bi0s
Cmd #3 at 0x12f820: dfirlabs
Cmd #4 at 0x12d690: Ymkwc2N0Znt3M2xjMG0zXw==
Cmd #5 at 0x12d6d0: azr43ln1ght.github.io
Cmd #6 at 0x125650: Azr43lKn1ght
Cmd #7 at 0x125680: did you find flag1?
```

Vemos claramente que el usuario introdujo comandos de reconocimiento y algunas cadenas. La cadena `Ymkwc2N0Znt3M2xjMG0zXw==` nos llama la atención. Cualquier cadena que termine en `==` suele estar codificada en Base64.

Si la decodificamos, obtenemos la Flag 1:

```bash
echo "Ymkwc2N0Znt3M2xjMG0zXw==" | base64 -d
```

> **Flag 1:** `bi0sctf{w3lc0m3_`

(Nota: Adicionalmente revisamos `dlllist` y `handles` en busca de anomalías en los comandos ejecutados, pero no se encontró nada relevante).

## 4. Archivos en Memoria

### Búsqueda de archivos (`filescan`)

Usamos el plugin `filescan` para buscar archivos con extensiones interesantes como `.txt`, `.zip`, `.rar`, etc.

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 filescan | grep "\\.rar"
```

```bash
0x000000011fdaff20     16      0 -W-r-- \\Device\\HarddiskVolume2\\Users\\bruce\\Desktop\\flag5.rarp\\VirtualBox Dropped Files\\2024-08-06T18_36_43.522668500Z\\flag5.rar
```

Conseguimos encontrar dónde está alojada la `flag5`. Ahora hay que extraerla y ver su contenido.

### Volcado del archivo (`dumpfiles`)

Usamos el offset (`0x000000011fdaff20`) obtenido en el paso anterior para volcar el archivo de la memoria a nuestro equipo local.

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 dumpfiles -Q 0x000000011fdaff20 -D dump/
```

Transformamos el archivo extraído (`file.None.0xfffffa80049f86a0.dat`) a la extensión correcta `.rar` y analizamos su contenido:

```bash
unrar l dump/file.None.0xfffffa80049f86a0.rar
```

```bash
UNRAR 7.20 beta 2 freeware      Copyright (c) 1993-2025 Alexander Roshal

Archive comment:
The password for the zip file is the computer's password

Archive: dump/file.None.0xfffffa80049f86a0.rar
Details: RAR 5

 Attributes      Size     Date    Time   Name
----------- ---------  ---------- -----  ----
* ..A....        20  2024-08-06 18:47  flag.txt
----------- ---------  ---------- -----  ----
                   20                    1
```

El archivo contiene un comentario que indica que la contraseña del comprimido es la misma que **la contraseña del ordenador**.

### Extracción de Hashes de Contraseñas (`hashdump`)

Para obtener la contraseña del ordenador (del usuario `bruce`, ya que vimos la ruta `\\Users\\bruce\\`), volcamos los hashes del sistema:

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 hashdump
```

```bash
Administrator:500:aad3b435b51404eeaad3b435b51404ee:10eca58175d4228ece151e287086e824:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
bruce:1001:aad3b435b51404eeaad3b435b51404ee:b7265f8cc4f00b58f413076ead262720:::
HomeGroupUser$:1002:aad3b435b51404eeaad3b435b51404ee:bda4ed0acc67d6d60540d1a20cf444c6:::
```

### Crackeo de la contraseña

Nos copiamos el hash NT del usuario `bruce` (`b7265f8cc4f00b58f413076ead262720`) en un archivo de texto y procedemos a romperlo con John the Ripper usando una lista de palabras común (`rockyou.txt` o la por defecto `password.lst`).

```bash
echo "b7265f8cc4f00b58f413076ead262720" > hashbruce.txt
john --format=NT hashbruce.txt
```

```bash
Using default input encoding: UTF-8
Loaded 1 password hash (NT [MD4 512/512 AVX512BW 16x3])
Warning: no OpenMP support for this hash type, consider --fork=12
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst
batman           (?)     
1g 0:00:00:00 DONE 2/3 (2026-02-11 21:57) 20.00g/s 7680p/s 7680c/s 7680C/s 123456..larry
Use the "--show --format=NT" options to display all of the cracked passwords reliably
Session completed.
```

**La contraseña es `batman`.**

Una vez que tenemos la password podemos abrir el archivo `.rar` y ver la flag.

```bash
unrar x file.None.0xfffffa80049f86a0.rar
cat flag.txt
falg5 = bTByM18xMzMzNzQzMX0=
```

> **Flag 5:** `m0r3_13337431}`

***

## 5. Análisis de Otros Artefactos

Por completar el análisis y asegurar que no pasamos nada por alto, revisamos otros frentes:

* **Analisis de persistencia (`shimcache`)**: Nada relevante encontrado.
* **Investigación del portapapeles (`clipboard`)**: En el momento de la captura de memoria, lo que había en el portapapeles era un formato de texto (`CF_TEXT`), pero la extracción de datos no mostró nada relevante.
* **Variables de entorno (`envars`)**: Sin hallazgos críticos.
* **Reconocimiento de Archivos Recientes (`shellbags`) y Servicios (`svcscan`)**: Se listaron, pero la investigación nos lleva de vuelta a los procesos en ejecución interactivos.

***

## 6. Búsqueda de Código Inyectado (`malfind`)

Ejecutamos `malfind` para identificar páginas de memoria con permisos sospechosos (típicamente Ejecución/Lectura/Escritura) que puedan indicar inyección de código o procesos ocultando información.

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 malfind -D dump/malware/
```

* **`0xfffffa80039c2490 -> mspaint.exe (PID 2516)`**
* **`0xfffffa8006bbeb00 -> explorer.exe (PID 1172)`**
* **`0xfffffa80044c3b00 -> chrome.exe (PID 4456)`**
* **`svchost.exe`**: El malware genérico suele inyectarse aquí.

***

## 7. Análisis Específico de Procesos

### Análisis de `notepad.exe` (PID 2592)

Utilizamos `vaddump` para extraer cada segmento de memoria que el proceso Bloc de notas ha solicitado al sistema operativo de forma independiente.

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 vaddump -p 2592 -D dump/2592/
```

*(Esto genera múltiples archivos `.dmp`, cada uno corresponde a un rango de direcciones de memoria).*

Para saber qué hay dentro de un `.dmp` específico y dónde focalizar, usamos `vadinfo`:

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 vadinfo -p 2592
```

Buscamos los segmentos que tengan protección `PAGE_READWRITE` y que no estén vinculados a un archivo en disco (se llaman *Mapped* o *Private*). Esos suelen ser los que contienen el texto crudo que el usuario escribió temporalmente y que el sistema tiene en memoria.

Analizamos el contenido del nodo con mayor `CommitCharge` (que indica mayor uso de RAM por parte del segmento). En este caso el bloque: `Start 0x00000000001f0000 End 0x00000000002effff` (CommitCharge: 122).

Extraemos e inspeccionamos las strings (cadenas de texto legibles) dentro de ese dumpeo:

```bash
strings -e l dump/2592/*0x00000000001f0000-0x00000000002effff.dmp | less
```

**Encontramos la Flag 4 codificada en Base64:** `flag4 = YjNuM2YxNzVfeTB1Xw==`

> **Flag 4:** `b3n3f175_y0u_`

### Análisis de `mspaint.exe` (PID 2516)

Hacemos un volcado de memoria de todas las páginas direccionables de este proceso para investigar a fondo.

Podemos ver qué archivos (imágenes) tenía abiertos Paint en ese momento usando `handles`:

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 handles -p 2516 -t File
```

*(Se ven librerías y componentes MUI, pero ningún archivo `.png` o `.bmp` de usuario explícito).*

Dado que no hay archivos vinculados de forma evidente, vamos a buscar directamente en el propio espacio de memoria del proceso. Procedemos a hacer un volcado del proceso `mspaint.exe`:

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 memdump -p 2516 -D dump/mspaint/
```

Esto nos genera un archivo `.dmp` (en este caso `2516.dmp` de unos 493 MB).

#### Análisis del dump

Aplicaciones de edición gráfica como MS Paint almacenan el lienzo (las imágenes que se están editando) directamente en la memoria RAM como matrices de píxeles crudos (*raw bitmaps*), sin las cabeceras ni la compresión típica de formatos como PNG o JPG. GIMP cuenta con una función para abrir "Datos de imagen en bruto" (*Raw image data*), lo que nos permite renderizar un volcado binario de memoria como si fueran píxeles en pantalla, ajustando los parámetros manualmente hasta "cuadrar" la imagen. Para abrirlo usaremos **GIMP**, seleccionamos el archivo `2516.dmp` y nos aseguramos de elegir el tipo de archivo **Raw image data**.

<figure><img src="/files/MIj2TVKQmd9794rHlkb3" alt=""><figcaption></figcaption></figure>

Al abrir aparecerá un cuadro donde debemos "esculpir" (carvear) la imagen usando ensayo y error.

Tras muchísima búsqueda y cambios encontramos los parámetros necesarios para sacar lo que parece ser la flag.

<figure><img src="/files/5HKu3NKJw2jFjeCF00mj" alt=""><figcaption></figcaption></figure>

Los parámetros utilizados han sido:

* Formato de píxel (RGB 16-bit): Le indica a GIMP cómo interpretar los bytes en memoria. Windows y la arquitectura x86/x64 trabajan en Little Endian. El formato RGB 16-bit (o a veces 32-bit) coincide con la profundidad de color que Paint estaba usando para mapear los píxeles en memoria.
* Anchura (614): Este es el parámetro más crítico. Al abrir datos crudos, si el ancho no es exacto, la imagen se verá como ruido estático o líneas diagonales. Ajustando el valor de la anchura píxel a píxel logramos alinear los "saltos de línea" de la memoria hasta que el ruido se estabiliza y forma una imagen coherente.
* Offset (7941): Como el archivo .dmp contiene toda la memoria del proceso (no solo la imagen), hay que indicarle a GIMP cuántos bytes debe saltarse al principio antes de empezar a pintar los píxeles. Modificando este offset evitamos que la imagen se vea cortada o desplazada horizontalmente.
* Altura (3200): Se define una altura lo suficientemente grande para abarcar todo el bloque de memoria visualizable donde reside nuestra pista.

Tras ajustar minuciosamente estos parámetros, la previsualización nos muestra un texto entre el ruido de la memoria. Sin embargo, en Windows, los mapas de bits independientes del dispositivo (DIB) a menudo se almacenan en memoria de "abajo hacia arriba" (bottom-up). Esto provoca que al extraer la imagen en bruto se vea invertida y reflejada.

Si guardamos la imagen, la rotamos 180º y la espejamos, podemos leer claramente la siguiente cadena codificada en Base64: `dDBfZGYxcl9sNGl1Xw==`

> **Flag2:** `t0_df1r_l4iu_`

### Capturas de pantalla

Para ver lo que se estaba visualizando, tomamos capturas de pantalla de la memoria usando Windows subsytem GDI:

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 screenshot -D dump/mspaint/
```

<figure><img src="/files/Y5krSu35UWJCi2PYr71v" alt=""><figcaption></figcaption></figure>

El resultado indica que **todas las imágenes generadas estaban en blanco menos una**, sugiriendo que podría haber datos visuales ocultos.

Como medida adicional, tallamos imágenes del dump extraído usando `foremost`:

```bash
foremost -i dump/2516.dmp -o dump/mspaint/output_paint_carve -t png,bmp,jpg
```

<figure><img src="/files/0uOM5kFDuPWxVPTmJeFi" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/9ti7s0rTKFg8pwyZVEyv" alt=""><figcaption></figcaption></figure>

***

## 8. Análisis del Historial de Navegación (Google Chrome)

Buscamos en la memoria la base de datos de historial de Google Chrome del usuario.

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 filescan | grep "History"
```

```bash
0x000000011f2d9dd0     33      1 RW-rw- \\Device\\HarddiskVolume2\\Users\\bruce\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History-journal
0x000000011fd1bf20      1      1 RW-rw- \\Device\\HarddiskVolume2\\Users\\bruce\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History
```

Volcamos el archivo de la base de datos de historial (el que NO es "journal"):

```bash
vol2 -f gotham.raw --profile=Win7SP1x64 dumpfiles -Q 0x000000011fd1bf20 -D dump/google/
```

Verificamos el tipo de archivo volcados:

```bash
file file.None.0xfffffa800459f580.dat
SQLite 3.x database...
```

Abrimos el archivo con `sqlite3` y lanzamos una consulta para ver las URLs visitadas:

```bash
sqlite3 file.None.0xfffffa800459f580.dat
sqlite> SELECT url FROM urls ORDER BY visit_count;
```

```bash
<https://www.google.com/search?q=memlabs&oq=memlabs&aqs=chrome..69i57.3376j0j7&sourceid=chrome&ie=UTF-8>
<https://www.google.com/search?q=flag3+%3D+aDBwM190aDE1Xw%3D%3D&oq=flag3+%3D+aDBwM190aDE1Xw%3D%3D&aqs=chrome..69i57j0i512i546l2.321545j0j7&sourceid=chrome&ie=UTF-8>
```

Vemos una búsqueda en Google que el usuario realizó deliberadamente con la palabra clave `flag3 = aDBwM190aDE1Xw==`.

Decodificando la cadena Base64 obtenida de la búsqueda:

```bash
echo "aDBwM190aDE1Xw==" | base64 -d
```

> *Nota:* Chrome guarda el tiempo en Google Chrome Time (microsegundos desde el 1 de enero de 1601). Para convertirlo a algo legible en SQL (Timestamp Unix), se puede usar la fórmula: `Unix Timestamp = (Chrome Timestamp / 1,000,000) − 11,644,473,600`.

> **Flag 3:** `h0p3_th15_`

***

## 9. Reconstrucción de la Flag Final

Uniendo las piezas obtenidas en los diferentes análisis:

* **Flag 1 (Consola):** `bi0sctf{w3lc0m3_`
* **Flag 2 (Memoria raw de mspaint.exe):** `t0_df1r_l4iu_`
* **Flag 3 (Chrome History):** `h0p3_th15_`
* **Flag 4 (Notepad VAD):** `b3n3f175_y0u_`
* **Flag 5 (Archivo RAR):** `m0r3_13337431}`

**Flag Completa Final:**

```bash
bi0sctf{w3lc0m3_t0_df1r_l4iu_h0p3_th15_b3n3f175_y0u_m0r3_13337431}
```
