Playbooks SOC L1 — BTL1 Aligned
Doce playbooks operativos para los ataques que más se ven en cola SIEM de un SOC L1. Cada playbook sigue el ciclo PICERL y la terminología del temario BTL1, con queries para Splunk (SPL) y un apartado de Microsoft Sentinel (KQL) para entrevistas.
Cómo usar este documento
- En el SOC: abre el playbook del tipo de alerta que tengas en cola y sigue las fases en orden.
- Para entrevista técnica: los playbooks 01, 02, 03, 04 y 05 son los que más caen — domínalos a fondo.
- Para el portfolio GitHub: cada playbook se puede convertir en un
.mdindividual en/playbooks/. - Enfoque BTL1: las tareas de un analista L1 se concentran en la fase de Identificación (triaje, análisis, escalado). Contención inicial sí; erradicación completa y recovery escalan a L2/L3.
Catálogo de playbooks
Ataques contra autenticación: RDP, SSH, OWA, M365, VPN.
Acceso InicialAnálisis de email, cabeceras, adjuntos y URLs maliciosas.
Acceso InicialDetección de infección, análisis de proceso y triaje de hash.
EjecuciónCifrado masivo, shadow copies, contención agresiva.
ImpactoPtH, PsExec, WMI, RDP entre hosts internos.
MovimientoSalida anómala de datos vía HTTPS, DNS, cloud storage.
ImpactoSQLi, XSS, LFI/RFI, web shells contra apps expuestas.
ExplotaciónUsuario interno: abuso, fuga, accesos fuera de horario.
InternoBeaconing, DNS tunneling, tráfico hacia C2.
C2UAC bypass, token impersonation, abuso de servicios.
EscaladaVolumetric, SYN flood, HTTP flood, amplificación.
DisponibilidadCompromiso vía proveedor, software o dependencia.
Acceso InicialEl marco PICERL en cada playbook
Las seis fases que estructuran toda la respuesta a incidentes
Resumen de las 6 fases
1. Preparation — Preparación
Fase continua. Asegurarse de que la organización está lista antes de que ocurra un incidente: planes IRP, playbooks (este documento), formación del CSIRT, configuración de herramientas (SIEM, EDR, IDS/IPS), procedimientos de escalado y hardening.
2. Identification — Identificación
Detectar el incidente, determinar naturaleza y alcance. Aquí está el grueso del trabajo del L1: monitorizar alertas SIEM/EDR, analizar logs, hacer triaje (TP/FP), recolectar evidencia inicial respetando el orden de volatilidad y documentar.
3. Containment — Contención
Limitar el impacto y evitar propagación. Aislamiento de hosts (network containment del EDR), bloqueo de cuentas, bloqueo de IPs/dominios en firewall/proxy/DNS. Hay contención a corto plazo (parar la hemorragia) y a largo plazo (preparar el entorno limpio para recovery).
4. Eradication — Erradicación
Eliminar la causa raíz y todos los artefactos: malware, cuentas no autorizadas, backdoors, persistencia. Parchear las vulnerabilidades explotadas. A menudo implica reimaginar los sistemas afectados desde imagen limpia.
5. Recovery — Recuperación
Restaurar servicio normal: backups limpios, sistemas reconstruidos en producción, pruebas exhaustivas y monitorización intensiva de los hosts recuperados para detectar reinfección.
6. Lessons Learned — Lecciones aprendidas
Reunión post-incidente, informe final, análisis de causa raíz, identificación de brechas en controles y procedimientos. Actualización de playbooks, reglas SIEM, configuraciones y formación. Aquí cierra el ciclo y vuelve a Preparación.
Brute Force
Intentos masivos de autenticación contra RDP, SSH, OWA, M365, VPN o consolas web
Identificación · Triaje inicial
Lo primero ante una alerta de brute force es confirmar si es TP o FP. Muchos FP vienen de usuarios con contraseñas caducadas, apps con credenciales hardcodeadas o scanners legítimos. La clave está en el patrón: una IP única intentando 50 cuentas distintas (spraying) es muy distinto de un usuario fallando 10 veces (probable olvido).
Preguntas clave del triaje
- ¿Cuántos intentos fallidos? ¿En qué ventana de tiempo?
- ¿Una IP origen o muchas? ¿Geolocalización (impossible travel)?
- ¿Una cuenta objetivo o varias? (1→muchas = spraying; muchas→1 = password guessing)
- ¿Hubo algún éxito (4624) tras los fallos (4625)? — esto cambia la severidad a CRÍTICA
- ¿La cuenta atacada es privilegiada (Domain Admin, servicio crítico)?
Detección · SPL (Splunk)
Brute force clásico contra Windows: 10+ fallos (4625) de la misma IP origen contra una cuenta en 10 minutos.
index=wineventlog EventCode=4625
| bin _time span=10m
| stats count dc(Account_Name) as users_targeted values(Account_Name) as accounts by _time, src_ip
| where count >= 10
| sort - count
Password spraying: misma IP intentando muchas cuentas distintas con pocos intentos cada una (evade lockouts).
index=wineventlog EventCode=4625
| bin _time span=30m
| stats dc(Account_Name) as users_targeted count by src_ip
| where users_targeted >= 5 AND count >= 10
| sort - users_targeted
Brute force exitoso: serie de 4625 seguidos de un 4624 desde la misma IP/cuenta. Esto siempre escala.
index=wineventlog (EventCode=4624 OR EventCode=4625) Logon_Type IN (3,10)
| transaction src_ip Account_Name maxspan=15m
| where eventcount > 10 AND searchmatch("EventCode=4624")
| table _time src_ip Account_Name eventcount
Brute force contra SSH (sshd auth logs).
index=linux source="/var/log/auth.log" "Failed password"
| rex "Failed password for (invalid user )?(?<user>\S+) from (?<src_ip>\S+)"
| bin _time span=10m
| stats count dc(user) as users by _time, src_ip
| where count >= 15
Detección · KQL (Sentinel / Defender)
SecurityEvent
| where EventID == 4625
| where TimeGenerated > ago(1h)
| summarize FailedCount = count(),
TargetedAccounts = dcount(TargetUserName),
Accounts = make_set(TargetUserName, 20)
by IpAddress, bin(TimeGenerated, 10m)
| where FailedCount >= 10
| order by FailedCount desc
Sign-ins fallidos contra M365 / Entra ID seguidos de un éxito.
SigninLogs
| where TimeGenerated > ago(6h)
| summarize Failed = countif(ResultType != "0"),
Success = countif(ResultType == "0")
by UserPrincipalName, IPAddress, bin(TimeGenerated, 30m)
| where Failed >= 10 and Success >= 1
| order by TimeGenerated desc
Contención inmediata
- Bloquear IP origen en firewall perimetral / WAF si es externa.
- Forzar reset de contraseña de la cuenta si hubo éxito o si la cuenta es privilegiada.
- Habilitar MFA si no estaba activo (especialmente OWA/M365).
- Desactivar la cuenta temporalmente si hay sospecha alta de compromiso.
- Revisar sesiones activas (token theft, sesiones desde la IP atacante) y revocarlas.
Criterio de escalado a L2
- Hubo autenticación exitosa después del ataque.
- La cuenta es privilegiada (admin de dominio, cuenta de servicio crítica).
- Patrón sostenido en el tiempo (>24h) o desde múltiples IPs coordinadas.
- Indicios de movimiento lateral o ejecución posterior al login → ver PB-05.
Evidencia a recoger
| Artefacto | Origen | Para qué |
|---|---|---|
| Eventos 4624 / 4625 / 4740 | Windows Security log | Pivote temporal y por cuenta |
| Logs sshd / auth.log | Linux /var/log/auth.log | SSH brute force |
| SigninLogs | Entra ID | Spray contra M365 |
| Logs VPN / Firewall | Concentrador VPN, perimetral | Brute force externo |
| Geolocalización IP | Reputación (VirusTotal, AbuseIPDB) | Atribución y bloqueo |
Triaje: identificar IP origen → ¿una o varias? → ¿hubo 4624 posterior? → si no, bloqueo IP + monitorizar; si sí, escalar como compromiso confirmado y revocar sesiones.
Phishing
Análisis de email sospechoso: cabeceras, cuerpo, URLs y adjuntos para extraer IoCs
Identificación · Artefactos a examinar
El objetivo es determinar si el correo es malicioso y, si lo es, extraer IoCs para detección, bloqueo y threat intel. Cuatro bloques de artefactos según BTL1: cabeceras, cuerpo, URLs y adjuntos.
1. Cabeceras (Headers)
From,Reply-To,Return-Path— frecuentemente divergen en phishing.Received— se lee de abajo arriba para trazar la ruta.Authentication-Results— SPF / DKIM / DMARC. Un FAIL es bandera roja.- IP de origen real (último Received) → reputación.
2. Cuerpo (Body)
- Urgencia o amenaza ("tu cuenta será bloqueada").
- Errores gramaticales, saludos genéricos.
- Peticiones inusuales (credenciales, transferencias).
- Estilo inconsistente con comunicaciones previas.
3. URLs y enlaces
- Dominios engañosos (
paypaI.com, typosquatting). - Acortadores que ocultan destino (Bitly, TinyURL).
- IPs directas en lugar de dominios.
- Defang al documentar:
hxxp://malicious[.]com.
4. Adjuntos
- Extensiones peligrosas:
.exe .scr .bat .ps1 .js .vbs. - Office con macros:
.docm .xlsm .pptm. - Doble extensión:
factura.pdf.exe. - Archivos cifrados (evaden AV) con password en cuerpo.
Workflow de análisis
- Aislar el email en formato
.emlo.msgsin reenviar inline. - Cabeceras: pegar en MXToolbox Header Analyzer o Google Admin Toolbox. Verificar SPF/DKIM/DMARC.
- URLs: extraer (defanged), expandir acortadores con urlscan.io, comprobar reputación en VirusTotal + URLhaus.
- Adjuntos: calcular hash (MD5/SHA256), buscar en VirusTotal. Si no aparece → sandbox.
- Extraer IoCs: IPs, dominios, hashes, asuntos, direcciones email.
- Pivotar en SIEM: ¿quién más recibió esto? ¿alguien hizo clic?
Detección · SPL (Splunk)
Buscar quién más recibió un email con el mismo asunto o remitente.
index=email (sender="atacante@dominio-falso.com" OR subject="Factura urgente pendiente")
| stats count values(recipient) as destinatarios values(subject) as asuntos by sender
| sort - count
Detectar usuarios que hicieron clic en una URL maliciosa (proxy logs).
index=proxy url="*malicious-site.com*" OR url="*phishing-domain.tld*"
| stats count earliest(_time) as first_click latest(_time) as last_click by user, src_ip, url
| sort - count
Conexiones a un dominio recién registrado tras la entrega del correo.
index=dns OR index=proxy query="*.tld-sospechoso.*"
| stats count values(src_ip) as origenes by query
| where count > 0
| sort - count
Detección · KQL (Sentinel / Defender)
EmailEvents
| where TimeGenerated > ago(7d)
| where SenderFromAddress == "atacante@dominio-falso.com"
or Subject contains "Factura urgente"
| join kind=leftouter EmailUrlInfo on NetworkMessageId
| project TimeGenerated, RecipientEmailAddress, Subject, Url, DeliveryAction
| order by TimeGenerated desc
¿Alguien hizo clic en una URL del email malicioso?
UrlClickEvents
| where TimeGenerated > ago(7d)
| where Url contains "malicious-site.com"
| project TimeGenerated, AccountUpn, Url, ActionType, IPAddress
Contención y erradicación
- Purgar correo de todos los buzones (M365: Threat Explorer → Take action → Soft/Hard delete).
- Bloquear remitente y dominio en gateway de correo (Defender, Proofpoint, Mimecast).
- Bloquear URLs/IPs maliciosas en proxy/firewall/DNS.
- Bloquear hash de adjunto en EDR.
- Si alguien hizo clic e introdujo credenciales: reset password, revocar sesiones, MFA enrollment forzado, revisar reglas de bandeja (forwarding malicioso es típico).
- Si alguien ejecutó adjunto: aislar endpoint (network containment EDR) y pasar a PB-03 / PB-04.
IoCs a extraer y registrar
| IoC | De dónde | Dónde bloquear |
|---|---|---|
| IP origen | Cabecera Received | Firewall, mail gateway |
| Dominio remitente | From, Return-Path | Mail gateway |
| Dominios enlazados | Body / URLs | Proxy, DNS sinkhole |
| Hashes (MD5/SHA256) | Adjuntos | EDR, AV |
| Asunto | Subject | Regla SIEM / mail gateway |
Aislar el
.eml → cabeceras (SPF/DKIM/DMARC) → URLs (defanged, urlscan, VT) → adjuntos (hash, sandbox) → extraer IoCs → buscar en SIEM cuántos lo recibieron y cuántos clicaron → purgar de buzones, bloquear IoCs, resetear credenciales de los que clicaron.
Malware
Detección de ejecución maliciosa, triaje de proceso, análisis de hash y persistencia
Identificación · Triaje del proceso
Una alerta de malware suele venir del EDR o del AV. El triaje L1 consiste en validar la detección, entender qué hizo el proceso y decidir si el host queda contenido o no.
- Hash del binario → VirusTotal, MalwareBazaar (¿muestra conocida? ¿familia?).
- Padre y abuelo del proceso →
winword.exe → powershell.exe → ?es típico de macro. - Argumentos de línea de comandos → base64,
-enc,DownloadString, IPs raras. - Conexiones de red del proceso → ¿beacons?
- Persistencia creada → Run keys, tareas programadas, servicios, WMI subscriptions.
- Otros hosts con el mismo hash o nombre de fichero.
Detección · SPL (Splunk + Sysmon)
PowerShell codificado (típico downloader/dropper).
index=sysmon EventCode=1 Image="*powershell.exe"
(CommandLine="*-enc*" OR CommandLine="*-EncodedCommand*"
OR CommandLine="*FromBase64String*" OR CommandLine="*DownloadString*")
| table _time host User ParentImage Image CommandLine
| sort - _time
Office spawneando shell (macro maliciosa).
index=sysmon EventCode=1
ParentImage IN ("*winword.exe","*excel.exe","*powerpnt.exe","*outlook.exe")
Image IN ("*cmd.exe","*powershell.exe","*wscript.exe","*cscript.exe","*mshta.exe","*rundll32.exe")
| table _time host User ParentImage Image CommandLine
Persistencia: cambios en Run keys (Sysmon EID 13).
index=sysmon EventCode=13
TargetObject IN (
"*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run*",
"*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce*",
"*\\Services\\*"
)
| table _time host Image TargetObject Details
Buscar el mismo hash en otros endpoints (alcance lateral).
index=sysmon EventCode=1 SHA256="A3B5C7D9...HASH..."
| stats count values(Image) as paths values(CommandLine) as cmds by host
| sort - count
Detección · KQL (Defender for Endpoint)
DeviceProcessEvents
| where TimeGenerated > ago(24h)
| where InitiatingProcessFileName in~ ("winword.exe","excel.exe","powerpnt.exe","outlook.exe")
| where FileName in~ ("cmd.exe","powershell.exe","mshta.exe","wscript.exe","cscript.exe","rundll32.exe")
| project TimeGenerated, DeviceName, AccountName,
InitiatingProcessFileName, FileName, ProcessCommandLine
| order by TimeGenerated desc
DeviceProcessEvents
| where SHA256 == "A3B5C7D9...HASH..."
| summarize Hosts = make_set(DeviceName), Count = count() by FileName, SHA256
Contención inmediata
- Aislar el host en la red desde EDR (network containment / isolation).
- Matar el proceso y sus hijos.
- Bloquear el hash en EDR / AV (politica organizacional).
- Bloquear IPs/dominios C2 en firewall/proxy/DNS.
- Deshabilitar la cuenta si hubo robo de credenciales o si ejecutó como admin.
- Preservar evidencia: triage package del EDR (memoria, procesos, conexiones, persistencia) antes de tocar nada.
Live response · Comandos
Windows
tasklist /v
wmic process get Name,ProcessId,ParentProcessId,CommandLine
netstat -anob
schtasks /query /fo LIST /v
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run
Get-WmiObject Win32_StartupCommand
Linux
ps auxf
ss -tunap
lsof -i
crontab -l ; ls /etc/cron.*
cat ~/.bash_history
last ; w
find / -mtime -2 -type f 2>/dev/null
Criterio de escalado a L2
- Confirmado multi-host (mismo hash o C2 en >1 endpoint).
- Indicios de movimiento lateral → PB-05.
- Persistencia compleja (WMI, servicios, DLL hijacking).
- Sospecha de ransomware → PB-04 inmediatamente.
Ransomware
Cifrado masivo de ficheros, eliminación de copias de seguridad y demanda de rescate
Indicadores de ransomware activo
- Cambios masivos de extensión de fichero (
.lockbit,.encrypt, etc.). - Notas de rescate aparecidas en cada carpeta (
readme.txt,HOW_TO_DECRYPT.html). - Borrado de shadow copies:
vssadmin delete shadows,wbadmin delete catalog. - Deshabilitación de recovery:
bcdedit /set bootstatuspolicy ignoreallfailures. - Procesos consumiendo CPU de forma sostenida en muchos hosts simultáneamente.
- Servicios parados: bases de datos, AV, backups.
Detección · SPL (Splunk + Sysmon)
Borrado de shadow copies — uno de los IoCs más fiables de ransomware.
index=sysmon EventCode=1
(CommandLine="*vssadmin*delete*shadows*"
OR CommandLine="*wbadmin*delete*"
OR CommandLine="*wmic*shadowcopy*delete*"
OR CommandLine="*bcdedit*recoveryenabled*No*")
| table _time host User ParentImage Image CommandLine
Tasa anómala de creación/renombrado de ficheros (Sysmon EID 11).
index=sysmon EventCode=11
| bin _time span=5m
| stats count by _time, host
| where count > 500
| sort - count
Aparición de notas de rescate típicas en filesystems.
index=sysmon EventCode=11
TargetFilename IN ("*readme*.txt","*how_to_decrypt*","*restore_files*","*ransom*","*.lockbit","*.locked")
| stats count values(host) as hosts by TargetFilename
| sort - count
Detección · KQL (Defender)
DeviceProcessEvents
| where TimeGenerated > ago(1h)
| where ProcessCommandLine has_any ("vssadmin delete shadows",
"wbadmin delete", "wmic shadowcopy delete",
"bcdedit /set", "wevtutil cl")
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine
Contención agresiva (minutos)
- Aislar TODOS los hosts con indicios desde EDR. No esperes confirmación: aísla y verifica después.
- Desconectar shares de red y servidores de ficheros para parar la propagación.
- Bloquear C2 en perímetro (firewall, proxy, DNS).
- Deshabilitar cuentas usadas por el atacante (sobre todo de servicio/admin).
- Apagar lo que NO esté infectado todavía si la propagación es activa y agresiva (decisión coordinada con IR/Sistemas).
- Notificar inmediatamente: IR Manager, CISO, jurídico, comunicación. Activar el plan de crisis.
Evidencia clave a preservar
- Muestra del binario ransomware (hash + sample para sandbox/CTI).
- Nota de rescate completa (incluye ID de víctima y wallet).
- Memoria RAM de al menos un host afectado (claves de cifrado pueden estar en memoria).
- Logs de EDR de los 7-14 días previos (acceso inicial y propagación).
- Logs de DC: autenticaciones y creaciones de cuenta.
- Logs de backup: ¿qué intentó borrar el atacante?
Recovery (visión L2/L3 — qué esperar)
El L1 no lidera recuperación, pero debe entender el flujo: validar backups limpios y previos al compromiso → reconstruir hosts desde imagen → restaurar datos → monitorización intensiva post-restore (la reinfección por persistencia residual es muy común) → cambio masivo de credenciales del dominio (KRBTGT incluida si hay sospecha de Golden Ticket).
Aislar los 3 hosts inmediatamente desde EDR → notificar al on-call IR/CISO → bloquear C2 conocidos → buscar el mismo hash/binario en el resto del parque → revisar shadow copies y shares de red → preservar memoria RAM antes de apagar → empezar a documentar timeline.
Lateral Movement
Pass-the-Hash, PsExec, WMI, RDP entre hosts internos del dominio
Patrones típicos a buscar
El atacante ya está dentro. El L1 debe buscar saltos host-a-host con cuentas privilegiadas, usando técnicas que abusan de funcionalidad legítima de Windows.
- Logon Type 3 (Network) con NTLM en lugar de Kerberos en hosts no-servidor → señal de Pass-the-Hash.
- Creación de servicio remoto (EID 7045) con nombre random → PsExec o similares.
- Conexiones SMB a
ADMIN$,C$,IPC$desde una workstation a otra. - WMI remoto (
wmic /node:...) y procesos hijos dewmiprvse.exe. - WinRM (puertos 5985/5986) entre estaciones de trabajo.
- RDP (EID 4624 Logon Type 10) en horarios o desde orígenes raros.
Detección · SPL
Pass-the-Hash candidato: Logon Type 3 con paquete NTLM y cuenta privilegiada.
index=wineventlog EventCode=4624 Logon_Type=3
Authentication_Package_Name=NTLM
NOT Account_Name IN ("ANONYMOUS LOGON","-","*$")
| stats count values(Workstation_Name) as src_hosts values(host) as dst_hosts by Account_Name
| where count > 0
| sort - count
Creación de servicio remoto sospechoso (PsExec, SMBExec).
index=wineventlog EventCode=7045
(Service_Name="PSEXESVC" OR Service_File_Name="*\\admin$\\*"
OR Service_File_Name="*\\PSEXEC*" OR Service_Type="user mode service")
| table _time host Service_Name Service_File_Name Service_Account
Ejecución remota vía WMI desde otra estación.
index=sysmon EventCode=1 ParentImage="*wmiprvse.exe"
Image IN ("*cmd.exe","*powershell.exe","*rundll32.exe","*mshta.exe")
| table _time host User ParentImage Image CommandLine
Misma cuenta autenticándose en muchos hosts en poco tiempo.
index=wineventlog EventCode=4624 Logon_Type IN (3,10)
| bin _time span=30m
| stats dc(host) as hosts_count values(host) as hosts by _time, Account_Name
| where hosts_count >= 5
| sort - hosts_count
Detección · KQL (Defender)
DeviceLogonEvents
| where TimeGenerated > ago(24h)
| where LogonType in ("Network","RemoteInteractive")
| summarize Hosts = dcount(DeviceName), HostList = make_set(DeviceName, 20)
by AccountName, bin(TimeGenerated, 30m)
| where Hosts >= 5
| order by Hosts desc
Contención
- Aislar tanto el host origen (paciente cero) como los hosts destino confirmados.
- Deshabilitar la cuenta que se está usando para moverse lateralmente.
- Forzar reset de contraseña de esa cuenta y de cualquier cuenta vista en hosts comprometidos.
- Revisar Domain Admins y Enterprise Admins — si una de esas cuentas se movió lateralmente, escalado inmediato.
- Revocar Kerberos tickets (en casos graves: reset doble de KRBTGT).
- Bloquear SMB/RPC entre estaciones de trabajo (lo normal es que no exista; segmentación de red).
Técnica donde el atacante usa el hash NTLM de una contraseña en lugar de la contraseña en claro, autenticándose contra otros hosts sin necesidad de descifrarla. Detección: EID 4624 con Logon Type 3 + Authentication Package NTLM + cuenta privilegiada accediendo a hosts que normalmente no visita. Mitigación: Credential Guard, LAPS, restricción de admins locales, segmentación.
Data Exfiltration
Salida anómala de datos vía HTTPS, DNS tunneling, cloud storage o correo
Patrones a buscar
La exfiltración rara vez es "un fichero gigante saliendo". Suele ser tráfico anómalo en volumen o destino respecto al baseline del usuario/host. La detección depende de metadatos de red (NetFlow, proxy, firewall) más que del contenido cifrado.
- Volumen anómalo de subida respecto a la línea base del usuario.
- Destinos atípicos:
pastebin.com,transfer.sh,anonfiles,mega.nz, IP raras. - DNS tunneling: queries muy largas, subdominios random, alto volumen al mismo dominio.
- Uso anómalo de cloud storage (Google Drive, Dropbox, OneDrive personal).
- Correo con adjuntos grandes a dominios externos personales.
- Horarios anómalos: subidas en madrugada, fines de semana.
Detección · SPL
Subidas anómalas por host (proxy).
index=proxy
| bin _time span=1h
| stats sum(bytes_out) as bytes_uploaded by _time, src_ip, user
| eventstats avg(bytes_uploaded) as avg stdev(bytes_uploaded) as stdev by user
| where bytes_uploaded > avg + 3 * stdev AND bytes_uploaded > 100000000
| sort - bytes_uploaded
Conexiones a servicios de file sharing fuera de política.
index=proxy dest_domain IN (
"*pastebin.com","*transfer.sh","*anonfiles.com","*mega.nz",
"*wetransfer.com","*sendspace.com","*filebin.net")
| stats sum(bytes_out) as bytes count by user, dest_domain
| where bytes > 10000000
| sort - bytes
DNS tunneling: queries muy largas y muchas al mismo dominio.
index=dns
| eval qlen=len(query)
| stats count avg(qlen) as avg_len max(qlen) as max_len by src_ip, query_domain
| where count > 1000 AND avg_len > 50
| sort - count
Ratio anómalo bytes_out vs bytes_in en una sesión.
index=firewall action=allowed
| stats sum(bytes_out) as out sum(bytes_in) as in by src_ip dest_ip
| eval ratio = if(in>0, out/in, out)
| where out > 50000000 AND ratio > 10
| sort - out
Detección · KQL (Defender)
DeviceNetworkEvents
| where TimeGenerated > ago(24h)
| where RemoteUrl has_any ("pastebin.com","transfer.sh","anonfiles","mega.nz")
| summarize Bytes = sum(SentBytes), Count = count()
by DeviceName, InitiatingProcessAccountName, RemoteUrl
| where Bytes > 10000000
| order by Bytes desc
Contención
- Bloquear el destino (IP, dominio) en firewall/proxy.
- Aislar el host si la exfiltración está en curso.
- Suspender la cuenta sospechosa (sobre todo en escenarios de insider).
- Cuantificar lo exfiltrado: volumen, destino, horario, qué datos (revisar accesos a fileshares).
- Notificar a DPO/Legal si hay sospecha de datos personales (RGPD: 72h).
Web Attacks
SQLi, XSS, LFI/RFI, command injection y web shells contra aplicaciones expuestas
Patrones en logs HTTP
| Ataque | Patrón en URI/body | Indicador |
|---|---|---|
| SQLi | ' OR 1=1--, UNION SELECT, sleep( | Status 500/200 + tiempos altos |
| XSS | <script>, onerror=, javascript: | Stored vs reflected |
| LFI | ../../etc/passwd, %2e%2e%2f | Acceso a ficheros del sistema |
| RFI / RCE | ?file=http://, ;wget, |nc | Spawn de proceso desde el WS |
| Web shell | cmd.jsp, shell.aspx, c99.php | POST a fichero raro creado recientemente |
Detección · SPL
SQLi tentativo en logs web.
index=web (uri="*UNION*SELECT*" OR uri="*' OR '1'='1*"
OR uri="*sleep(*" OR uri="*--*" OR uri="*xp_cmdshell*"
OR uri="*information_schema*")
| stats count values(uri) as urls by src_ip
| sort - count
LFI / directory traversal.
index=web (uri="*../*" OR uri="*..%2f*" OR uri="*%2e%2e%2f*"
OR uri="*etc/passwd*" OR uri="*windows/win.ini*")
| stats count values(uri) as urls by src_ip status
Servidor web spawneando shell (web shell ejecutándose).
index=sysmon EventCode=1
ParentImage IN ("*w3wp.exe","*httpd*","*nginx*","*java*","*tomcat*","*php-fpm*")
Image IN ("*cmd.exe","*powershell.exe","*bash","*sh","*nc","*wget","*curl")
| table _time host User ParentImage Image CommandLine
Detección · KQL
DeviceProcessEvents
| where InitiatingProcessFileName in~ ("w3wp.exe","httpd","nginx","tomcat","php-fpm")
| where FileName in~ ("cmd.exe","powershell.exe","bash","sh","nc","wget","curl")
| project TimeGenerated, DeviceName, InitiatingProcessFileName,
FileName, ProcessCommandLine
| order by TimeGenerated desc
Contención
- Bloquear IP atacante en WAF / firewall.
- Activar reglas WAF específicas (OWASP CRS para SQLi/XSS).
- Tirar el servicio temporalmente si hay RCE confirmado y no hay parche aún.
- Buscar web shells en directorios web: ficheros recientes, hashes raros, ficheros con permisos extraños.
- Revisar conexiones salientes del servidor web (¿llama a casa?).
- Cambiar credenciales de BBDD, app y APIs si SQLi confirmado.
UNION SELECT password FROM users--. ¿Y ahora?"Es SQLi. Verificar el código de respuesta: si 200 con datos → exitoso. Buscar misma IP/sesión en otros endpoints, exfiltración posterior, web shell creado, escalado a la BBDD. Bloquear IP, activar WAF, escalar a desarrollo, rotar credenciales de BBDD.
Insider Threat
Empleado / contractor que abusa de su acceso legítimo (malicioso o negligente)
Patrones típicos
- Accesos fuera de horario habitual o desde geografías nuevas.
- Descargas masivas de fileshares o repositorios (SharePoint, Confluence, GitLab).
- Uso anómalo de USB o impresoras (volumen de impresión).
- Reenvíos a correo personal (reglas de Outlook, forwarding).
- Subidas a cloud personal (Drive, Dropbox cuenta privada).
- Acceso a recursos fuera de su rol (curiosity browsing).
- Cambios bruscos de comportamiento tras renuncia o conflicto reportado.
Detección · SPL
Acceso fuera de horario laboral.
index=wineventlog EventCode=4624 Logon_Type IN (2,10,11)
| eval hour=strftime(_time,"%H"), wday=strftime(_time,"%w")
| where (hour<7 OR hour>20) OR wday IN ("0","6")
| stats count by Account_Name host hour wday
| sort - count
Descarga masiva en fileshare por un usuario.
index=fileserver action=read
| bin _time span=1h
| stats count sum(file_size) as bytes by _time, user
| where count > 500 OR bytes > 1000000000
| sort - bytes
Reglas de reenvío automático sospechosas (M365).
index=o365 Operation IN ("New-InboxRule","Set-InboxRule","Set-Mailbox")
(Parameters="*ForwardTo*" OR Parameters="*ForwardingSmtpAddress*"
OR Parameters="*RedirectTo*")
| table _time UserId Parameters ClientIP
Uso de USB de almacenamiento (Sysmon EID 11 sobre rutas removibles + EID 1 de USB).
index=wineventlog EventCode IN (6416,4663)
(ObjectName="*USBSTOR*" OR DeviceDescription="*Disk*")
| stats count values(SubjectUserName) as user by host
| sort - count
Contención (con cabeza)
- NO actuar unilateralmente. Coordinar con IR Manager, RRHH y Legal antes de bloquear.
- Aumentar logging sobre el usuario sin que lo perciba (más eventos, captura más larga).
- Preservar evidencia: imagen de disco si va a derivar en proceso disciplinario o legal.
- Documentar cadena de custodia con hashes (MD5/SHA256), responsable, fecha/hora.
- Cuando se decida actuar: revocar accesos de golpe (AD, SaaS, VPN, físico) en coordinación con RRHH.
Command & Control (C2)
Beaconing, DNS tunneling y comunicaciones encubiertas con servidores del atacante
Patrones típicos de C2 (BTL1 — Network Analysis)
- Beaconing periódico: conexiones a intervalos casi fijos a la misma IP/dominio (cada 60s, 5min, 1h...).
- Conexiones pequeñas y regulares con ratio bytes_in/bytes_out balanceado o muy asimétrico.
- Dominios recién registrados (newly registered domains, NRDs).
- DGA (Domain Generation Algorithms): nombres aleatorios
xkj19asdfk.tld. - DNS con queries muy largas a un mismo dominio (tunneling).
- HTTPS a IPs en lugar de dominios, certificados autofirmados o JA3 raros.
- User-Agents anómalos o ausentes (Cobalt Strike, Empire, Sliver).
Detección · SPL
Beaconing — intervalos regulares a un mismo destino.
index=firewall action=allowed
| sort 0 src_ip dest_ip _time
| streamstats current=f last(_time) as prev_time by src_ip dest_ip
| eval interval = _time - prev_time
| stats count avg(interval) as avg_int stdev(interval) as stdev_int by src_ip dest_ip
| where count > 20 AND stdev_int < (avg_int * 0.1) AND avg_int > 30
| sort - count
Conexiones a dominios recién resueltos (necesita lookup de NRDs).
index=dns
| stats earliest(_time) as first_seen count by query
| where first_seen > relative_time(now(), "-7d")
| sort first_seen
User-Agents conocidos de C2 frameworks.
index=proxy
| search http_user_agent IN ("*Cobalt*","*Empire*","*Mythic*","*Sliver*","Mozilla/4.0*")
| stats count by src_ip dest_domain http_user_agent
Proceso no-browser haciendo HTTP/HTTPS (típico de beacon).
index=sysmon EventCode=3
NOT Image IN ("*chrome.exe","*firefox.exe","*msedge.exe","*iexplore.exe","*outlook.exe","*teams.exe")
DestinationPort IN (80,443,8080,8443)
| stats count values(DestinationIp) as ips by host Image
| sort - count
Detección · KQL
DeviceNetworkEvents
| where TimeGenerated > ago(24h)
| where RemotePort in (80,443,8080,8443)
| where InitiatingProcessFileName !in~ ("chrome.exe","firefox.exe","msedge.exe","outlook.exe","teams.exe")
| summarize Count = count(), Hosts = make_set(RemoteIP, 10)
by DeviceName, InitiatingProcessFileName
| where Count > 50
| order by Count desc
Contención
- Bloquear IPs/dominios C2 en firewall/proxy/DNS sinkhole.
- Aislar el host con beacon confirmado (EDR network containment).
- Cazar el implant en disco y memoria (proceso, persistencia).
- Buscar otros hosts hablando con el mismo destino → propagación lateral.
- Threat intel: cruzar el dominio/IP con VirusTotal, AlienVault OTX, ThreatFox, URLhaus.
Privilege Escalation
UAC bypass, token impersonation, abuso de servicios y exploits locales
Patrones a buscar
- Token impersonation: proceso de usuario normal hereda SID de SYSTEM o admin.
- UAC bypass:
fodhelper.exe,eventvwr.exe,computerdefaults.exespawn de procesos elevados. - Modificación de servicios existentes para ejecutar comandos.
- Adición a grupos privilegiados: Administrators, Domain Admins.
- Dumping de credenciales:
lsass.exeacceso desde proceso no autorizado (mimikatz). - Asignación de derechos peligrosos:
SeDebugPrivilege,SeImpersonatePrivilege.
Detección · SPL
Acceso a LSASS desde proceso no autorizado (posible Mimikatz / credential dumping).
index=sysmon EventCode=10 TargetImage="*lsass.exe"
(GrantedAccess="0x1010" OR GrantedAccess="0x1410" OR GrantedAccess="0x143A")
NOT SourceImage IN ("*MsMpEng.exe","*csrss.exe","*wininit.exe","*services.exe")
| table _time host SourceImage TargetImage GrantedAccess
UAC bypass clásico vía fodhelper/eventvwr.
index=sysmon EventCode=1
ParentImage IN ("*fodhelper.exe","*eventvwr.exe","*computerdefaults.exe","*sdclt.exe")
Image IN ("*cmd.exe","*powershell.exe")
| table _time host ParentImage Image CommandLine
Cambios en grupos privilegiados (EID 4728/4732/4756).
index=wineventlog EventCode IN (4728,4732,4756)
Target_Account_Name IN ("Domain Admins","Enterprise Admins","Administrators","Schema Admins")
| table _time host Subject_User_Name Member_Account_Name Target_Account_Name
Asignación de privilegios sensibles (EID 4672 anómalo).
index=wineventlog EventCode=4672
NOT Account_Name IN ("SYSTEM","LOCAL SERVICE","NETWORK SERVICE","*$")
Privileges IN ("*SeDebugPrivilege*","*SeImpersonatePrivilege*","*SeTcbPrivilege*","*SeLoadDriverPrivilege*")
| table _time host Account_Name Privileges
Contención
- Aislar el host donde se haya producido la escalada.
- Deshabilitar la cuenta ya escalada y revocar tokens/tickets.
- Revisar y revertir cambios en grupos (quitar la cuenta añadida indebidamente).
- Reset de contraseña de TODAS las cuentas que hayan iniciado sesión en ese host (sus hashes pueden estar en LSASS).
- Si se dumpeó LSASS: considerar el host comprometido a nivel de credenciales — reset de password de cualquier usuario que haya tocado ese host recientemente.
DDoS / DoS
Volumetric, SYN flood, HTTP flood y amplificación contra servicios expuestos
Tipos y patrones
| Tipo | Patrón | Capa OSI |
|---|---|---|
| Volumetric | Inundación de tráfico (UDP flood) | 3-4 |
| SYN flood | Conexiones TCP a medio establecer | 4 |
| HTTP flood | GET/POST masivos a URLs costosas | 7 |
| Slowloris | Mantener conexiones abiertas semi-completas | 7 |
| Amplificación | DNS/NTP/Memcached reflejados al objetivo | 4 |
Detección · SPL
Aumento abrupto de conexiones entrantes a un servicio.
index=firewall direction=inbound dest_port IN (80,443)
| bin _time span=1m
| stats count by _time dest_ip
| eventstats avg(count) as avg stdev(count) as stdev by dest_ip
| where count > avg + 5 * stdev
| sort - count
SYN flood: muchas SYN sin completar handshake.
index=firewall tcp_flag=SYN action=allowed
| stats count dc(src_ip) as src_count by dest_ip _time
| bin _time span=1m
| where count > 10000
HTTP flood: misma URI golpeada miles de veces desde miles de IPs.
index=web
| bin _time span=1m
| stats count dc(src_ip) as ips by _time uri
| where count > 5000 AND ips > 500
| sort - count
Contención
- Notificar al proveedor anti-DDoS (Cloudflare, Akamai, ISP) si existe contrato — es lo primero.
- Activar rate limiting en WAF / load balancer.
- Geo-blocking temporal si el ataque viene de regiones específicas.
- Blackhole routing de IPs claramente maliciosas (cuidado con FPs masivos).
- Escalar capacidad (autoscaling) si la app lo permite — comprar tiempo.
- Vigilar otros ataques en paralelo: el DDoS suele usarse como cortina de humo para exfiltración u otros incidentes.
Supply Chain
Compromiso vía proveedor, software firmado o dependencia (SolarWinds, 3CX, MOVEit-style)
El L1 en este tipo de incidente
El L1 rara vez es el primero en detectar un supply chain por sí solo — normalmente llega como aviso externo: CTI feed, advisory de un fabricante, alerta de CERT/CSIRT, noticia pública. El papel del L1 es contener rápido y cazar IoCs en el parque.
Triggers típicos
- Advisory del fabricante de una herramienta crítica que tienes desplegada.
- IoCs publicados por CISA, INCIBE-CERT, CCN-CERT, MITRE, vendor TI.
- Comportamiento anómalo de software firmado y legítimo (binarios buenos haciendo cosas malas).
- Componente open-source de tu stack con CVE crítico y exploitation activa.
Detección · SPL
Hunting con IoCs publicados (hashes, dominios, IPs).
index=sysmon (SHA256 IN ("HASH1","HASH2","HASH3")
OR Image="*nombre-vendor-comprometido*")
| stats count earliest(_time) as first_seen by host Image SHA256
| sort first_seen
Conexiones a infraestructura C2 del proveedor comprometido.
index=firewall OR index=dns OR index=proxy
(dest_ip IN ("IOC_IP1","IOC_IP2") OR query="*IOC_DOMAIN*" OR dest_domain="*IOC_DOMAIN*")
| stats count values(src_ip) as origenes earliest(_time) as first_seen by dest
Software firmado haciendo cosas raras (proceso legítimo, comportamiento ilegítimo).
index=sysmon EventCode=1 Image="*nombre-software-confiable*"
(CommandLine="*powershell*" OR CommandLine="*cmd*"
OR CommandLine="*wmic*" OR CommandLine="*-enc*")
| table _time host Image CommandLine ParentImage
Contención
- Inventariar dónde está instalado el componente comprometido (CMDB, EDR, gestión de parches).
- Aislar hosts con la versión vulnerable mientras se confirma exposición.
- Bloquear IoCs en firewall, proxy, EDR, DNS.
- Aplicar parche/mitigación del vendor — o desinstalar si no hay parche.
- Hunting retrospectivo: ¿hubo actividad sospechosa desde la fecha de la primera versión troyanizada?
- Coordinar con el vendor y con CERT nacional si el alcance lo justifica.
vendor.exe y por tanto está bien"). Esta lección entra en la fase 6 de PICERL y debe traducirse en mejoras del SIEM.
(1) por qué son difíciles de detectar (software legítimo firmado),
(2) que la detección suele venir por hunting de IoCs publicados,
(3) que el control compensatorio es defensa en profundidad — EDR, segmentación, mínimo privilegio — no confiar solo en firma de código.