Detección de password spraying en el System Log de Okta
Detecta password spraying, fuerza bruta y credential stuffing en Okta: fallos por IP y por usuario, eventos de ThreatInsight y el inicio de sesión que importa.
TL;DR. El password spraying son muchos usuarios, pocos intentos por cada uno, desde el mismo origen: user.session.start o user.authentication.verify fallidos agrupados por client.ipAddress, que tocan ocho o más cuentas en una hora con unos tres intentos como máximo por cuenta. La fuerza bruta es lo contrario: muchos fallos en una sola cuenta. Ambos solo importan de verdad si van seguidos de un éxito desde el mismo origen, así que busca ese éxito primero. Los ataques distribuidos a través de proxies residenciales esquivan la agrupación por IP; pivota también por ASN, user agent y eventos de ThreatInsight.
Tres ataques, tres formas
| Ataque | Forma en el registro | ATT&CK |
|---|---|---|
| Password spraying | un origen, muchos usuarios, 1–3 intentos cada uno | T1110.003 |
| Adivinación de contraseñas (fuerza bruta) | muchos intentos sobre un usuario | T1110.001 |
| Credential stuffing | pares usuario/contraseña conocidos, repartidos entre muchos orígenes, alta tasa de éxito con contraseñas reutilizadas | T1110.004 |
El spraying se mantiene a propósito por debajo de los umbrales de bloqueo: un puñado de contraseñas comunes por cuenta, en cientos de cuentas. Por eso el bloqueo por usuario no es una detección.
El equipo Identity Threat Research de Okta informó en la primavera de 2024 de grandes campañas de credential stuffing canalizadas a través de Tor y proxies residenciales, de modo que el tráfico parecía venir de dispositivos de usuarios corrientes y no de proveedores de VPS (Okta Security: cómo bloquear servicios de anonimización). Tenlo presente cuando un spraying «venga» de cientos de IP domésticas.
Los eventos
| eventType | Qué leer |
|---|---|
user.session.start con outcome.result = FAILURE | outcome.reason (por ejemplo INVALID_CREDENTIALS), IP, ASN, user agent |
user.authentication.verify con FAILURE | lo mismo |
user.session.start con SUCCESS desde el mismo origen | el compromiso |
user.account.lock | bloqueos provocados por los intentos |
security.threat.detected | petición desde una IP que ThreatInsight clasificó como maliciosa |
security.attack.start | ThreatInsight detectó que la organización está bajo ataque |
security.breached_credential.detected | se usó una credencial asociada a una filtración conocida |
security.threat.detected y security.attack.start son las dos consultas que Okta Security sugiere para vigilar estas campañas (fuente). Cuando ThreatInsight está en modo «log and enforce», las peticiones de IP que considera de amenaza alta pueden bloquearse antes de la autenticación y no convertirse nunca en fallos de user.session.start, lo que cambia el significado de tus recuentos.
Cómo lo detecta el analizador
| Regla | Agrupa por | Umbral | Agravamiento |
|---|---|---|---|
access.password_spray | IP del cliente | ≥ 8 usuarios distintos con fallos en 1 h, media ≤ 3 fallos por usuario → alta | un user.session.start correcto desde esa IP en 1 h → crítica |
access.brute_force | usuario | ≥ 10 fallos en 15 min → media | un inicio de sesión correcto en 30 min → alta |
threat.threatinsight | IP del cliente | cualquier evento de ThreatInsight, o debugData.threatSuspected = true → media | — |
threat.breached_credential | — | cualquier security.breached_credential.detected → media | — |
La condición de «media de intentos por usuario» es lo que separa un spraying de un NAT ruidoso. Una IP de salida de oficina donde mucha gente se equivoca de contraseña el lunes por la mañana produce muchos usuarios con un fallo cada uno, pero también un flujo constante de éxitos de esos mismos usuarios. Mira la tasa de éxito antes de alarmarte.
Cazar un spraying que las reglas podrían pasar por alto
La regla por IP es precisa pero fácil de esquivar con una red de proxies. Compleméntala a mano:
- Agrupa los fallos por ASN en lugar de por IP (
securityContext.asNumber). Un ASN de hosting con fallos contra 50 de tus usuarios es un spraying aunque cada petición use una IP distinta. - Agrupa por user agent. Las herramientas de spraying suelen usar una cadena de user agent fija, a veces anticuada, en todas sus IP.
- Mira los nombres de usuario atacados. Los sprays recorren listas alfabéticas, incluyen antiguos empleados o siguen un patrón de nombres (
nombre.apellido) deducido de fuentes públicas. - Encuentra los éxitos. Para cada IP, ASN o user agent que aparezca en los fallos, enumera sus inicios de sesión correctos. Esa lista corta es tu incidente.
- Revisa qué hicieron después las cuentas con éxito: solicitudes push (¿intento de fatiga?), registro de factores, SSO.
En el analizador, la pestaña Entidades enumera las IP con ASN, país, número de eventos y número de fallos: ordena por fallos y pulsa Eventos en los orígenes principales.
Leer outcome.reason
No todos los fallos significan lo mismo, y el campo de motivo es donde se separan un spraying y un problema del usuario. INVALID_CREDENTIALS en muchas cuentas desde un mismo origen es el spraying en sí. Los fallos que terminan en user.account.lock muestran que el atacante se pasó de tu política de bloqueo: útil para acotar el alcance (qué cuentas hay que desbloquear), y también indica que no fue cuidadoso. Una serie de fallos de un usuario desde su red habitual, seguida de un éxito desde esa misma red, es una persona que olvidó un cambio de contraseña, no un ataque. Lee siempre el motivo junto con el origen.
Si un inicio de sesión tuvo éxito
Una contraseña correcta en una cuenta que exige MFA significa que ahora el atacante necesita el segundo factor, que es justo el punto de partida de la fatiga MFA o de un restablecimiento por el helpdesk. Actúa antes de que lo consiga:
- Restablece la contraseña y elimina las sesiones de cada cuenta con un éxito desde el origen atacante.
- Revisa en cada una los push, los registros de factores y el SSO posteriores al éxito.
- Bloquea el origen con una zona de red de bloqueo; bloquea los anonimizadores con una zona dinámica mejorada.
- Avisa a los usuarios afectados: su contraseña es conocida y quizá la reutilicen en otros sitios.
Prevención
- ThreatInsight en modo «Log and enforce security based on threat level» en lugar de solo registro (Okta Help Center).
- Zonas dinámicas mejoradas para bloquear anonimizadores, Tor y proxies en el inicio de sesión, un control que Okta Security recomienda frente a estas campañas (fuente).
- Autenticadores sin contraseña y resistentes al phishing: no hay contraseña que rociar.
- Protección frente a contraseñas filtradas donde esté disponible, y formación de los usuarios sobre la reutilización.