GhostAcademy
Ghost AcademySecLearn// WINDOWS EVENT LOGS LAB
🔵 LABORATORIO DFIR — NIVEL INICIAL / INTERMEDIO
Análisis de Event Logs de Windows para Respuesta a Incidentes
Forense de Windows · Detección de amenazas · SOC / DFIR · GhostAcademy · unfantasmaenelsistema.com
Event ViewerPowerShell Brute ForcePassword Spraying Privilege EscalationLOLBins PersistenciaMITRE ATT&CK KerberoastingTimeline Analysis
9EJERCICIOS
30+EVENT IDs
9PREGUNTAS
🎯
Objetivos del Laboratorio
¿Qué vas a aprender y practicar?

Este laboratorio práctico te guía por el análisis forense de registros de eventos de Windows (Windows Event Logs) para la detección e investigación de incidentes de seguridad. Los Event Logs son la fuente de telemetría más importante disponible de forma nativa en sistemas Windows y el punto de partida obligatorio en cualquier SOC o investigación DFIR.

Al finalizar serás capaz de:

  • Navegar por el Visor de Eventos y entender la estructura de los logs
  • Identificar y analizar los Event IDs críticos de seguridad
  • Detectar ataques de fuerza bruta, password spraying y movimiento lateral
  • Identificar creación de cuentas no autorizadas y escalada de privilegios
  • Detectar ejecución sospechosa de procesos, LOLBins y scripts PowerShell maliciosos
  • Detectar instalación de servicios y tareas programadas como mecanismos de persistencia
  • Correlacionar múltiples eventos para reconstruir la línea de tiempo de un ataque
  • Automatizar el análisis con PowerShell (Get-WinEvent)
📌 CONTEXTOLos Event Logs están siempre activos en cualquier Windows moderno. Un atacante genera eventos inevitablemente: cada autenticación, cada proceso creado, cada modificación de cuenta queda registrada. Aprender a interpretarlos es la habilidad #1 del analista de seguridad defensiva.
F1Estructura
F2Auth
F3Cuentas
F4Procesos
F5Persist.
F6Timeline
F7PowerShell
🧠
Teoría: Estructura y Tipos de Event Logs de Windows
Conceptos fundamentales antes de comenzar
📂CANALES PRINCIPALES DE LOG
CanalArchivo .evtxContenido relevante para seguridad
SecuritySecurity.evtxAutenticaciones, cuentas, acceso a objetos, política — el más crítico
SystemSystem.evtxServicios instalados/iniciados, drivers, apagados del sistema
ApplicationApplication.evtxErrores de aplicaciones, eventos de software
PowerShell/Operational...PowerShell%4Operational.evtxScripts PS, ScriptBlock logging (IDs 4103, 4104) — crítico
Sysmon/Operational...Sysmon%4Operational.evtxProcesos con hash, conexiones de red, cambios de registro
Task Scheduler...TaskScheduler%4Operational.evtxTareas programadas creadas/ejecutadas

Los archivos .evtx se encuentran en C:\Windows\System32\winevt\Logs\ y pueden copiarse y analizarse en otro sistema para análisis offline forense.

🔌ANATOMÍA DE UN EVENTO (XML)
Estructura XML de Event ID 4624
<Event> <s> <EventID>4624</EventID> <!-- ID del evento --> <TimeCreated SystemTime="2025-01-15T10:32:47Z"/> <!-- UTC --> <Computer>WORKSTATION01</Computer> <!-- D&oacute;nde ocurri&oacute; --> <Channel>Security</Channel> </s> <EventData> <Data Name="TargetUserName">jdoe</Data> <!-- Cuenta autenticada --> <Data Name="LogonType">10</Data> <!-- 10 = RDP --> <Data Name="IpAddress">192.168.1.50</Data> <!-- IP de origen --> <Data Name="LogonID">0x1a2b3c</Data> <!-- Clave de correlaci&oacute;n --> </EventData> </Event>

El Logon ID es el campo más valioso para correlación: permite rastrear TODOS los eventos de una misma sesión (procesos creados, cuentas modificadas, etc.) correlacionando por ese identificador único.

📋
Prerrequisitos y Entorno
Lo que necesitas antes de empezar
💻ENTORNO RECOMENDADO
  • Sistema operativo: Windows 10/11 Pro o Windows Server 2019/2022 (máquina virtual recomendada)
  • Permisos: cuenta de administrador local
  • PowerShell 5.1+ (incluido en Windows 10/11)
  • Visor de Eventos nativo: eventvwr.msc
  • Opcional: Sysmon de Sysinternals para visibilidad adicional
💡 PARA CLASE — LOGS DE PRÁCTICASi no tienes un entorno con incidentes reales: (1) EVTX Attack Samples — github.com/sbousseaden/EVTX-ATTACK-SAMPLES: logs reales de ataques categorizados por MITRE ATT&CK. (2) CyberDefenders y BlueTeamLabs Online con labs que incluyen .evtx. (3) TryHackMe — módulos de Windows Event Logs y Sysmon.
⚙
Configurar la Auditoría Avanzada de Windows
Sin esto, muchos eventos críticos no se registran
⚠ PROBLEMA FRECUENTEPor defecto Windows NO registra muchos eventos críticos de seguridad. La auditoría debe configurarse explícitamente. Si un Event ID no aparece, la categoría de auditoría no está habilitada.
1
Verificar configuración actual CMD
Ver auditoría configurada
# Ver todas las categorías auditpol /get /category:* # Ver las relevantes auditpol /get /category:"Account Logon" auditpol /get /category:"Logon/Logoff" auditpol /get /category:"Account Management" auditpol /get /category:"Detailed Tracking"
2
Activar categorías esenciales ADMIN REQUERIDO
Habilitar auditoría avanzada (ejecutar como Admin)
# Inicio/cierre de sesión auditpol /set /subcategory:"Logon" /success:enable /failure:enable auditpol /set /subcategory:"Logoff" /success:enable auditpol /set /subcategory:"Special Logon" /success:enable # Gestión de cuentas auditpol /set /subcategory:"User Account Management" /success:enable /failure:enable auditpol /set /subcategory:"Security Group Management" /success:enable /failure:enable # Creación de procesos (necesario para Event ID 4688) auditpol /set /subcategory:"Process Creation" /success:enable # Cambios de política auditpol /set /subcategory:"Audit Policy Change" /success:enable /failure:enable
3
Habilitar Command Line en Event ID 4688 REGISTRO DE WINDOWS
Habilitar command line auditing
# Necesario para ver los argumentos de cada proceso (muy importante) reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /f
4
Habilitar PowerShell ScriptBlock Logging (Event ID 4104) POWERSHELL — CRÍTICO

