Ataques Low and Slow | Slowloris y R.U.D.Y. — Cómo Detectar y Bloquear

Aprende cómo los ataques low and slow explotan el protocolo HTTP/1.1 para agotar las conexiones de los servidores. Entiende la mecánica CRLF CRLF, Request Buffering, JA3/JA4 Fingerprint y cómo el edge neutraliza Slowloris.

La mayoría de los ataques DDoS son evidentes: generan picos enormes de tráfico que saturan enlaces y derriban servidores en segundos. Los ataques low and slow son lo opuesto. Usan decenas —no miles— de conexiones, cada una transmitiendo datos a un ritmo mínimo, manteniendo ocupados los recursos del servidor indefinidamente sin completar nunca la solicitud. Las herramientas de detección volumétrica simplemente no los detectan.

Los ataques low and slow son una categoría de ataques DDoS de capa 7 que agotan los recursos de un servidor web mediante un pequeño número de conexiones mantenidas abiertas durante largos períodos, transmitiendo datos a velocidad mínima. En lugar de inundar con volumen, el atacante ocupa hilos o descriptores de archivo del servidor esperando solicitudes que nunca se completan.

Por qué los ataques low and slow pasan desapercibidos

La detección tradicional de DDoS monitorea volumen: paquetes por segundo, bytes por segundo, solicitudes por segundo. Los ataques low and slow generan muy poco tráfico. La tabla siguiente ilustra la diferencia de perfil frente a un HTTP Flood convencional:

CaracterísticaHTTP FloodLow and Slow (Slowloris)
Volumen de solicitudes500.000+ req/s1–10 req/s
Ancho de banda generado50+ GbpsMenos de 1 Mbps
Conexiones simultáneasMiles (vida corta)100–1.000 (vida larga)
Datos por conexión/tiempoAlto volumen continuo1 byte cada 10–15 segundos
Visibilidad volumétricaAlta — fácil de detectarPrácticamente nula
RPS (Requests Per Second)Pico abruptoEstable y bajo
Conexiones ESTABLISHEDFluctúan rápidamenteSe acumulan continuamente

El servidor mantiene cada conexión activa —consumiendo un hilo o un descriptor de archivo— mientras espera que la solicitud termine. Con suficientes conexiones ocupadas, el pool de hilos se agota y las conexiones legítimas reciben HTTP 408 Request Timeout o son rechazadas con error de conexión.

Slowloris — explotación de la mecánica CRLF del HTTP/1.1

Desarrollado por Robert “RSnake” Hansen en 2009, Slowloris explota una característica fundamental del protocolo HTTP/1.1 (RFC 7230): el servidor debe esperar la secuencia de cierre de headers CRLF CRLF (\r\n\r\n) antes de procesar la solicitud. Mientras esa secuencia no llega, el servidor mantiene la conexión abierta y los recursos asignados.

El mecanismo funciona en cinco pasos:

  1. El atacante abre cientos de conexiones TCP al servidor objetivo.
  2. En cada conexión, envía el inicio de una solicitud HTTP/1.1 sintácticamente válida — la línea de solicitud y algunos headers — pero omite deliberadamente la secuencia CRLF CRLF que cerraría el bloque de headers.
  3. Cada 10–15 segundos, envía un byte adicional (un nuevo header parcial, como X-Keep: a) para resetear el idle timeout del servidor, manteniendo la conexión viva sin completar la solicitud.
  4. El servidor, siguiendo la especificación HTTP/1.1, espera indefinidamente el CRLF CRLF que nunca llega. Cada conexión ocupa un hilo en Apache (modelo MPM Prefork o Worker) o un descriptor de archivo en servidores asíncronos.
  5. Cuando todos los hilos o conexiones disponibles están ocupados, las nuevas solicitudes legítimas son rechazadas o reciben HTTP 408 Request Timeout.

El envío periódico de bytes adicionales es el elemento crítico: impide que el servidor cierre la conexión por inactividad, extendiendo el ataque indefinidamente con un coste mínimo de ancho de banda para el atacante.

