El gusano de Morris: el fallo no fue atacar, fue defenderse
El 2 de noviembre de 1988 un gusano que no borraba nada alcanzó, según se estima, a uno de cada diez ordenadores de internet y dejó muchos inservibles. La culpa la tuvo una línea defensiva: reinstalarse una de cada siete veces para que nadie pudiera vacunarse. Es el patrón de tu tormenta de reintentos.
Hoy se cumplen años del primer incidente que tumbó una parte grande de internet.
El 2 de noviembre de 1988, hacia las ocho y media de la tarde en la costa este de Estados Unidos —de madrugada ya en España—, Robert Tappan Morris, estudiante de posgrado en Cornell, soltó un programa desde una máquina del MIT. Lo lanzó desde allí, y no desde su universidad, para despistar sobre su origen.
Se estima que en veinticuatro horas alcanzó unos 6.000 de los aproximadamente 60.000 ordenadores que entonces estaban conectados. Uno de cada diez.
Y no pretendía romper nada. Según la sentencia que lo condenó, lo que buscaba era demostrar lo frágil que era la seguridad de la red, aprovechando los fallos que había descubierto.

El disquete con el código del gusano, en el Museum of Science de Boston. Foto: Go Card USA, CC BY-SA 2.0; imagen disponible bajo la misma licencia. La imagen de portada de este artículo es una composición a partir de esta foto y se distribuye bajo la misma licencia.
El 14 % que lo cambió todo
El programa estaba pensado para extenderse: llegar a una máquina, copiarse y seguir. Nada de borrar, nada de cifrar, nada de robar.
Morris incluyó una comprobación evidente: antes de instalarse, preguntar si ya había una copia suya en esa máquina. Si la había, no duplicarse.
Pero se le ocurrió una objeción razonable: un administrador espabilado podría hacer que su máquina contestara siempre que sí, y con eso vacunarse gratis. Para evitarlo, programó que, aun recibiendo un sí, el gusano se instalara igualmente en torno a un 14 % de las veces. Una de cada siete.
Ese uno de cada siete es toda la historia.
Con propagación entre miles de máquinas, «una de cada siete» deja de ser una excepción y se convierte en crecimiento. Los ordenadores se infectaban decenas de veces, cada copia consumía procesador y memoria, y las máquinas se paraban. No por lo que hacía el gusano, sino por cuántas veces lo hacía a la vez.
Un experimento se convirtió en una denegación de servicio por una línea de código defensiva.
Esto te pasa todos los meses
No te propagas por internet, pero el patrón se parece mucho y probablemente ya lo has sufrido.
Tu servicio va lento. Los clientes tienen reintentos configurados, porque reintentar es lo sensato. Así que ante la lentitud, cada cliente manda la petición otra vez. Y otra. El servicio, que iba lento por una causa cualquiera, ahora recibe el triple de tráfico. Va más lento. Se reintenta más.
Se llama tormenta de reintentos y es el mismo patrón: una medida defensiva razonable que, multiplicada, se vuelve el problema.
Variantes que verás:
- Todos los clientes reintentan al mismo intervalo exacto, de modo que las peticiones llegan sincronizadas en oleadas en lugar de repartidas.
- Un
cronque se ejecuta cada cinco minutos y tarda ocho: el siguiente arranca antes de que termine el anterior. Si además se estorban y cada uno tarda más, se van amontonando. - Un reintento que se hace en cada capa: el cliente hace hasta tres intentos, la pasarela hasta tres y el servicio interno hasta tres. Un fallo puede acabar en veintisiete peticiones al fondo.
- Una caché que caduca a la vez para todas las claves y manda a todo el mundo a la base de datos en el mismo segundo.
Para los reintentos, las medidas que reducen el riesgo son baratas: espera creciente entre intentos, aleatoriedad en esa espera para que nadie coincida, y un cortacircuitos que deje de intentarlo del todo cuando el fallo es sostenido. Y un límite de intentos en una sola capa, no en las tres. Los otros dos casos piden lo suyo: el cron, un bloqueo que le impida solaparse consigo mismo; la caché, repartir las caducidades o que solo una petición regenere cada clave.
Por dónde entraba
Los vectores del gusano son un catálogo de 1988 que se lee incómodamente actual:
- Un desbordamiento de búfer en el servicio
finger, por no comprobar el tamaño de lo que entraba. - Un
sendmailque en muchas instalaciones estaba compilado en modo depuración, lo que permitía ejecutar órdenes. - Las relaciones de confianza entre máquinas: si A confía en B, quien esté en B pasa a A sin credenciales.
- Y un diccionario de contraseñas frecuentes incorporado en el propio programa.
Traduce cada uno a hoy: validación de entrada, servicios con la depuración activada en producción, confianza implícita entre sistemas de la misma red, y contraseñas que se adivinan con una lista. Los cuatro siguen siendo los cuatro. Ya escribí sobre lo que cuesta la contraseña cómoda y sobre por qué «aquí no hay nada que robar» no es una medida de seguridad.
Lo que salió de aquella noche
Dos cosas duraderas.
La primera: Morris fue la primera persona condenada en firme bajo la Ley de Fraude y Abuso Informático estadounidense de 1986. Tres años de libertad condicional, 400 horas de servicio comunitario y algo más de diez mil dólares de multa. Ni un solo dato borrado y una condena penal. No fue necesario demostrar que quisiera causar el daño: bastó el acceso intencionado sin autorización y el perjuicio que provocó. Es la parte que conviene recordar antes de lanzar un escaneo «solo para ver» contra una red que no es tuya, y la razón por la que el perfil que más preocupa nunca es el que busca hacer daño, sino el que lo abre por probar.
La segunda, y más importante: aquel desastre dejó claro que no había nadie a quien llamar. No existía un sitio donde reportar un incidente que afectara a media red. De ahí salió el primer equipo de respuesta a emergencias informáticas, el CERT, y con él la idea entera de que estas cosas se coordinan. Todo lo que hoy damos por hecho al gestionar el día después empieza esa noche.
Feliz aniversario
Tres cosas para hoy:
- Cuenta las capas de tu sistema que reintentan. Si es más de una, multiplica los números y mira el resultado.
- Comprueba que tus reintentos tienen espera creciente y aleatoria. Un
sleep(5)fijo es una oleada esperando a ocurrir. - Busca algún servicio con la depuración activada en producción. Lleva ahí desde aquella migración de hace dos años.
(Y la moraleja de fondo: la parte peligrosa del código de Morris no fue la que atacaba. Fue la que defendía. Casi siempre es así.)
Preguntas frecuentes
¿Qué fue el gusano de Morris?
Fue un programa autorreplicante liberado el 2 de noviembre de 1988 por Robert Tappan Morris, entonces estudiante de posgrado en Cornell, desde un equipo del MIT. Según la sentencia que lo condenó, su objetivo era demostrar las deficiencias de seguridad de la red explotando fallos que había descubierto. Se propagó aprovechando varias vulnerabilidades conocidas y se estima que en veinticuatro horas alcanzó unos 6.000 de los aproximadamente 60.000 ordenadores conectados a internet, dejando muchos de ellos inoperativos por saturación.
¿Por qué causó tanto daño si no destruía datos?
Porque su autor incorporó una replicación forzada en torno al catorce por ciento de los casos, incluso cuando la máquina indicaba estar ya infectada. La medida pretendía impedir que los administradores neutralizaran el programa simulando esa respuesta, pero en la práctica permitió que cada equipo acumulara numerosas copias simultáneas, agotando su procesador y su memoria hasta dejarlo inutilizable.
¿Qué es una tormenta de reintentos?
Es la situación en la que la degradación de un servicio provoca que sus clientes repitan las peticiones fallidas, incrementando la carga y agravando la degradación en un ciclo que se retroalimenta. Se agrava cuando los reintentos se producen a intervalos fijos, lo que sincroniza las peticiones en oleadas, y cuando varias capas del sistema reintentan de forma independiente, multiplicando el número total de solicitudes generadas por un único fallo.
¿Cómo se previene ese comportamiento?
Para los reintentos, con cuatro medidas complementarias: incrementar progresivamente el intervalo entre intentos, añadir una componente aleatoria a ese intervalo para evitar la sincronización entre clientes, incorporar un cortacircuitos que suspenda los intentos cuando el fallo se mantiene y limitar los reintentos a una sola capa de la arquitectura. Otros casos del mismo patrón piden medidas propias: impedir que una tarea programada se solape consigo misma o repartir las caducidades de una caché.
¿Qué consecuencias legales e institucionales tuvo el incidente?
Robert Tappan Morris fue la primera persona condenada en firme conforme a la Ley de Fraude y Abuso Informático estadounidense de 1986, con tres años de libertad condicional, cuatrocientas horas de servicio comunitario y una multa de 10.050 dólares, pese a que el programa no destruía información. El tribunal de apelación concluyó que no era necesario demostrar intención de causar el daño: bastaban el acceso intencionado sin autorización y el perjuicio resultante. En el plano institucional, el episodio motivó la creación del primer equipo de respuesta ante emergencias informáticas, el CERT.
El blog, día a día
¿Te ha resultado útil o quieres comentar algo?
Hablemos →