| Escenario | El entorno del dominio de Forela es un caos puro. Acaba de recibir otra alerta del controlador de dominio sobre la exfiltración de la base de datos NTDS.dit. Solo un día antes, respondiste a una alerta en el mismo controlador de dominio donde un atacante volcó NTDS.dit a través de la utilidad vssadmin. Sin embargo, lograste eliminar los archivos volcados, expulsar al atacante del controlador de dominio y restaurar una instantánea limpia. Ahora, nuevamente han logrado acceder al controlador de dominio con una cuenta de administrador de dominio gracias a su acceso persistente en el entorno. Esta vez están abusando de ntdsutil para volcar la base de datos. ¡Ayuda a Forela en estos tiempos caóticos! |
| Archivos | APPLICATION.evtx, SECURITY.evtx , SYSTEM.evtx |
| Fuente de apoyo | NTDS dumping attack detection |

Pasos Previos
1. Convertir los archivos .evtx a JSON para poder trabajar con ellos.
- En mi caso he utilizado la herramienta `Chainsaw`.
- Para utilizar esta herramienta debemos situarnos en el directorio donde se encuentran nuestros archivos `.evtx` y ejecutar este comando (yo ubiqué `Chainsaw` en `/opt`)
/opt/chainsaw/chainsaw dump *.evtx --json > events.json 2. Disponer de la herramienta jq para hacer consultas en archivos JSON
- Con `jq` podemos extraer información específica de archivos JSON mediante la aplicación de filtros.
- Utilizando esta herramienta podremos consultar nuestro JSON de forma anidada. Por ejemplo, con este archivo llamado `product.json`
{"product":
{
"productID": 101,
"productName": "Wireless Mouse",
"dimensions": {
"width": "2.5 inches",
"height": "1.5 inches",
"depth": "4 inches"
}
}
} - Si queremos acceder al valor del campo `depth` tendremos que utilizar un comando como este:
cat product.json | jq '.product.dimensions.depth' o
cat product.json | jq '.product | .dimensions.depth' Tasks
Task 1. Al utilizar ntdsutil.exe para volcar NTDS en el disco, este emplea simultáneamente el Servicio Shadow Copy de Microsoft. ¿Cuál es el timestamp más reciente en el que este servicio entró en estado de ejecución, lo que significaría el posible inicio del proceso de volcado de NTDS?
Pista
- En los logs de eventos de sistema, filtra por el ID de evento 7036 y busca el nombre del servicio mencionado. Una vez que lo encuentres, ve a la pestaña de detalles y expande la opción del sistema para obtener la hora del evento en UTC.
Respuesta
- 2024-05-15 05:39:55
-
De resolver
CrownJewel-1sabemos que el evento que se encarga de cambiar los estados de un servicio es el7036y que el nombre del servicio esVolume Shadow Copy. -
Utilizaremos este comando para recuperar todos los timestamp de ese evento para ese servicio y eliminaremos las repeticiones:
cat events.json | jq '.[].Event | select(.System.EventID == 7036) | select(.EventData.param1 == "Volume Shadow Copy") | .System.TimeCreated_attributes.SystemTime'|sort -u
- Ahora solo tendremos que quedarnos con el timestamp más reciente.
Task 2. Identifica la ruta completa del volcado del archivo NTDS
Pista
- En los logs de eventos de aplicación, filtra por el Event ID 325. Este evento se registra cada vez que se crea una nueva base de datos (nueva copia de la base de datos NTDS.dit) por el motor de la base de datos.
Respuesta
- C:\Windows\Temp\dump_tmp\Active Directory\ntds.dit
- Primero filtraremos por
ntds.dit:
cat events.json | grep -i ntds.dit
-
Cualquier ruta diferente de
Windows/NTDS/ntds.dit(ruta por defecto parantds.dit) es indicativo de un comportamiento malicioso. -
De todas ellas,
C:\\Windows\\Temp\\dump_tmp\\Active Directory\\ntds.ditparece ser la indicada, llamar a un directoriodump_tmpsugiere la intención de hacer un volcado temporal.
Task 3. ¿Cuándo se creó el volcado de la base de datos en el disco?
Pista
- Podría ser el mismo momento del evento cuando se creó la copia de la base de datos(Event ID 325)
Respuesta
- 2024-05-15 05:39:56
- Sabemos la ubicación donde se volcó la base de datos, así que filtraremos los eventos por el directorio
dump_tmp:
cat events.json | jq '.[].Event' -c | grep -i dump_tmp | jq . -
Nos devolverá tres eventos con ID
330, 325, 327. -
Como el evento
325es el que se activa cuando se crea la nueva base de datos, utilizaremos su timestamp.
Task 4. ¿Cuándo se consideró el nuevo volcado de la base de datos completo y listo para usar?
Pista
- En los logs de eventos de aplicación, filtra por el Event ID 327. Este evento se registra cada vez que una nueva base de datos (una nueva copia de la base de datos NTDS.dit) es desacoplada por el motor de la base de datos y marcada como lista para usar.
Respuesta
- 2024-05-15 05:39:58
- Después del evento
325se ejecuta el327que es el que indica que la base de datos ha sido desacoplada, por lo que la respuesta debería ser el timestamp del evento327que hemos recuperado anteriormente.
Task 5. Los logs de eventos utilizan fuentes de eventos para rastrear eventos que provienen de diferentes orígenes. ¿Qué fuente de eventos proporciona datos sobre el estado de la base de datos, como la creación y el desacoplamiento?
Pista
- Mira la fuente de Evento en los eventos de las preguntas 2 a 4.
Respuesta
- ESENT
- La fuente de eventos que proporciona estatus de la base de datos es
ESENT, como podemos ver en los eventos que recuperamos en la pregunta 3.
Task 6. Cuando se utiliza ntdsutil.exe para hacer un volcado de la base de datos, enumera una serie de grupos de usuario para validar los privilegios de la cuenta que está siendo usada. ¿Qué dos grupos se enumeran por el proceso ntdsutil.exe? Proporciona los grupos en orden alfabético separados por coma y espacio.
Pista
- En los logs de seguridad, filtra por el ID de evento 4799. Busca eventos dentro del espacio de tiempo del incidente identificado hasta ahora. Identifica los eventos donde el nombre del proceso es C:\Windows\System32\ntdsutil.exe.
Respuesta
- Administrators, Backup Operators
-
El proceso que se activa cuando se enumeran grupos es el
4799. -
Recuperaremos los nombres de los grupos que se muestran en el campo
.EventData.TargetUserName, filtrando por el evento4799cuando es llamado porntdsutil.exe:
cat events.json | jq '.[].Event | select(.System.EventID == 4799) | select(.EventData.CallerProcessName | test("ntdsutil.exe")) | .EventData.TargetUserName'|sort -u - Nos devolverá:
- “Administrators"
- "Backup Operators”
Task 7. Ahora se te ha encomendado la tarea de encontrar el momento de inicio de sesión de la sesión maliciosa. Usando el ID de inicio de sesión, encuentra el momento en el que la sesión de usuario comenzó.
Pista
- Dado que este es un entorno de dominio, querríamos usar eventos de Kerberos para encontrar el timestamp. Filtra por los eventos con ID `4768` y `4769`. A partir de aquí, identifica el evento donde el nombre de la cuenta es un nombre de cuenta de usuario y no una cuenta de servicio o de máquina (que comienza con un $) en el evento `4768`. Este evento será seguido inmediatamente por un evento `4769` con el mismo nombre de usuario del sujeto. Ahora agrega otro envento al filtro, el `5379`. Estos nuevos eventos tienen el ID de inicio de sesión que estamos rastreando. Observa que el timestamp de todos estos eventos es el mismo, ya que ocurrieron uno después del otro. Este será el tiempo de inicio de sesión.
Respuesta
- 2024-05-15 05:36:31
-
Tal y como dice la pista, la autenticación en entornos de dominio se lleva a cabo con
Kerberos, y se asocia con los eventos4768y4769. -
Primero buscamos en los eventos
4768un nombre de usuario que no sea ni un servicio ni una máquina:
cat events.json | jq '.[].Event | select(.System.EventID == 4768) | .EventData.TargetUserName' -
Esto no devuelve:
- “DC01$"
- "DC01$"
- "Administrator”
-
El único que tiene nombre de usuario es
Administrator. -
Buscaremos el evento
4768deAdministrador:
cat events.json | jq '.[].Event | select(.System.EventID == 4768) | select(.EventData.TargetUserName == "Administrator")'
-
Nos quedamos con el timestamp hasta los segundos, ya que según nos dice la pista, los eventos
4768,4769y5379se ejecutan de forma secuencial (uno inmediatamente después del otro). -
Ahora necesitamos buscar los eventos que contengan el ID de inicio de sesion, que son los eventos
5379. -
Filtramos por el timestamp anterior.
cat events.json | jq '.[].Event | select(.System.EventID == 5379) | select(.System.TimeCreated_attributes.SystemTime | test("2024-05-15T05:36:31"))' - Esto nos devuelve 3 eventos con ID de sesión
0x8de3d(campoSubjectLogonId) y todos con el mismo timestamp, el mismo que hemos utilizado para filtar. Esa es la respuesta a la pregunta.
¡Eso es todo!