R.U.D.Y. — fragmentación del cuerpo POST y bloqueo de sockets

R.U.D.Y. (R-U-Dead-Yet?) opera en una fase diferente del protocolo HTTP: el cuerpo de la solicitud POST, después de que los headers ya han sido enviados correctamente.

El mecanismo explota el campo Content-Length:

  1. El atacante envía una solicitud POST completa y sintácticamente válida, con todos los headers, incluyendo Content-Length: 1000000 (u otro valor alto).
  2. El servidor asigna un socket y reserva recursos para recibir el cuerpo de 1 MB declarado.
  3. El atacante transmite el cuerpo en fragmentos de 1 byte cada 10 segundos — tráfico válido desde la perspectiva del protocolo TCP, sin violar ningún timeout de inactividad.
  4. El socket permanece bloqueado en la asignación de recepción. Con decenas de conexiones simultáneas así, los sockets disponibles se agotan.

Los objetivos preferidos de R.U.D.Y. son los endpoints que procesan grandes volúmenes de datos POST: formularios de autenticación, APIs de carga de archivos, endpoints de procesamiento de datos que típicamente tienen un Content-Length alto o sin límite definido.

Slow Read Attack — manipulación de la Ventana de Recepción TCP

El Slow Read Attack opera en la capa de transporte (TCP), no en la capa de aplicación HTTP. El mecanismo explota la Ventana de Recepción TCP (TCP Receive Window) — el parámetro que indica al emisor cuántos bytes está listo para aceptar el receptor.

El ataque funciona de la siguiente manera:

  1. El atacante establece una conexión TCP normal y envía una solicitud HTTP legítima.
  2. Antes de que el servidor comience a enviar la respuesta, el atacante configura su Ventana de Recepción TCP en un valor muy bajo — cercano a cero (win=1 o win=64), en lugar del estándar de 65 KB–128 KB.
  3. El servidor, respetando el control de flujo TCP, solo puede enviar datos en la cantidad que autoriza la ventana del receptor. Con una ventana de 1 byte, envía un byte, espera el ACK, envía otro byte, y así sucesivamente.
  4. El send buffer del servidor (típicamente 65 KB–128 KB) se llena porque los datos no pueden despacharse a velocidad normal.
  5. Cuando el send buffer se satura, el servidor emite TCP Window Probes — paquetes de sondeo periódicos para verificar si la ventana del cliente se ha expandido. Cada probe consume CPU y mantiene el estado de conexión activo en el kernel.
  6. Decenas de conexiones con ventana reducida simultáneamente consumen tanto el pool de send buffers como CPU de procesamiento de probes, agotando recursos del servidor sin generar tráfico visible.

El Slow Read Attack es particularmente eficaz contra servidores que no tienen límite de tiempo para el envío completo de respuestas — solo para la recepción de solicitudes.

Apache Killer — Range Header y fragmentación de respuesta

El Apache Killer envía solicitudes con un header Range que contiene cientos de rangos de bytes solapados y redundantes. El servidor debe preparar y serializar cada rango individualmente como parte de una respuesta multipart, consumiendo CPU y memoria por solicitud incluso desde un único cliente.

GET / HTTP/1.1
Host: objetivo.com
Range: bytes=0-1,0-2,0-3,0-5,0-10,...,0-65536

Este ataque fue corregido en Apache 2.2.21 (2011) con la limitación del número de rangos aceptados por solicitud, pero variaciones siguen afectando servidores sin actualizar.

Modelos de concurrencia y superficie de ataque

La efectividad de los ataques low and slow varía según el modelo de concurrencia del servidor:

