PowerShell para auditar logs de seguridad en Windows

Imagina que alguien pasó las últimas 48 horas intentando adivinar la contraseña de un usuario en tu servidor Windows. Sin monitoreo, nunca lo sabrías, hasta el día en que lo consiguiera. Windows registra todo esto en el Security Event Log. El problema es que el Event Viewer es lento, está lleno de clics y es imposible de automatizar. PowerShell resuelve eso en una línea.
Get-WinEvent: el cmdlet correcto para eventos de seguridad
Existe Get-EventLog (legado) y Get-WinEvent (moderno). Usa siempre Get-WinEvent: es significativamente más rápido en logs grandes, admite filtrado por hash directo en la consulta (sin traer todo a memoria primero) y ya no se sigue desarrollando en PowerShell 7+. Get-EventLog ni siquiera existe en PowerShell Core corriendo en Linux.
Para leer el Security Log necesitas una terminal elevada (Ejecutar como administrador). Si lo intentas sin privilegios, vas a recibir un error de acceso denegado: no es un bug, es el comportamiento esperado de un log que guarda datos sensibles de autenticación.
# Verificar los últimos 50 eventos del log de seguridad
Get-WinEvent -LogName Security -MaxEvents 50 | Select-Object TimeCreated, Id, MessageLos Event IDs que necesitas conocer
Windows tiene cientos de IDs de evento, pero para auditar seguridad en el día a día, unos pocos cubren la gran mayoría de los escenarios críticos:
- 4624 — Logon exitoso (cualquier inicio de sesión en la máquina)
- 4625 — Falla de logon (contraseña incorrecta, cuenta bloqueada, usuario inválido)
- 4634 / 4647 — Logoff (sesión finalizada)
- 4648 — Logon con credenciales explícitas (pass-the-hash, runas)
- 4688 — Nuevo proceso creado (requiere auditoría de creación de procesos activa)
- 4698 — Tarea programada creada (vector clásico de persistencia de malware)
- 4720 — Cuenta de usuario creada
- 4732 — Miembro agregado a grupo privilegiado (ej: Administradores)
- 4776 — Autenticación NTLM local (relevante para detectar ataques laterales)
Si administras Active Directory, agrega también el 4768 (solicitud de Kerberos TGT) y el 4771 (falla de preautenticación Kerberos) a tu lista de vigilancia.
Detectar logins fallidos en las últimas 24 horas
Este es el caso de uso más común. Cualquier servidor expuesto a internet acumula intentos de login constantemente, especialmente en el puerto 3389 (RDP) y en cuentas de servicio con contraseñas débiles.
# Listar fallas de logon de las últimas 24 horas
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4625
StartTime = (Get-Date).AddDays(-1)
} | ForEach-Object {
[PSCustomObject]@{
Hora = $_.TimeCreated
Usuario = $_.Properties[5].Value
IP = $_.Properties[19].Value
Motivo = $_.Properties[8].Value
}
} | Sort-Object Hora -DescendingEl acceso vía $_.Properties[n].Value extrae campos específicos del evento sin necesidad de parsear texto. Las propiedades del evento 4625 son fijas: el índice 5 es el nombre de usuario objetivo, el 19 es la dirección IP de origen, el 8 es el sub-estado de falla (código que indica si la cuenta no existe, la contraseña es incorrecta, la cuenta está bloqueada, etc.).
Identificar fuerza bruta: agrupar por IP atacante
Una o dos fallas pueden ser error humano. Cincuenta fallas desde la misma IP en diez minutos son fuerza bruta. PowerShell agrupa esto en segundos:
# Top 10 IPs con más fallas de logon (últimos 7 días)
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4625
StartTime = (Get-Date).AddDays(-7)
} | ForEach-Object {
$_.Properties[19].Value
} | Where-Object { $_ -ne '-' -and $_ -ne '' } |
Group-Object |
Sort-Object Count -Descending |
Select-Object -First 10 Count, NameUna IP que aparece con cientos de intentos es candidata inmediata para bloqueo en el firewall o en el Windows Firewall vía New-NetFirewallRule. El caso del ataque a Trellix y de varias otras operaciones de ransomware empezaron con fuerza bruta en cuentas expuestas sin protección adecuada.
Verificar tareas programadas creadas recientemente (persistencia)
Crear una tarea programada es uno de los mecanismos de persistencia más usados por el malware, y Windows registra cada creación con el evento 4698. Si tú no has creado tareas programadas manualmente, cualquier aparición de ese ID merece atención:
# Tareas programadas creadas en las últimas 48 horas
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4698
StartTime = (Get-Date).AddHours(-48)
} | Select-Object TimeCreated, MessageExportar reporte de auditoría a CSV
Para enviar por correo o archivar, basta con canalizar el resultado a Export-Csv. Esto funciona con cualquiera de los scripts anteriores: solo cambia el final del pipeline:
# Exportar fallas de logon a CSV
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4625
StartTime = (Get-Date).AddDays(-7)
} | ForEach-Object {
[PSCustomObject]@{
Hora = $_.TimeCreated
Usuario = $_.Properties[5].Value
IP = $_.Properties[19].Value
}
} | Export-Csv -Path ".\fallas-logon-$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation -Encoding UTF8El nombre del archivo incluye la fecha automáticamente vía Get-Date -Format 'yyyyMMdd'. Si nunca usaste esto, el post PowerShell para principiantes cubre los fundamentos de pipeline y formateo de objetos que hacen posibles estos scripts.
Activar auditoría de creación de procesos (evento 4688)
Por defecto, Windows no registra qué procesos se crearon, lo que deja un punto ciego enorme para detectar la ejecución de herramientas maliciosas. Para activarlo vía Group Policy localmente:
# Verificar política actual de auditoría de procesos
auditpol /get /subcategory:"Process Creation"
# Activar auditoría de creación de procesos (requiere admin)
auditpol /set /subcategory:"Process Creation" /success:enable /failure:enableDespués de activarlo, puedes combinar esto con filtros en el evento 4688 para detectar la ejecución de powershell.exe con argumentos codificados en base64, patrón clásico de ejecución de payload ofuscado. Para entornos corporativos, la recomendación es gestionar esto vía GPO centralizado e integrar los logs en un SIEM, pero incluso localmente ya es un paso significativo de visibilidad.
Conclusión
Los event logs existen en todo entorno Windows, pero permanecen invisibles sin herramientas para consultarlos de forma eficiente. Con Get-WinEvent y filtros por hash, obtienes reportes de seguridad en segundos, sin tercerizar eso en un producto caro. Si administras servidores Windows y todavía no tienes este tipo de verificación en tu checklist semanal, vale la pena empezar por los eventos 4625 y 4698: son los dos que con más frecuencia revelan algo que no debería estar pasando. Si quieres capas extra de monitoreo de red además de los logs locales, NextDNS con filtrado de DNS cifrado es un complemento práctico para entornos domésticos y pequeñas empresas. ¿Pasaste por alguna situación donde los logs ayudaron a identificar un problema? Cuéntanos en los comentarios.




Comentarios