inicio / r3v3la / capítulo 01
CAP. 01 forense · sistemas

Eventos de Windows

// en 3 líneas

Windows lleva un diario de lo que pasa en el equipo: quién entra, quién falla al intentarlo, qué se instala y quién toca las cuentas. Casi nadie lo lee, pero está ahí. Y si alguien lo borra, el borrado también queda apuntado.

El caso

Un lunes por la mañana todo parece normal: nadie ha notado nada raro y los equipos funcionan. Pero el registro de seguridad de uno de ellos cuenta otra historia. Durante la madrugada del domingo hay cientos de intentos de inicio de sesión fallidos, todos desde la misma dirección, probando nombres de usuario uno detrás de otro. Y luego, a las 3:14, uno que no falló: una sesión de escritorio remoto que nadie de la empresa abrió.

Nadie lo vio en su momento porque nadie estaba mirando. El rastro, sin embargo, estaba escrito con hora, usuario, tipo de acceso y origen. Este capítulo va de aprender a leer ese diario: los intentos, el acceso que sí prosperó y lo que pasó después.

La herramienta

El registro de eventos de Windows es el sistema que usa el propio sistema operativo, sus servicios y muchas aplicaciones para dejar constancia de lo que ocurre. Cada anotación es un evento con un identificador numérico (el Event ID), una fecha, un origen y un bloque de datos con los detalles.

Los eventos se agrupan en registros o canales. Para forense y defensa, los que más importan son estos:

RegistroQué guarda
SecurityInicios y cierres de sesión, cambios en cuentas y grupos, uso de privilegios, borrado del propio registro. Es el más valioso.
SystemServicios que se instalan, arrancan o paran, errores de controladores, apagados.
ApplicationLo que escriben las aplicaciones: errores, bloqueos, instalaciones.
Microsoft-Windows-PowerShell/OperationalBloques de código de PowerShell ejecutados, si está activado su registro.
Microsoft-Windows-TerminalServices-LocalSessionManager/OperationalSesiones de escritorio remoto (RDP): inicio, reconexión y desconexión, con el usuario y la IP de origen.

Físicamente son archivos .evtx que viven en C:\Windows\System32\winevt\Logs\. Se pueden copiar y analizar en otro equipo, que es justo lo que se hace en una investigación.

Plataforma
Windows (cliente y servidor)
Tipo
GUI (eventvwr.msc) y CLI (PowerShell, wevtutil)
Licencia
Incluido en Windows

Cómo se usa

Con el Visor de eventos

Pulsa Win + R, escribe eventvwr.msc y entra en Registros de Windows → Seguridad. Para no ahogarte en miles de líneas, usa Filtrar registro actual en el panel derecho y escribe los ID que buscas, por ejemplo 4625. En la pestaña Detalles de cada evento, la vista XML muestra todos los campos con su nombre.

Para el registro de seguridad necesitas abrirlo como administrador.

Qué revela

No hace falta memorizar cientos de ID. Con este puñado se reconstruye buena parte de lo que pasa en un equipo:

IDRegistroQué significa
4624SecurityInicio de sesión correcto.
4625SecurityInicio de sesión fallido.
4634 / 4647SecurityCierre de sesión (el 4647 es el que inicia el propio usuario).
4648SecurityInicio de sesión con credenciales explícitas, por ejemplo con runas.
4672SecuritySesión con privilegios especiales: alguien entró como administrador.
4688SecuritySe creó un proceso. Solo si la auditoría está activada.
4720SecuritySe creó una cuenta de usuario.
4732SecuritySe añadió un miembro a un grupo local, como Administradores.
1102SecuritySe borró el registro de seguridad.
1100SecurityEl servicio de registro de eventos se detuvo.
7045SystemSe instaló un servicio nuevo. Clásico en persistencia y movimiento lateral.
104SystemSe borró un registro distinto al de seguridad.
4104PowerShell/OperationalBloque de código de PowerShell ejecutado.
21 / 25TerminalServices-LocalSessionManagerInicio (21) o reconexión (25) de una sesión de escritorio remoto, con el usuario y la IP de origen.
41SystemEl equipo se apagó sin cerrar bien: corte de luz, cuelgue o apagado forzado (Kernel-Power).
6008SystemEl apagado anterior fue inesperado. Confirma lo que sugiere el 41.