ServidorModelo de concurrenciaLímite críticoVulnerabilidad a SlowlorisVulnerabilidad a Slow Read
Apache MPM PreforkHilo por conexiónMaxRequestWorkers (predeterminado: 150–256)Alta — 1 hilo por conexión bloqueadaMedia
Apache MPM WorkerHilo por conexiónMaxRequestWorkersAltaMedia
IIS (Windows)Pool de hilos fijomaxConcurrentRequestsPerCPUAltaMedia-Alta
NginxAsíncrono (event loop)worker_connections × worker_processesBaja — no bloquea hilo, pero agota descriptores de archivoMedia — los send buffers se llenan
Node.jsEvent loop asíncronomaxConnections (net.Server)BajaMedia
LiteSpeedAsíncronoConfigurableBajaBaja

Nota importante sobre Nginx: aunque la arquitectura asíncrona de Nginx es significativamente más resistente al Slowloris clásico — ya que no bloquea un hilo por conexión — el servidor sigue siendo limitado por la directiva worker_connections. Cada conexión abierta, aunque inactiva, consume un descriptor de archivo. Un atacante con volumen suficiente de conexiones puede agotar el worker_connections total de Nginx (predeterminado: 1.024 por worker), causando el rechazo de nuevas conexiones sin ningún bloqueo de hilo.

HTTP/2, multiplexación de streams y nuevos vectores

HTTP/2 cambió la dinámica de los ataques low and slow de forma ambivalente:

Resistencia al Slowloris clásico: como HTTP/2 usa multiplexación — múltiples streams lógicos sobre una única conexión TCP — el Slowloris que abre cientos de conexiones TCP es menos efectivo. El servidor necesita menos conexiones para atender el mismo número de solicitudes.

Nuevos vectores de ataque lento: la multiplexación crea superficies de ataque específicas de HTTP/2:

  • Streams lentos mediante manipulación de WINDOW_UPDATE: HTTP/2 tiene su propio control de flujo, independiente del TCP. Un atacante puede abrir múltiples streams en una única conexión TCP y enviar frames WINDOW_UPDATE con incrementos mínimos — forzando al servidor a enviar datos de cada stream en fragmentos ínfimos. El efecto es similar al Slow Read Attack, pero operando en la capa de aplicación HTTP/2.
  • Manipulación de frames SETTINGS: el atacante puede enviar frames SETTINGS con parámetros agresivos (como INITIAL_WINDOW_SIZE cercano a cero) para todos los streams, reduciendo el throughput de toda la conexión mientras mantiene el canal abierto.
  • Agotamiento por multiplexación de streams: abrir decenas de streams simultáneos en una única conexión y alimentarlos lentamente consume buffers de estado de stream en el servidor sin activar alertas de conexiones TCP.

Nginx con HTTP/2 activado sigue siendo limitado por worker_connections — cada conexión TCP con múltiples streams HTTP/2 sigue ocupando un descriptor de archivo. La protección requiere configurar límites de streams por conexión y timeouts de stream además de los timeouts de conexión TCP.

Técnicas de mitigación

Timeouts agresivos por fase del protocolo

La configuración de timeouts por fase — diferenciando el tiempo para recibir headers, cuerpo y enviar respuesta — es la defensa más directa y eficiente:

# Nginx — mitigación de Slowloris y R.U.D.Y.
client_header_timeout 10s; # Tiempo máximo para recibir headers completos (CRLF CRLF)
client_body_timeout 10s; # Tiempo máximo entre bytes consecutivos del cuerpo
keepalive_timeout 15s; # Tiempo máximo de conexión keepalive inactiva
send_timeout 10s; # Tiempo máximo entre bytes enviados al cliente
# Apache — mod_reqtimeout para Slowloris y R.U.D.Y.
# Headers: mínimo de 500 bytes/s, plazo de 10 a 20 segundos
RequestReadTimeout header=10-20,minrate=500
# Cuerpo: mínimo de 500 bytes/s, plazo de 20 segundos
RequestReadTimeout body=20,minrate=500

La directiva minrate es especialmente relevante: en lugar de un timeout fijo, verifica si la tasa de transferencia está por encima de un umbral mínimo. Una conexión que envía 1 byte cada 10 segundos viola minrate=500 inmediatamente, siendo terminada incluso antes de alcanzar el plazo máximo.