Captura el contenido completo de scripts PowerShell ejecutados, incluso ofuscados. Fundamental para detectar ataques fileless.

Habilitar ScriptBlock Logging
# Event ID 4104 - ScriptBlock logging reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 /f # Event ID 4103 - Module logging reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" /v EnableModuleLogging /t REG_DWORD /d 1 /f
✓ RECOMENDADO — INSTALAR SYSMONSysmon proporciona telemetría más detallada: hashes SHA-256 de procesos, conexiones de red por proceso, cambios de registro. Instalar: sysmon64 -accepteula -i sysmon-config.xml (usar config de SwiftOnSecurity en GitHub)
💻
Ejercicio 1 — El Visor de Eventos
Objetivo: familiarizarse con la interfaz y estructura de los logs
1
Abrir el Visor de Eventos ACCESO
Abrir Event Viewer
# Win+R: eventvwr.msc # Desde CMD: eventvwr # Desde PowerShell: Start-Process eventvwr.msc
2
Explorar la jerarquía NAVEGACIÓN

Panel izquierdo:

  • Registros de Windows → Aplicación, Seguridad, Sistema
  • Registros de aplicaciones y servicios → Microsoft → Windows → PowerShell, Sysmon...

Haz clic en Seguridad. Cada evento muestra: nivel, fecha, origen, ID y categoría.

3
Examinar el detalle de un evento ANATOMÍA

Doble clic en cualquier evento:

  • Pestaña General: descripción legible con datos rellenos
  • Pestaña Detalles → XML: el XML raw con todos los campos exactos — el más útil para forense
4
Exportar logs para análisis offline PRESERVACIÓN
Exportar logs con cadena de custodia
# Clic derecho sobre el log -> 'Guardar todos los eventos como...' -> .evtx # Con PowerShell (m&aacute;s controlado): wevtutil epl Security C:\Evidence\Security_$(Get-Date -Format yyyyMMdd).evtx wevtutil epl System C:\Evidence\System_$(Get-Date -Format yyyyMMdd).evtx # Calcular hashes (cadena de custodia) Get-FileHash C:\Evidence\*.evtx -Algorithm SHA256 | Format-Table
❓ Pregunta
Al abrir el log de Seguridad ves que tiene solo 20MB y los eventos más antiguos son de hace 2 días. En un sistema en producción, ¿qué significaría esto?
💡 Busca el Event ID 1102 y piensa en por qué un log podría ser tan pequeño.
Ver respuesta
Puede indicar borrado intencional de logs. El Event ID 1102 (log de seguridad borrado) se registra cuando alguien borra el log. Otro motivo: tamaño máximo muy pequeño. Investigar: (1) buscar Event IDs 1102 y 104, (2) verificar tamaño máximo configurado, (3) revisar si hay logs en SIEM centralizado o backup.
🔒
Ejercicio 2 — Eventos de Autenticación
Objetivo: analizar el ciclo completo de inicio y cierre de sesión
🔑EVENT IDs DE AUTENTICACIÓN CLAVE
Event IDNombreCuándo ocurreRelevancia
4624Inicio de sesión correctoAutenticación exitosaCrítico — ver Logon Type
4625Error de inicio de sesiónAutenticación fallidaCrítico — fuerza bruta, spraying
4634Cierre de sesiónFin de sesiónAlto — correlacionar con 4624
4648Credenciales explícitasrunas, PsExec, movimiento lateralCrítico — lateral movement
4672Privilegios especiales asignadosAdmin se autenticaAlto — siempre acompaña 4624 de admin
4769Ticket servicio Kerberos solicitadoAcceso a servicio del dominioCrítico — Kerberoasting (muchos + RC4)
4776Validación NTLMAuth NTLMCrítico — Pass-the-Hash, NTLM relay
1
Examinar campos críticos del Event ID 4624 ANÁLISIS
Campos clave de un evento 4624
# Campos que SIEMPRE debes revisar: # # LogonType -> Vector de acceso (ver tabla de tipos) # TargetUserName -> Cuenta que se autenticó # LogonID -> ID Único de sesión (correlación con otros eventos) # IpAddress -> IP de origen (- o ::1 = local) # WorkstationName -> Equipo de origen # AuthPackageName -> NTLM / Kerberos / Negotiate # ElevatedToken -> 1 = sesión elevada (admin)
2
Buscar inicios de sesión RDP (Logon Type 10) DETECCIÓN RDP
Buscar logins RDP con PowerShell
Get-WinEvent -FilterHashtable @{{ LogName = 'Security' Id = 4624 }} | Where-Object {{ $_.Properties[8].Value -eq 10 }} | ForEach-Object {{ [PSCustomObject]@{{ Tiempo = $_.TimeCreated Usuario = $_.Properties[5].Value IP_Origen = $_.Properties[18].Value Workstation= $_.Properties[11].Value LogonID = $_.Properties[7].Value }} }} | Sort-Object Tiempo | Format-Table -AutoSize
3
Detectar uso de credenciales explícitas (4648) LATERAL MOVEMENT
Buscar eventos 4648
# Indica runas, PsExec, movimiento lateral Get-WinEvent -FilterHashtable @{{ LogName='Security'; Id=4648 }} | ForEach-Object {{ [PSCustomObject]@{{ Tiempo = $_.TimeCreated Cuenta_Origen = $_.Properties[1].Value Cuenta_Objetivo = $_.Properties[5].Value Servidor_Destino = $_.Properties[8].Value Proceso = $_.Properties[11].Value }} }} | Format-Table -AutoSize
❓ Pregunta
Encuentras muchos Event ID 4624 con LogonType=3 desde la IP 10.10.5.22 durante el fin de semana. El usuario es 'svc_backup'. ¿Es sospechoso?
💡 Logon Type 3 es acceso de red (SMB). Piensa en qué hace una cuenta de servicio de backup y en qué horario debería trabajar.
Ver respuesta
Puede ser legítimo o sospechoso. Señales de alarma: (1) backup no programado ese fin de semana, (2) IP 10.10.5.22 no es el servidor de backup habitual, (3) la cuenta accede a recursos no relacionados con backup. Investigar: correlacionar el Logon ID de esos 4624 con 4688 para ver qué procesos ejecutó la cuenta en esa sesión.
🔎
Ejercicio 3 — Filtrado y Búsqueda Avanzada
Objetivo: encontrar eventos específicos entre millones de entradas
1
Filtro básico del Visor de Eventos GUI
  1. Selecciona Seguridad en el panel izquierdo
  2. Clic en "Filtrar registro actual..."
  3. Escribe el ID en "Incluye/Excluye identificadores": ej. 4625
  4. Para múltiples IDs sepáralos con comas: 4624, 4625, 4648
  5. Establece un rango de fechas en "Fecha y hora"