El tipo de inicio de sesión

Un 4624 solo dice que alguien entró. El campo LogonType dice cómo, y ahí está la mitad de la historia:

TipoSignificado
2Interactivo: alguien delante del teclado.
3Red: acceso a una carpeta compartida o a un recurso remoto.
4 / 5Tarea programada / servicio.
7Desbloqueo de la sesión.
10Escritorio remoto (RDP).
11Credenciales en caché, sin contactar con el controlador de dominio.

Por qué falló

En un 4625, el campo SubStatus distingue entre alguien que se equivoca y alguien que está probando:

CódigoMotivoLectura
0xC000006AContraseña incorrectaEl usuario existe. Si se repite mucho, fuerza bruta sobre una cuenta.
0xC0000064El usuario no existeAlguien está adivinando nombres de cuenta.
0xC0000234Cuenta bloqueadaLos intentos ya dispararon la política de bloqueo.
0xC0000072Cuenta deshabilitadaAlguien intenta usar una cuenta dada de baja.

El detalle que da nombre a la serie

Borrar el registro de seguridad no borra el rastro: genera un 1102 nuevo, con la hora y la cuenta que lo hizo. Y si el registro aparece vacío salvo ese evento, eso ya es una pregunta que responder. Quien intenta ocultar lo que hizo deja otra huella al hacerlo.

Con PowerShell

Toda esta lectura del diario se puede automatizar. Los comandos son largos, así que van plegados: ábrelos cuando los necesites.

Ver comandos de PowerShell

Consultas útiles

Abre PowerShell como administrador y carga primero esta pequeña función, que convierte los datos de cada evento en campos con nombre. Así no dependes de posiciones numéricas que cambian entre versiones de Windows:

# Convierte el bloque EventData de un evento en campos con nombre
function Get-EventData {
    param([Parameter(ValueFromPipeline)]$Evento)
    process {
        $xml   = [xml]$Evento.ToXml()
        $datos = [ordered]@{ Hora = $Evento.TimeCreated; Id = $Evento.Id }
        foreach ($d in $xml.Event.EventData.Data) { $datos[$d.Name] = $d.'#text' }
        [pscustomobject]$datos
    }
}

Inicios de sesión fallidos de las últimas 24 horas:

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddDays(-1)} -ErrorAction SilentlyContinue |
  Get-EventData |
  Select-Object Hora, TargetUserName, LogonType, IpAddress, SubStatus |
  Format-Table -AutoSize

¿Desde dónde vienen? Agrupa por origen y por usuario intentado:

$fallos = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -ErrorAction SilentlyContinue | Get-EventData
$fallos | Group-Object IpAddress      | Sort-Object Count -Descending | Select-Object Count, Name
$fallos | Group-Object TargetUserName | Sort-Object Count -Descending | Select-Object Count, Name

Inicios de sesión correctos por escritorio remoto (tipo 10):

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -ErrorAction SilentlyContinue |
  Get-EventData |
  Where-Object LogonType -eq '10' |
  Select-Object Hora, TargetUserName, IpAddress |
  Format-Table -AutoSize

El registro de Seguridad da el 4624, pero el escritorio remoto tiene además su propio canal, con el usuario y la IP de origen en cada sesión:

Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'; Id=21,25} -ErrorAction SilentlyContinue |
  Get-EventData |
  Select-Object Hora, Id, User, 'Address' |
  Format-Table -AutoSize

Apagados inesperados: cortes de luz, cuelgues o apagados forzados. El 41 y el 6008 se apoyan entre sí.

Get-WinEvent -FilterHashtable @{LogName='System'; Id=41,6008} -ErrorAction SilentlyContinue |
  Select-Object TimeCreated, Id, Message | Format-List

¿Alguien ha borrado registros?

# 1102: se borró el registro de seguridad
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=1102} -ErrorAction SilentlyContinue |
  Select-Object TimeCreated, Id, Message | Format-List

# 104: se borró otro registro (System, Application...)
Get-WinEvent -FilterHashtable @{LogName='System'; Id=104} -ErrorAction SilentlyContinue |
  Select-Object TimeCreated, Id, Message | Format-List