Limitación de conexiones por IP con limit_conn

# Nginx — limitación de conexiones simultáneas por IP
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
limit_conn conn_limit 20; # Máximo de conexiones por IP
limit_conn_status 429; # Devuelve HTTP 429 al superar el límite

El limit_conn de Nginx actúa al nivel de conexiones TCP activas, no de solicitudes. Esto lo hace efectivo contra Slowloris (que abre muchas conexiones) incluso antes de recibir cualquier dato HTTP.

Request Buffering en el reverse proxy edge

El Request Buffering es un mecanismo defensivo fundamental que opera en el reverse proxy edge: el nodo edge monta y valida la solicitud HTTP completa — incluyendo todos los headers y el cuerpo declarado — antes de abrir cualquier conexión upstream con el servidor de origen.

El impacto es decisivo:

  • El servidor de origen nunca recibe conexiones incompletas. Solo las solicitudes completamente recibidas y validadas por el edge llegan al backend.
  • Los ataques Slowloris y R.U.D.Y. quedan retenidos en el edge, que aplica sus propios timeouts agresivos.
  • El edge soporta órdenes de magnitud más conexiones simultáneas que un servidor Apache típico, diluyendo el impacto del ataque.
  • El Slow Read Attack también se neutraliza: el edge envía la respuesta al cliente de forma asíncrona, sin mantener bloqueado el estado del send buffer del servidor de origen mientras espera que el cliente reciba los datos lentamente.

JA3/JA4 Fingerprinting y análisis conductual en el WAF

Las herramientas de ataque como Slowloris, R.U.D.Y. y sus variantes presentan patrones identificables que difieren de los navegadores legítimos:

TLS Fingerprinting (JA3/JA4): el handshake TLS de cada cliente deja una “huella digital” basada en la secuencia de cipher suites, extensiones TLS y parámetros de versión. El hash JA3 (y su sucesor JA4) de herramientas de ataque como Slowloris en Python o Perl difiere consistentemente del hash de navegadores como Chrome, Firefox o Safari. Un WAF con soporte JA3/JA4 puede bloquear solicitudes con fingerprints conocidos de herramientas de ataque antes de analizar ningún dato HTTP.

Análisis conductual complementario:

  • Ausencia de headers típicos de navegador (Accept-Language, Accept-Encoding, Accept)
  • Ninguna solicitud de recursos secundarios (CSS, JavaScript, imágenes) tras la solicitud inicial
  • Timing mecánico y regular entre bytes — patrón no humano
  • Secuencias de solicitudes incompatibles con la navegación real — patrones detectables mediante técnicas de detección de bots

Configuraciones de límite de streams HTTP/2

# Nginx — límites para mitigar ataques slow en HTTP/2
http2_max_concurrent_streams 64; # Máximo de streams simultáneos por conexión
http2_idle_timeout 30s; # Timeout para conexiones HTTP/2 inactivas
http2_recv_timeout 30s; # Timeout para recibir frames HTTP/2

Señales de detección

IndicadorQué observarAtaque probable
Alto ESTABLISHED con bajo RPSss -s o netstat -an con conteo anormalmente alto vs. bajo throughput HTTPSlowloris
Conexiones de larga duración sin completarLogs con conexiones abiertas más de 30s sin solicitud finalizadaSlowloris / R.U.D.Y.
Pocos IPs con muchas conexiones cada unoNúmero pequeño de IPs con decenas de conexiones abiertas simultáneamenteSlowloris
CPU normal, hilos o descriptores de archivo agotadosServidor sin carga de CPU pero rechazando conexionesTodos
Errores 503 o 408 sin pico de RPSService Unavailable o Request Timeout sin aumento visible de tráficoTodos
Send buffer del servidor continuamente llenoMétricas de red mostrando backpressure TCP sin tráfico volumétricoSlow Read Attack
TCP Window Probes frecuentes en los logs de redCapturas de paquetes (tcpdump/Wireshark) mostrando probes periódicosSlow Read Attack