2
Filtros XPath avanzados XPATH
Filtros XPath para Event Viewer
<!-- Filtrar 4625 de un usuario específico --> <QueryList> <Query Id="0" Path="Security"> <Select Path="Security"> *[System[(EventID=4625)]] and *[EventData[Data[@Name='TargetUserName']='administrator']] </Select> </Query> </QueryList> <!-- Múltiples IDs + rango de tiempo --> <QueryList> <Query Id="0" Path="Security"> <Select Path="Security"> *[System[(EventID=4624 or EventID=4625 or EventID=4648) and TimeCreated[@SystemTime&gt;='2025-01-15T00:00:00Z' and @SystemTime&lt;='2025-01-15T23:59:59Z']]] </Select> </Query> </QueryList>
3
Análisis de archivos .evtx offline OFFLINE
Analizar .evtx fuera del sistema analizado
# Analizar archivo .evtx copiado de otro equipo Get-WinEvent -Path 'C:\Evidence\Security.evtx' -FilterHashtable @{{ Id = @(4624, 4625, 4648) }} | ForEach-Object {{ [PSCustomObject]@{{ Tiempo = $_.TimeCreated EventID = $_.Id Usuario = $_.Properties[5].Value IP = $_.Properties[18].Value }} }} | Export-Csv 'C:\Evidence\auth_events.csv' -NoTypeInformation
❓ Pregunta
Recibes una alerta de que la cuenta 'mgarcia' pudo ser comprometida el 20 de enero entre 14:00 y 16:00. ¿Qué Event IDs incluirías en el filtro?
💡 Cubre autenticación, actividad y posibles cambios. Las horas en XPath son UTC.
Ver respuesta
Incluiría: 4624 (logons exitosos), 4625 (fallidos), 4648 (credenciales explícitas), 4634 (cierres), 4672 (privilegios especiales). Si sospecho escalada: 4720 (cuenta creada) y 4732 (añadido a grupo). Filtrar por TargetUserName='mgarcia' y el rango horario para reconstruir qué hizo la cuenta exactamente.
🔴
Ejercicio 4 — Detección de Ataques de Fuerza Bruta y Password Spraying
Objetivo: identificar intentos de acceso masivos no autorizados
🚨 ESCENARIO — SERVIDOR BAJO ATAQUE
El SOC recibe alerta: más de 200 eventos 4625 en el servidor FILESERVER01 en 30 minutos. Determina si es fuerza bruta, password spraying o un falso positivo.
1
Cuantificar y clasificar los fallos VOLUMEN
Analizar fallos de autenticación
$inicio = (Get-Date).AddHours(-2) $fallos = Get-WinEvent -FilterHashtable @{{ LogName='Security'; Id=4625; StartTime=$inicio }} | ForEach-Object {{ [PSCustomObject]@{{ Tiempo = $_.TimeCreated Usuario = $_.Properties[5].Value IP_Origen = $_.Properties[19].Value SubStatus = $_.Properties[9].Value LogonType = $_.Properties[10].Value }} }} Write-Host "Total fallos: $($fallos.Count)" # Top IPs atacantes $fallos | Group-Object IP_Origen | Sort-Object Count -Desc | Select-Object -First 10 | Format-Table Count, Name -AutoSize # Top usuarios atacados $fallos | Group-Object Usuario | Sort-Object Count -Desc | Select-Object -First 10 | Format-Table Count, Name -AutoSize
2
Distinguir fuerza bruta de password spraying PATRÓN
Detectar el tipo de ataque
# FUERZA BRUTA: muchos intentos en UN usuario desde UNA IP # SPRAYING: pocos intentos en MUCHOS usuarios desde UNA IP $fallos | Group-Object IP_Origen | ForEach-Object {{ $usuariosUnicos = ($_.Group.Usuario | Sort-Object -Unique).Count [PSCustomObject]@{{ IP = $_.Name TotalFallos = $_.Count UsuariosDistintos= $usuariosUnicos Patron = if ($usuariosUnicos -gt 10) {{ 'PASSWORD SPRAYING' }} else {{'FUERZA BRUTA'}} }} }} | Format-Table -AutoSize
3
Analizar el SubStatus para entender la causa ERRORES
Analizar códigos de error
# SubStatus más comunes: # 0xC000006A = Contraseña incorrecta (usuario EXISTE) # 0xC0000064 = Usuario NO existe (enumeración) # 0xC000006F = Fuera del horario permitido # 0xC0000072 = Cuenta deshabilitada # 0xC0000234 = Cuenta bloqueada (por ataques previos) $fallos | Group-Object SubStatus | Sort-Object Count -Desc | ForEach-Object {{ $sig = switch ($_.Name) {{ '0xc000006a' {{'Contraseña incorrecta (usuario existe)'}} '0xc0000064' {{'Usuario NO existe (enumeración)'}} '0xc0000072' {{'Cuenta deshabilitada'}} '0xc0000234' {{'Cuenta bloqueada (bruteforce previo)'}} default {{"Código: $($_.Name)"}} }} [PSCustomObject]@{{ Significado=$sig; Total=$_.Count }} }} | Format-Table -AutoSize
4
Detectar éxito tras los fallos (brute force completado) CRÍTICO
Detectar login exitoso desde IP atacante
$ips_atacantes = $fallos.IP_Origen | Sort-Object -Unique $exitos = Get-WinEvent -FilterHashtable @{{ LogName='Security'; Id=4624; StartTime=$inicio }} | ForEach-Object {{ [PSCustomObject]@{{ Tiempo = $_.TimeCreated Usuario = $_.Properties[5].Value IP_Origen= $_.Properties[18].Value LogonType= $_.Properties[8].Value }} }} | Where-Object {{ $_.IP_Origen -in $ips_atacantes }} if ($exitos) {{ Write-Host "ALERTA CRITICA: login exitoso desde IP atacante!" -ForegroundColor Red $exitos | Format-Table -AutoSize }} else {{ Write-Host "Sin logins exitosos desde IPs atacantes" -ForegroundColor Green }}
❓ Pregunta
Encuentras 500 eventos 4625 con SubStatus 0xC0000064 desde la IP 45.33.32.156. ¿Qué técnica indica y por qué la diferencia con 0xC000006A es importante?
💡 Piensa en qué hace un atacante antes de intentar la contraseña correcta.
Ver respuesta
0xC0000064 indica que el usuario no existe: enumeración de usuarios para descubrir qué cuentas son válidas, típicamente previa a un password spraying. 0xC000006A indica usuario válido con contraseña incorrecta, mucho más peligroso porque el atacante ya sabe qué cuentas existen y está adivinando la contraseña.
👤
Ejercicio 5 — Gestión de Cuentas y Privilegios
Objetivo: detectar creación de cuentas no autorizadas y escalada de privilegios
🚨 ESCENARIO — CUENTA BACKDOOR
El viernes a las 23:47 se creó la cuenta 'support_temp' y se añadió al grupo Administrators. Nadie del equipo de TI la recuerda. Reconstruye quién la creó y desde dónde.
👤EVENT IDs DE GESTIÓN DE CUENTAS
Event IDDescripciónRelevancia
4720Cuenta de usuario creadaBackdoor de cuenta
4726Cuenta eliminadaBorrado de evidencia
4738Cuenta modificadaCambio de contraseña, flags
4740Cuenta bloqueadaConfirma ataque previo
4728Miembro añadido a grupo global (AD)Escalada (Domain Admins)
4732Miembro añadido a grupo localEscalada (Administrators)
1
Detectar creación de cuentas BÚSQUEDA
Buscar cuentas creadas recientemente
$hace7dias = (Get-Date).AddDays(-7) Get-WinEvent -FilterHashtable @{{ LogName='Security'; Id=4720; StartTime=$hace7dias }} | ForEach-Object {{ [PSCustomObject]@{{ Tiempo = $_.TimeCreated Nueva_Cuenta = $_.Properties[0].Value # TargetUserName Creada_Por = $_.Properties[4].Value # SubjectUserName Logon_ID = $_.Properties[7].Value # Para correlaci&oacute;n }} }} | Format-Table -AutoSize
2
Verificar adición al grupo Administrators ESCALADA
Detectar adición al grupo Administrators
# Event ID 4732 - grupo local Get-WinEvent -FilterHashtable @{{LogName='Security'; Id=4732}} | Where-Object {{ $_.Properties[2].Value -like '*Admin*' }} | ForEach-Object {{ [PSCustomObject]@{{ Tiempo = $_.TimeCreated Miembro = $_.Properties[0].Value Grupo = $_.Properties[2].Value Por_Quien = $_.Properties[6].Value }} }} | Format-Table -AutoSize # Para dominio - Event ID 4728 (grupos globales) Get-WinEvent -FilterHashtable @{{LogName='Security'; Id=4728}} | Where-Object {{ $_.Properties[2].Value -like '*Domain Admin*' }} | ForEach-Object {{ Write-Host "ALERTA: $($_.Properties[0].Value) -> $($_.Properties[2].Value)" -ForegroundColor Red }}
3
Rastrear la sesión origen por Logon ID CORRELACIÓN
Rastrear sesión por Logon ID
$logonId = '0x1a2b3c' # Del campo SubjectLogonId del evento 4720 Get-WinEvent -FilterHashtable @{{LogName='Security'; Id=4624}} | Where-Object {{ $_.Properties[7].Value -eq $logonId }} | ForEach-Object {{ Write-Host "Sesi&oacute;n origen:" Write-Host " Usuario: $($_.Properties[5].Value)" Write-Host " IP: $($_.Properties[18].Value)" Write-Host " Tipo: $($_.Properties[8].Value) (10=RDP, 3=Red)" Write-Host " Hora: $($_.TimeCreated)" }}
❓ Pregunta
El evento 4720 muestra que la cuenta fue creada por SYSTEM (SubjectLogonId = 0x3e7). ¿Es más preocupante que si la creara un usuario normal?
💡 0x3e7 es el Logon ID fijo de la sesión SYSTEM. ¿Qué tipo de proceso corre como SYSTEM?
Ver respuesta
Es significativamente más preocupante. Que SYSTEM cree una cuenta indica: (1) explotación de vulnerabilidad de elevación de privilegios, (2) un servicio malicioso corriendo como SYSTEM, (3) malware con privilegios de sistema. Investigar: Event ID 4688 alrededor de esa hora buscando procesos sospechosos ejecutados como SYSTEM.
⚙
Ejercicio 6 — Ejecución de Procesos Sospechosos (4688)
Objetivo: detectar malware, LOLBins y PowerShell malicioso
📌 REQUISITOEl Event ID 4688 requiere auditoría de Process Creation habilitada + command line auditing activado (Ejercicio de Configuración). Sin esto el campo CommandLine estará vacío.
1
Detectar comandos de reconocimiento RECONOCIMIENTO
Buscar herramientas de reconocimiento
$recon = @('whoami','net user','net group','net localgroup', 'ipconfig','systeminfo','tasklist','netstat', 'nltest','wmic','reg query','dsquery') Get-WinEvent -FilterHashtable @{{ LogName='Security'; Id=4688 StartTime=(Get-Date).AddHours(-24) }} | ForEach-Object {{ $cmd = $_.Properties[8].Value $usr = $_.Properties[1].Value $padre = $_.Properties[13].Value foreach ($r in $recon) {{ if ($cmd -like "*$r*") {{ Write-Host "[RECON] $r" -ForegroundColor Yellow Write-Host " $($_.TimeCreated) | Usuario: $usr" Write-Host " Padre: $padre" Write-Host " CMD: $cmd" }} }} }}
2
Detectar LOLBins LIVING-OFF-THE-LAND
Detectar LOLBins comunes
# Ejecutables legítimos abusados con fines maliciosos $lol = @('certutil','mshta','regsvr32.exe','wscript', 'cscript','rundll32','bitsadmin','expand.exe') Get-WinEvent -FilterHashtable @{{LogName='Security'; Id=4688}} | ForEach-Object {{ $proc = [IO.Path]::GetFileName($_.Properties[5].Value).ToLower() if ($proc -in $lol) {{ [PSCustomObject]@{{ Hora = $_.TimeCreated Usuario = $_.Properties[1].Value LOLBin = $proc CmdLine = $_.Properties[8].Value Padre = $_.Properties[13].Value }} }} }} | Format-Table -AutoSize -Wrap
3
Detectar PowerShell sospechoso POWERSHELL ABUSE
Buscar PowerShell con parámetros sospechosos
# -EncodedCommand (-enc) : ejecuta base64 (evasion de logging) # -WindowStyle Hidden : oculta ventana # IEX / DownloadString : descarga y ejecuta # bypass : evade política de ejecución Get-WinEvent -FilterHashtable @{{LogName='Security'; Id=4688}} | Where-Object {{ $c = $_.Properties[8].Value $c -match 'powershell' -and ( $c -match '-[Ee][Nn][Cc]' -or $c -match 'IEX|Invoke-Expression' -or $c -match 'DownloadString|DownloadFile' -or $c -match '-[Ww]indow[Ss]tyle\s+[Hh]idden' -or $c -match 'bypass' ) }} | ForEach-Object {{ Write-Host "[PS SOSPECHOSO] $($_.TimeCreated)" -ForegroundColor Red Write-Host " Usuario: $($_.Properties[1].Value)" Write-Host " CMD: $($_.Properties[8].Value)" -ForegroundColor Yellow }}
❓ Pregunta
En los logs de 4688 ves que excel.exe tiene como hijo a powershell.exe, que ejecuta cmd.exe /c whoami. ¿Qué técnica indica?
💡 Piensa en qué hace Excel para ejecutar PowerShell. ¿Macros?
Ver respuesta
Macro maliciosa de Excel (Maldoc / VBA macro attack). El flujo clásico: documento Office → shell → reconocimiento. El atacante envía un documento con macro que, al habilitarse, descarga y ejecuta malware. La cadena padre-hijo es uno de los indicadores más fiables. Otros sospechosos: winword.exe → powershell.exe, outlook.exe → cmd.exe.
📡
Ejercicio 7 — Servicios y Mecanismos de Persistencia
Objetivo: detectar servicios maliciosos y tareas programadas
📡EVENT IDs DE PERSISTENCIA
Event IDCanalDescripción
4697SecurityServicio instalado en el sistema
7045SystemNuevo servicio instalado (incluye ruta del ejecutable)
7040SystemTipo de inicio de servicio cambiado
4698SecurityTarea programada creada
4702SecurityTarea programada modificada
1102SecurityLog de seguridad borrado — anti-forense crítico
104SystemLog del sistema borrado — anti-forense crítico
1
Detectar instalación de servicios SERVICIOS
Buscar servicios instalados
# Event ID 7045 del canal System (más detallado que 4697) Get-WinEvent -FilterHashtable @{{LogName='System'; Id=7045}} | ForEach-Object {{ [PSCustomObject]@{{ Tiempo = $_.TimeCreated Nombre = $_.Properties[0].Value # ServiceName Ruta = $_.Properties[1].Value # ImagePath Inicio = $_.Properties[2].Value # StartType Cuenta = $_.Properties[4].Value # AccountName }} }} | Sort-Object Tiempo -Desc | Format-Table -AutoSize -Wrap # RUTAS SOSPECHOSAS: # C:\Users\*\AppData\Temp\... # C:\ProgramData\... # Nombres que imitan servicios (svchost32.exe, lsass.exe)
2
Detectar tareas programadas SCHEDULED TASKS
Buscar tareas creadas recientemente
# Event ID 4698 - Tarea programada creada Get-WinEvent -FilterHashtable @{{LogName='Security'; Id=4698}} | ForEach-Object {{ [PSCustomObject]@{{ Tiempo = $_.TimeCreated Usuario = $_.Properties[1].Value Tarea = $_.Properties[4].Value }} }} | Sort-Object Tiempo -Desc | Format-Table -AutoSize
3
Detectar borrado de logs (anti-forense) ANTI-FORENSICS
Detectar borrado de logs
# Event ID 1102 - Log de Seguridad borrado Get-WinEvent -FilterHashtable @{{LogName='Security'; Id=1102}} | ForEach-Object {{ Write-Host "CRITICO: Log BORRADO" -ForegroundColor Red Write-Host " Cuando: $($_.TimeCreated)" Write-Host " Por quien: $($_.Properties[1].Value)" }} # Event ID 104 - Log del Sistema borrado Get-WinEvent -FilterHashtable @{{LogName='System'; Id=104}} | ForEach-Object {{ Write-Host "CRITICO: Log SISTEMA borrado - $($_.TimeCreated)" -ForegroundColor Red }}
❓ Pregunta
Encuentras Event ID 7045 con ImagePath = C:\Users\Public\svchost32.exe. ServiceName = 'Windows Update Helper'. ¿Qué te llama la atención?
💡 Fijate en la ruta, el nombre del ejecutable y el nombre del servicio.
Ver respuesta
Múltiples alarmas: (1) Ruta sospechosa: servicios legítimos de Windows están en System32, nunca en Users\Public. (2) svchost32.exe imita svchost.exe: el real nunca tiene '32'. (3) 'Windows Update Helper' no existe como servicio nativo. Para confirmar: calcular SHA-256 en VirusTotal, verificar firma digital, buscar en 4688 si fue creado por otro proceso.
🔗
Ejercicio 8 — Correlación de Eventos y Línea de Tiempo
Objetivo: reconstruir la secuencia completa de un incidente
🚨 ESCENARIO — INCIDENTE COMPLETO
El servidor muestra actividad inusual el martes por la noche. Reconstruye: (1) cómo entró el atacante, (2) reconocimiento, (3) escalada de privilegios, (4) persistencia, (5) borrado de evidencia.
1
Construir una línea de tiempo unificada TIMELINE
Script de timeline de seguridad
$inicio = (Get-Date).AddDays(-2) $IDS_SEC = @(1102,4624,4625,4648,4672,4688,4697,4698,4720,4728,4732) $IDS_SYS = @(7045,7040,104) $tl = @() foreach ($id in $IDS_SEC) {{ try {{ Get-WinEvent -FilterHashtable @{{LogName='Security';Id=$id;StartTime=$inicio}} -EA Stop | ForEach-Object {{ $tl += [PSCustomObject]@{{ Tiempo=$_.TimeCreated; EID=$id; Canal='Security' Desc=$_.Message.Split('.')[0].Trim().Substring(0,[Math]::Min(75,$_.Message.Length)) }} }} }} catch {{}} }} foreach ($id in $IDS_SYS) {{ try {{ Get-WinEvent -FilterHashtable @{{LogName='System';Id=$id;StartTime=$inicio}} -EA Stop | ForEach-Object {{ $tl += [PSCustomObject]@{{Tiempo=$_.TimeCreated;EID=$id;Canal='System' Desc=$_.Message.Split('.')[0].Trim().Substring(0,[Math]::Min(75,$_.Message.Length))}} }} }} catch {{}} }} $tl | Sort-Object Tiempo | Format-Table Tiempo,EID,Canal,Desc -AutoSize -Wrap $tl | Sort-Object Tiempo | Export-Csv 'C:\Forensics\timeline.csv' -NoTypeInformation
2
Rastrear una sesión completa por Logon ID CORRELACIÓN
Rastrear acciones de una sesión
$logonId = '0x1234ab' # Del campo LogonID del evento 4624 sospechoso # Procesos creados en esa sesi&oacute;n Get-WinEvent -FilterHashtable @{{LogName='Security'; Id=4688}} | Where-Object {{ $_.Properties[3].Value -eq $logonId }} | ForEach-Object {{ Write-Host "PROCESO: $($_.Properties[5].Value)" Write-Host "CMDLINE: $($_.Properties[8].Value)" Write-Host "HORA: $($_.TimeCreated)" Write-Host "" }} # Cuentas creadas en esa sesi&oacute;n Get-WinEvent -FilterHashtable @{{LogName='Security'; Id=4720}} | Where-Object {{ $_.Properties[7].Value -eq $logonId }} | ForEach-Object {{ Write-Host "CUENTA CREADA: $($_.Properties[0].Value)" -ForegroundColor Red }}
❓ Pregunta
En la sesión correlacionada por Logon ID ves: net user, net localgroup, whoami /all, creación de cuenta, adición a Administrators. ¿Qué fases de MITRE ATT&CK representa cada acción?
💡 MITRE ATT&CK organiza las técnicas en Tácticas.
Ver respuesta
net user/localgroup/whoami → Discovery (TA0007), Account Discovery (T1087). Creación de cuenta → Persistence (TA0003), Create Account (T1136.001). Añadir a Administrators → Privilege Escalation (TA0004), Account Manipulation (T1098). Logon Type 3 sugiere movimiento lateral (TA0008).
💻
Ejercicio 9 — Automatización con PowerShell
Objetivo: scripts reutilizables para análisis eficiente y automatizado
1
Métodos de filtrado de Get-WinEvent FUNDAMENTOS
Get-WinEvent: los 4 métodos
# MÉTODO 1: FilterHashtable (m&aacute;s r&aacute;pido) Get-WinEvent -FilterHashtable @{{ LogName='Security'; Id=4624 StartTime=(Get-Date).AddHours(-24) }} # MÉTODO 2: FilterXml (control total con XPath) $x = '<QueryList><Query Id="0" Path="Security"><Select Path="Security">*[System[(EventID=4625)]]</Select></Query></QueryList>' Get-WinEvent -FilterXml $x # MÉTODO 3: Archivo .evtx offline Get-WinEvent -Path 'C:\Evidence\Security.evtx' -FilterHashtable @{{Id=4624}} # MÉTODO 4: Remoto (requiere WinRM) Get-WinEvent -ComputerName 'SERVER01','DC01' -FilterHashtable @{{LogName='Security';Id=4720}}
2
Script de triáje rápido de seguridad TRIAGE
Script de triáje completo
# ============================================ # TRIAJE RAPIDO DE SEGURIDAD # GhostAcademy - unfantasmaenelsistema.com # ============================================ param([int]$H=24, [string]$Equipo=$env:COMPUTERNAME) Write-Host "=== TRIAJE: $Equipo | Ultimas $H horas ==" -ForegroundColor Cyan $ini=(Get-Date).AddHours(-$H) # [1] Fallos Write-Host "`n[1] FALLOS 4625:" -ForegroundColor Yellow try {{ $f=Get-WinEvent -CN $Equipo -FH @{{LogName='Security';Id=4625;StartTime=$ini}} -EA Stop Write-Host " Total: $($f.Count)" $f|Group-Object {{$_.Properties[19].Value}}|Sort Count -Desc|Select -F 5| %{{Write-Host " IP $($_.Name): $($_.Count)"}} }} catch {{Write-Host " Sin fallos"}} # [2] Cuentas creadas Write-Host "`n[2] CUENTAS 4720:" -ForegroundColor Yellow try {{ $c=Get-WinEvent -CN $Equipo -FH @{{LogName='Security';Id=4720;StartTime=$ini}} -EA Stop if($c){{Write-Host " ALERTA: $($c.Count) cuentas!" -ForegroundColor Red $c|%{{Write-Host " $($_.Properties[0].Value) por $($_.Properties[4].Value)"}} }} else{{Write-Host " Ninguna"}} }} catch {{Write-Host " Sin acceso"}} # [3] Servicios Write-Host "`n[3] SERVICIOS 7045:" -ForegroundColor Yellow try {{ $s=Get-WinEvent -CN $Equipo -FH @{{LogName='System';Id=7045;StartTime=$ini}} -EA Stop if($s){{Write-Host " ALERTA: $($s.Count) servicios!" -ForegroundColor Red $s|%{{Write-Host " $($_.Properties[0].Value): $($_.Properties[1].Value)"}} }} else{{Write-Host " Ninguno"}} }} catch {{}} # [4] Logs borrados Write-Host "`n[4] LOGS BORRADOS:" -ForegroundColor Yellow try {{ $b=Get-WinEvent -CN $Equipo -FH @{{LogName='Security';Id=1102;StartTime=$ini}} -EA Stop if($b){{Write-Host " CRITICO: LOGS BORRADOS!" -ForegroundColor Red}} else{{Write-Host " OK"}} }} catch {{Write-Host " OK"}} Write-Host "`n=== FIN TRIAJE ===" -ForegroundColor Cyan
3
Analizar múltiples hosts en paralelo ESCALA
Análisis en paralelo de múltiples servidores
$servidores = @('SRV01','SRV02','DC01','FILESERVER') $resultados = $servidores | ForEach-Object -Parallel {{ $srv = $_ $ini = (Get-Date).AddHours(-24) try {{ $fallos = (Get-WinEvent -CN $srv -FH @{{ LogName='Security'; Id=4625; StartTime=$ini }} -EA Stop).Count [PSCustomObject]@{{Servidor=$srv; Fallos4625=$fallos; Estado='OK'}} }} catch {{ [PSCustomObject]@{{Servidor=$srv; Fallos4625=0; Estado='Sin acceso'}} }} }} -ThrottleLimit 5 $resultados | Sort-Object Fallos4625 -Desc | Format-Table -AutoSize
❓ Pregunta
¿Cuál es la diferencia entre FilterHashtable y FilterXml en Get-WinEvent? ¿Cuándo usar cada uno?
💡 Piensa en flexibilidad vs velocidad y qué permite filtrar cada uno.
Ver respuesta
FilterHashtable es más rápido porque Windows filtra a nivel del motor de logging antes de devolver datos — ideal para filtros simples (por ID, fecha, nivel). FilterXml con XPath permite filtrar por valores de campos dentro del EventData (ej: solo eventos con un TargetUserName específico o una IP concreta) — más flexible pero algo más lento. Regla práctica: FilterHashtable para volumen rápido, luego Where-Object o FilterXml cuando necesitas precisión de campo.
📚
Referencia: Event IDs de Seguridad Esenciales
Cheat sheet para SOC analysts y DFIR
Event IDCanalDescripciónTTPs relacionadas
1102SecurityLog de auditoría borradoAnti-forensics
104SystemLog del sistema borradoAnti-forensics
4624SecurityInicio de sesión correcto — ver Logon TypeAcceso inicial, movimiento lateral
4625SecurityError de inicio de sesiónFuerza bruta, password spraying
4634SecurityCierre de sesiónDuración de sesiones
4648SecurityInicio con credenciales explícitasMovimiento lateral, runas, PsExec
4672SecurityPrivilegios especiales asignadosUso de cuentas admin
4688SecurityNuevo proceso creado (necesita configuración)Ejecución de malware, LOLBins
4697SecurityServicio instaladoPersistencia como servicio
4698SecurityTarea programada creadaPersistencia por scheduled task
4720SecurityCuenta de usuario creadaPersistencia de cuenta backdoor
4726SecurityCuenta eliminadaEliminación de evidencia
4728SecurityMiembro añadido a grupo global (AD)Escalada (Domain Admins)
4732SecurityMiembro añadido a grupo localEscalada (Administrators)
4740SecurityCuenta bloqueadaConfirma ataque de fuerza bruta
4768SecurityKerberos TGT solicitadoGolden Ticket detection, AS-REP Roasting
4769SecurityTicket de servicio Kerberos solicitadoKerberoasting (muchos + RC4=0x17)
4771SecurityFallo pre-auth KerberosFuerza bruta en dominio
4776SecurityValidación NTLMPass-the-Hash, NTLM relay
7045SystemNuevo servicio instaladoPersistencia como servicio
4104PS/OperationalScriptBlock logging — contenido completo del scriptScripts ofuscados, fileless malware
🔑
Tipos de Inicio de Sesión (Logon Types)
Campo crítico en eventos 4624 y 4625 — determina el vector de acceso
TipoNombreDescripciónRelevancia forense
2InteractiveLogon físico en la consola (teclado + pantalla)Acceso físico o KVM
3NetworkAcceso de red: SMB, WMI, recursos compartidosMovimiento lateral, acceso a shares
4BatchTarea programada ejecutada por el schedulerPersistencia por scheduled task
5ServiceInicio de sesión de un servicio de WindowsServicios maliciosos
7UnlockDesbloqueo de estación de trabajoActividad del usuario
8NetworkCleartextCredenciales en texto plano por la redRiesgo captura de credenciales
9NewCredentialsrunas con /netonlyMovimiento lateral
10RemoteInteractiveAcceso RDP — escritorio remoto interactivoCrítico — RDP desde IPs externas
11CachedInteractiveLogon con credenciales cacheadas (sin DC)Sistemas fuera de red de dominio
⚠
Códigos de Error de Autenticación (SubStatus)
Campo del Event ID 4625 que explica el motivo del fallo
SubStatusSignificadoInterpretación
0xC000006ABAD_PASSWORDContraseña incorrecta — el usuario EXISTE. Fuerza bruta o spraying.
0xC0000064NO_SUCH_USEREl usuario NO EXISTE. Enumeración de usuarios o typo.
0xC000006FINVALID_LOGON_HOURSFuera del horario permitido. Restricción horaria activa.
0xC0000070INVALID_WORKSTATIONAcceso desde equipo no autorizado.
0xC0000072ACCOUNT_DISABLEDCuenta deshabilitada. Reutilización de cuentas antiguas.
0xC0000234ACCOUNT_LOCKED_OUTCuenta bloqueada. Confirma fuerza bruta previa.
0xC0000193ACCOUNT_EXPIREDCuenta expirada.
0xC0000071PASSWORD_EXPIREDContraseña expirada. Normal en rotación de contraseñas.
🔧
Herramientas Recomendadas
Más allá del Visor de Eventos nativo
🔨HERRAMIENTAS GRATUITAS ESENCIALES
  • Hayabusa — github.com/Yamato-Security/hayabusa: aplica reglas Sigma automáticamente a .evtx y genera timelines. Muy recomendada para DFIR.
  • Chainsaw — github.com/WithSecureLabs/chainsaw: similar a Hayabusa, orientada a CTF y DFIR rápido.
  • DeepBlueCLI — github.com/sans-blue-team/DeepBlueCLI: script PowerShell que analiza logs buscando patrones de ataque conocidos.
  • FullEventLogView (NirSoft): vista unificada de múltiples .evtx con filtros avanzados. Portátil y gratuito.
  • Sysmon (Sysinternals/Microsoft): enriquece enormemente la telemetría. Gratuito.
  • Sigma Rules — github.com/SigmaHQ/sigma: formato estándar para reglas de detección compatibles con muchas plataformas.
  • EVTX Attack Samples — github.com/sbousseaden/EVTX-ATTACK-SAMPLES: logs reales de ataques para práctica.
✓ CONCLUSIÓN DEL LABORATORIOHas completado los 9 ejercicios. Ahora tienes las bases para: navegar el Event Viewer, configurar auditoría avanzada, analizar los Event IDs críticos, detectar fuerza bruta y password spraying, identificar cuentas maliciosas y escalada de privilegios, detectar LOLBins y persistencia, correlacionar eventos para reconstruir timelines de ataques, y automatizar todo con PowerShell y Get-WinEvent.
✓ Copiado