Sacar una copia para analizarla fuera

En una investigación no se trabaja sobre el equipo vivo. Exporta los registros y analiza la copia:

New-Item -ItemType Directory -Path C:\evidencia -Force | Out-Null
wevtutil epl Security    C:\evidencia\Security.evtx
wevtutil epl System      C:\evidencia\System.evtx
wevtutil epl "Microsoft-Windows-PowerShell/Operational" C:\evidencia\PowerShell-Operational.evtx
wevtutil epl "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" C:\evidencia\RDP-LocalSessionManager.evtx

# Leer una copia exportada
Get-WinEvent -Path C:\evidencia\Security.evtx -FilterXPath "*[System[EventID=4625]]" | Get-EventData

Activar lo que Windows no registra de fábrica

Un Windows recién instalado apunta los inicios de sesión, pero no registra qué programas se ejecutan ni el código de PowerShell completo, y su registro de seguridad es pequeño. Si quieres que el diario sirva cuando haga falta, hay que prepararlo antes:

# Ver la política de auditoría actual
auditpol /get /category:*

# Auditar la creación de procesos (evento 4688).
# Se usa el GUID porque el nombre de la subcategoría cambia con el idioma de Windows.
auditpol /set /subcategory:"{0CCE922B-69AE-11D9-BED3-505054503030}" /success:enable

# Incluir la línea de comandos completa en el 4688
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /f

# Registrar los bloques de código de PowerShell (evento 4104)
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 /f

# Ver el tamaño del registro de seguridad y subirlo a 1 GB
Get-WinEvent -ListLog Security | Select-Object LogName, MaximumSizeInBytes, RecordCount
wevtutil sl Security /ms:1073741824

En una empresa con dominio, esto se configura por GPO y no equipo a equipo. Lo de arriba sirve para tu equipo o tu laboratorio.

Practica

La mejor forma de aprender a leer el diario es escribir en él y luego buscarte. Haz estos ejercicios en una máquina virtual, nunca en un equipo de trabajo.

Ver los 4 ejercicios
Ejercicio 1 · Cázate a ti mismo

Provoca inicios de sesión fallidos y encuéntralos.

# Tres intentos contra una cuenta que no existe
1..3 | ForEach-Object { net use \\localhost\IPC$ /user:usuario_falso ClaveFalsa123 2>$null }

# Búscalos
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -MaxEvents 5 |
  Get-EventData | Select-Object Hora, TargetUserName, LogonType, SubStatus

¿Qué tipo de inicio de sesión aparece y por qué? ¿Qué SubStatus ves? Repite con tu usuario real y una contraseña equivocada y compara.

Ejercicio 2 · La cuenta que nadie creó

Simula la persistencia más básica: una cuenta nueva con privilegios.

net user soporte_it P4ssw0rd!Lab /add
net localgroup Administrators soporte_it /add   # en Windows en español: Administradores

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4720,4732} -MaxEvents 5 |
  Get-EventData | Format-List

# Limpieza
net user soporte_it /delete

¿Qué cuenta aparece como autora del cambio? Al borrarla, ¿qué evento nuevo se genera?

Ejercicio 3 · Borra las huellas

Haz lo que haría un intruso y comprueba qué queda.

# SOLO EN LA MÁQUINA VIRTUAL
wevtutil cl Security

Get-WinEvent -LogName Security -MaxEvents 5 | Select-Object TimeCreated, Id, Message | Format-List

¿Cuántos eventos quedan? ¿Qué te dice el 1102 sobre quién lo hizo?

Ejercicio 4 · Registros de un ataque real

Descarga registros .evtx de ataques documentados y analízalos como si llegaran de un cliente. El repositorio EVTX-ATTACK-SAMPLES los tiene clasificados por técnica.

# Con Hayabusa: línea de tiempo con las detecciones de sus reglas
hayabusa.exe csv-timeline -d .\EVTX-ATTACK-SAMPLES -o timeline.csv

# Con EvtxECmd: todos los eventos normalizados a CSV
EvtxECmd.exe -d .\EVTX-ATTACK-SAMPLES --csv .\salida

Elige una carpeta, por ejemplo la de movimiento lateral, e intenta contar qué pasó solo con los eventos antes de leer su nombre.