Errores comunes y soluciones

Error: Usar solo detección volumétrica para monitorear DDoS. Solución: Los ataques low and slow son invisibles para las alertas de volumen. Monitorea también: conexiones por IP, duración media de conexiones, tasa de completitud de solicitudes y utilización de hilos o descriptores de archivo.

Error: Asumir que Nginx es completamente inmune a Slowloris. Solución: La arquitectura event-driven de Nginx es más resistente, pero no inmune. El límite worker_connections puede agotarse con suficientes conexiones lentas. Configura limit_conn y timeouts incluso con Nginx.

Error: Configurar solo un timeout global de conexión. Solución: Separa los timeouts por fase del protocolo (client_header_timeout, client_body_timeout, send_timeout). Un único timeout global no captura conexiones que envían datos continuamente a ritmo mínimo — la directiva minrate de Apache es el mecanismo más preciso para ese caso.

Error: Ignorar HTTP/2 como vector de ataque slow por ser más resistente al Slowloris clásico. Solución: HTTP/2 no elimina los vectores low and slow — solo los transforma. Configura límites de streams (http2_max_concurrent_streams) y timeouts específicos de HTTP/2 además de los timeouts TCP.

Error: No monitorear el pool de hilos ni el uso de descriptores de archivo. Solución: El agotamiento de hilos o descriptores de archivo es el indicador más directo de un ataque low and slow en curso. Configura alertas cuando la utilización alcance el 80%.

Preguntas frecuentes

¿Por qué Slowloris se llama ataque “furtivo”? Porque genera un volumen de tráfico irrisorio —menos de 1 Mbps— que no activa las alertas volumétricas. Es invisible para IDS/IPS basados en volumen, para proveedores de tránsito que monitoran solo ancho de banda y para dashboards de solicitudes por segundo. La única métrica que lo revela es el número de conexiones ESTABLISHED acumuladas.

¿Un solo ordenador puede ejecutar Slowloris? Sí. Herramientas como el Slowloris original en Perl y versiones Python modernas ejecutan el ataque desde una sola máquina sin botnet. Esto lo hace accesible a atacantes con recursos limitados y hace ineficaz el bloqueo por volumen o diversidad de IPs.

¿El uso de HTTPS/TLS impide los ataques Slowloris o R.U.D.Y.? No. El handshake TLS se negocia antes de la capa HTTP y se completa normalmente en ambos ataques. Tras concluir el handshake TLS, Slowloris y R.U.D.Y. operan en la capa HTTP sobre el canal TLS establecido — el cifrado no tiene visibilidad sobre el ritmo de transmisión del payload HTTP. La mitigación efectiva debe ocurrir tras la terminación TLS, en capa 7, mediante análisis de headers, timing y comportamiento de la solicitud.

¿Cuánto tiempo tarda Slowloris en derribar un servidor Apache no protegido? En pruebas documentadas, un servidor Apache con configuración predeterminada (256 hilos) puede ser derribado por Slowloris en 30 segundos a 2 minutos, dependiendo del número de conexiones que el atacante abra. Con 256 conexiones lentas simultáneas, el pool de hilos se agota completamente antes de que actúe ningún timeout predeterminado.

¿Cómo identificar si un error 503 está provocado por HTTP Flood o por un ataque Low and Slow? La diferencia está en las métricas de RPS y conexiones ESTABLISHED. Un HTTP Flood provoca un error 503 acompañado de un pico abrupto y elevado de solicitudes por segundo (RPS), con alto consumo de CPU y red. Un ataque Low and Slow genera errores 503 con RPS estable y bajo — prácticamente indistinguible del tráfico normal — pero con un número creciente y anómalo de conexiones ESTABLISHED de larga duración, CPU cercana a lo normal e hilos o descriptores de archivo agotados. El comando ss -s o netstat -an | grep ESTABLISHED | wc -l cruzado con el RPS actual es el diagnóstico más rápido.

¿R.U.D.Y. es más peligroso que Slowloris? Depende del objetivo. R.U.D.Y. es más efectivo contra aplicaciones que procesan grandes volúmenes de datos POST — cargas de archivos, APIs, formularios con límites altos de Content-Length. Slowloris es más genérico y afecta a cualquier servidor HTTP con límite de hilos o conexiones. En servidores con mod_reqtimeout correctamente configurado, R.U.D.Y. se mitiga con minrate, mientras que Slowloris requiere configuración adicional de client_header_timeout.

¿Cómo distinguir un usuario con conexión lenta de un ataque low and slow? Los usuarios con conexión lenta legítima completan la solicitud eventualmente, solicitan múltiples recursos secuencialmente (CSS, JS, imágenes tras el HTML) y tienen timing variable e irregular entre bytes — comportamiento humano. Los ataques low and slow mantienen las conexiones abiertas indefinidamente sin completar, con timing mecánico y regular entre bytes, ninguna solicitud de recursos secundarios y patrones JA3/JA4 de fingerprint consistentes con herramientas de automatización en lugar de navegadores reales.

¿Qué es el Request Buffering y por qué es efectivo contra los ataques low and slow? El Request Buffering es el mecanismo por el que un reverse proxy edge acumula y valida la solicitud HTTP completa — headers y cuerpo completos — antes de abrir la conexión con el servidor de origen (upstream). El resultado es que el servidor de origen nunca recibe solicitudes incompletas: el edge absorbe toda la lentitud del cliente, aplica sus timeouts y solo reenvía al backend lo que está completamente recibido y validado. Esto hace al servidor de origen inmune a Slowloris y R.U.D.Y., independientemente de su configuración interna.

¿Cuál es el impacto del HTTP/2 en los ataques low and slow? HTTP/2 usa multiplexación de streams, lo que reduce la efectividad del Slowloris clásico que abre muchas conexiones TCP. Sin embargo, crea nuevos vectores: un atacante puede abrir múltiples streams HTTP/2 en una única conexión TCP y manipular frames WINDOW_UPDATE y SETTINGS para forzar al servidor a transmitir datos en fragmentos mínimos — replicando el efecto del Slow Read Attack en la capa de aplicación. Los límites de http2_max_concurrent_streams y los timeouts de stream son necesarios para mitigar estos vectores.

Cómo implementar en Azion

Azion neutraliza los ataques low and slow antes de que lleguen al origen:

  1. Request Buffering en el edge: Los data centers de Azion montan y validan cada solicitud HTTP completa antes de abrir la conexión con el servidor de origen. Las conexiones que no completan headers o cuerpo dentro de los límites configurados se descartan en el edge, sin impactar nunca el backend.
  2. Timeouts agresivos por fase: El edge aplica timeouts distintos para la recepción de headers, cuerpo y envío de respuesta, terminando las conexiones lentas antes de que agoten los recursos downstream.
  3. Limitación de conexiones por IP: El edge aplica límites de conexiones simultáneas por IP, impidiendo que un único cliente ocupe decenas de recursos en el servidor de origen.
  4. Bot Manager con JA3/JA4 Fingerprinting: Identifica herramientas de ataque como Slowloris y R.U.D.Y. mediante TLS fingerprinting (hashes JA3/JA4) y análisis conductual, bloqueando conexiones sospechosas antes de que completen el handshake HTTP.
  5. WAF con análisis de comportamiento: Detecta patrones de transmisión anómalos — timing mecánico, ausencia de headers de navegador, secuencias de solicitudes incompatibles con el comportamiento humano — complementando el fingerprinting con análisis de capa 7.

Aprende más en la documentación del WAF de Azion.

mantente actualizado

Suscríbete a nuestro boletín informativo

Recibe las últimas actualizaciones de productos, destacados de eventos y conocimientos de la industria tecnológica directamente en tu bandeja de entrada.