WannaCry: cómo un solo ordenador podía convertir una red entera en un incendio digital

En mayo de 2017 ocurrió algo que, visto desde fuera, parecía casi imposible: un ransomware empezó a aparecer en ordenadores de todo el mundo y, en cuestión de horas, había afectado a organizaciones de decenas de países.
Su nombre era WannaCry.
Lo que hacía especialmente peligroso a WannaCry no era únicamente que cifrara archivos y pidiera un rescate. Lo verdaderamente extraordinario era que tenía comportamiento de gusano informático (worm): una máquina infectada podía buscar otras máquinas vulnerables y tratar de infectarlas automáticamente.
Para entender cómo funcionaba, conviene olvidarse por un momento de la imagen de un hacker sentado frente a un ordenador. En WannaCry, gran parte del trabajo lo hacía el propio programa.
Primero: ¿cómo llegó WannaCry a un ordenador?
Aquí hay una pequeña corrección importante respecto a una idea que suele repetirse sobre el ataque.
No se conoce con certeza cuál fue el vector inicial exacto de la campaña de WannaCry. Microsoft señaló en sus primeros análisis que podían existir varias posibilidades, incluyendo ingeniería social, pero también que una máquina vulnerable podía ser comprometida directamente mediante SMB desde otra máquina infectada.
Lo que sí conocemos con bastante claridad es lo que sucedía después de que una máquina estuviera comprometida.
Ahí comenzaba la parte de gusano.
El ingrediente fundamental: SMB
Windows utilizaba —y todavía utiliza en determinados contextos— SMB (Server Message Block) para compartir recursos como archivos e impresoras entre equipos.
En 2017 existía una vulnerabilidad crítica que afectaba a implementaciones antiguas de SMBv1.
El problema fue que muchísimos sistemas todavía no habían instalado el parche.
WannaCry incorporaba código de explotación relacionado con EternalBlue, que permitía atacar determinados sistemas Windows vulnerables a través de SMB.
Por eso la situación podía ser:
RED INTERNA
┌───────────────┐
│ PC A │
│ infectado │
└───────┬───────┘
│
busca otros equipos
│
┌───────┼────────┐
▼ ▼ ▼
PC B PC C PC D
vulnerable parcheado vulnerable
│ │
▼ ▼
infectar infectar
PC C podía estar perfectamente en la misma red y no resultar vulnerable.
Estar conectado a la red no era suficiente.
La máquina tenía que exponer el servicio correspondiente y ser susceptible a la vulnerabilidad que WannaCry estaba explotando.
Microsoft documentó que WannaCry intentaba infectar máquinas Windows sin parchear tanto en redes locales como mediante un escaneo masivo de direcciones IP de Internet.
Entonces, ¿cómo se “clonaba”?
Aquí está la parte que suele resultar confusa.
WannaCry no hacía algo parecido a:
“Voy a escribir mi código fuente dentro de otro ordenador.”
El malware ya era un programa compilado.
Podemos simplificarlo mentalmente así:
Código del malware
│
▼
ejecutable
│
▼
máquina A
Cuando A encontraba otra máquina vulnerable, el proceso era aproximadamente:
A está infectada
│
▼
Busca otros equipos
│
▼
Encuentra B
│
▼
B es vulnerable a SMB
│
▼
Explota la vulnerabilidad
│
▼
Consigue ejecutar código en B
│
▼
Coloca/ejecuta el payload de WannaCry
│
▼
B queda infectada
Microsoft observó que, después de conseguir la explotación, WannaCry ejecutaba código a nivel de kernel relacionado con DOUBLEPULSAR, con modificaciones destinadas a colocar y ejecutar el componente del ransomware.
Y aquí aparece la parte verdaderamente interesante:
B ahora puede hacer exactamente lo mismo que A.
A 🦠
/ \
/ \
▼ ▼
B 🦠 C 🦠
/ \ \
▼ ▼ ▼
D 🦠 E 🦠 F 🦠
No hay un operador humano diciéndole a cada máquina qué hacer.
Cada nueva máquina infectada se convierte en otro punto desde el que el gusano puede continuar buscando objetivos.
Una maqueta para entenderlo
Podemos representar el concepto sin tocar una red real.
Imaginemos que cada carpeta representa una computadora:
laboratorio/
├── PC_1/
├── PC_2/
├── PC_3/
├── PC_4/
├── PC_5/
└── PC_6/
Y que un programa consigue pasar de una de esas carpetas a otra:
programa original
│
▼
PC_1
│
copia
▼
PC_2
│
nueva copia
▼
PC_4
Esto es únicamente la parte conceptual de:
“hay un programa y consigue colocar una copia en otro lugar”.
WannaCry añadía una pieza muchísimo más compleja y peligrosa: cómo conseguir que ese “otro lugar” fuera una máquina remota y cómo conseguir ejecución allí mediante una vulnerabilidad.
Nuestra maqueta no intentará reproducir esa parte.
¿Qué ocurría realmente en WannaCry?
Podemos colocar las piezas reales sobre nuestro modelo:
MÁQUINA INFECTADA
│
▼
Escaneo de objetivos
│
▼
¿SMB accesible?
│
┌────┴────┐
│ │
NO SÍ
│ │
│ ▼
│ ¿Sistema vulnerable?
│ │
│ ┌───┴───┐
│ │ │
│ NO SÍ
│ │ │
│ │ ▼
│ │ explotación
│ │ │
│ │ ▼
│ │ ejecución de código
│ │ │
│ │ ▼
│ └──► WannaCry
│ │
└─────────────┘
│
▼
nuevo propagador
Microsoft describió precisamente este comportamiento: WannaCry realizaba escaneo de máquinas locales y también generaba grandes cantidades de tráfico SMB al buscar objetivos en Internet. Una máquina que conseguía infectar podía convertirse en el siguiente punto desde el que continuaba la propagación.
Lo que hizo tan grave al ataque
La vulnerabilidad no era nueva cuando ocurrió el brote.
Microsoft había publicado el parche MS17-010 el 14 de marzo de 2017, casi dos meses antes del ataque de mayo.
Eso creó una situación explosiva:
Vulnerabilidad conocida
+
Parche disponible
+
muchas máquinas sin actualizar
+
gusano automatizado
=
propagación masiva
Por eso WannaCry es un ejemplo tan importante en seguridad informática.
El atacante no necesitaba controlar manualmente cientos de miles de ordenadores.
El propio malware hacía el trabajo repetitivo.
¿Y qué pasó con el famoso “kill switch”?
Hay otro detalle fascinante.
Una muestra de WannaCry contenía una comprobación relacionada con un dominio específico. Cuando el investigador de seguridad Marcus Hutchins registró ese dominio, muchas muestras dejaron de continuar con su comportamiento de propagación. Este mecanismo pasó a conocerse popularmente como el “kill switch”.
No fue realmente un botón mágico capaz de desinfectar todas las máquinas; su efecto fue impedir que determinadas muestras continuaran con parte de su ejecución, lo que contribuyó a frenar el brote.
La idea que hay que quedarse
Si tuviéramos que reducir todo WannaCry a una sola idea, sería esta:
UNA MÁQUINA INFECTADA
│
▼
busca otras máquinas
│
▼
encuentra una vulnerable
│
▼
consigue ejecutar código
│
▼
nueva infección
│
▼
NUEVO PROPAGADOR
│
┌──────┴──────┐
▼ ▼
busca busca
otros otros
Por eso WannaCry era más que un ransomware.
El ransomware explicaba qué quería hacer con los archivos.
El componente de gusano explicaba cómo podía llegar automáticamente a muchísimas máquinas.
Y la vulnerabilidad de SMB era el puente que permitía pasar de:
“Tengo control de esta computadora”
a:
“Ahora puedo intentar conseguir control de otra computadora vulnerable.”
Esa combinación —vulnerabilidad + automatización + propagación— fue lo que convirtió un programa malicioso en un brote global.
Y quizá la lección más importante de WannaCry no fue que existiera un malware especialmente sofisticado, sino que una vulnerabilidad ya parcheada podía seguir siendo devastadora cuando permanecían suficientes máquinas sin actualizar.
Microsoft posteriormente señaló que el brote afectó a cientos de miles de equipos y que la propagación mediante EternalBlue fue una de las características que lo distinguieron de un ransomware convencional.
WannaCry por dentro: una simulación segura de cómo un gusano se propaga
Hasta ahora hemos visto que WannaCry no era simplemente un ransomware que cifraba archivos. Una de sus características más importantes era su comportamiento de gusano informático: una máquina comprometida podía buscar otros sistemas vulnerables e intentar comprometerlos automáticamente.
Pero una explicación teórica puede quedarse corta.
Así que vamos a construir una pequeña simulación.
El objetivo no será reproducir WannaCry, sino observar de forma visual una idea concreta:
una instancia puede colocar una copia en otro lugar, ejecutar esa copia y hacer que la nueva instancia continúe el proceso.
No utilizaremos Internet, SMB, vulnerabilidades reales, direcciones IP, sockets, credenciales ni ningún mecanismo de acceso remoto.
En su lugar, cada carpeta de nuestro ordenador representará una computadora diferente.
La idea será:
PC_1 🦠
│
▼
PC_2 🦠
│
▼
PC_3 🛡️ ← parcheada
│
▼
PC_4 🦠
│
▼
PC_5 🦠
│
▼
PC_6 🦠
Pero hay un detalle importante:
no será simplemente una animación que cambia el nombre de PC_1 por PC_2.
Cada copia del programa será realmente ejecutada como una nueva instancia de Python dentro de la maqueta.
Eso nos permitirá observar mucho mejor la idea de:
PC infectada
│
▼
coloca una copia
│
▼
ejecuta esa copia
│
▼
NUEVA INSTANCIA
│
▼
nuevo propagador
1. Nuestro laboratorio
En lugar de utilizar un único archivo para hacerlo todo, vamos a separar la demostración en tres partes:
gusano-demo/
│
├── crear_laboratorio.py
├── ejecutar_gusano.py
├── gusano_simulado.py
└── README.md
crear_laboratorio.py
Su trabajo es únicamente preparar el escenario.
Crea las computadoras ficticias y los archivos basura que utilizaremos durante la demostración.
ejecutar_gusano.py
Será nuestra consola central.
Nos permitirá iniciar la demostración y observar en una sola terminal todo lo que van haciendo las diferentes copias.
gusano_simulado.py
Es el programa que representa el comportamiento del gusano.
Será el archivo que se copie entre nuestras PCs ficticias y cuya nueva copia se ejecutará para continuar la cadena.
Por tanto:
crear_laboratorio.py
│
▼
prepara el mundo
ejecutar_gusano.py
│
▼
inicia y observa
gusano_simulado.py
│
▼
se copia y ejecuta
2. Crear el laboratorio
Primero ejecutamos:
python3 crear_laboratorio.py
Se creará automáticamente:
laboratorio/
│
├── PC_1/
├── PC_2/
├── PC_3/
├── PC_4/
├── PC_5/
├── PC_6/
└── registro.log
Dentro de cada PC habrá además:
PC_X/
│
├── archivos/
│ ├── documento.txt
│ ├── foto.jpg
│ ├── informe.pdf
│ └── datos.csv
│
└── estado.txt
Estos archivos no son documentos reales.
Son archivos ficticios creados específicamente por crear_laboratorio.py.
Incluso foto.jpg y informe.pdf son solamente archivos basura con nombres que nos ayudan a representar distintos tipos de documentos.
Así podemos modificarlos durante la demostración sin tocar ningún archivo personal.
3. Una PC estará “parcheada”
Nuestro laboratorio introduce además algo muy importante.
No todas las máquinas serán vulnerables.
Tendremos:
PC_1 → vulnerable
PC_2 → vulnerable
PC_3 → parcheada
PC_4 → vulnerable
PC_5 → vulnerable
PC_6 → vulnerable
¿Por qué?
Porque anteriormente vimos que estar conectado a una red no era suficiente para que WannaCry pudiera comprometer una máquina.
En nuestro laboratorio no existe una vulnerabilidad real.
Simplemente representaremos esta condición mediante:
estado.txt
Una PC puede contener:
vulnerable
o:
parcheada
Esto sustituye de forma completamente artificial y segura la pregunta:
¿el sistema puede ser comprometido?
por:
¿qué dice estado.txt?
No son equivalentes técnicamente.
Es únicamente una representación visual.
4. El programa
Este será nuestro pequeño laboratorio de propagación:
Gusano Demo — No es malware real
NECESITAS REGISTRARTE PARA DESCARGAR EL CODIGO:
Dentro del ZIP tendremos:
crear_laboratorio.py
ejecutar_gusano.py
gusano_simulado.py
README.md
5. ¿Qué ocurre cuando lo ejecutamos?
Primero creamos el laboratorio:
python3 crear_laboratorio.py
Después iniciamos el gusano falso:
python3 ejecutar_gusano.py
Aparecerá algo parecido a:
==============================================================================
EJECUTAR GUSANO — LABORATORIO SIMULADO
==============================================================================
No hay red, exploits ni cifrado real. Solo carpetas creadas por la demo.
PC_1 ○ → PC_2 ○ → PC_3 🛡️ → PC_4 ○ → PC_5 ○ → PC_6 ○
[CONTROL] Lanzando la primera copia en PC_1...
Nuestra consola central acaba de iniciar la primera instancia.
Entonces aparece:
┌───────────────────────────────────────────────────────────────────┐
│ ▶ NUEVA INSTANCIA EJECUTÁNDOSE EN PC_1 │
└───────────────────────────────────────────────────────────────────┘
[DEBUG] Script activo:
.../gusano_simulado.py
[DEBUG] Proceso PID de Python: 12691
El PID (Process ID) nos resultará especialmente útil.
Identifica el proceso de Python que se está ejecutando.
Más adelante veremos que la siguiente copia tendrá otro PID.
6. PC_1 comienza su trabajo
La simulación muestra:
Procesando PC simulada
[██ ] 20%
[████ ] 40%
[██████ ] 60%
[████████ ] 80%
[██████████] 100%
Después encuentra los archivos ficticios:
[ARCHIVOS] Simulando bloqueo de archivos ficticios...
🔒 documento.txt
→ documento.txt.SIMULADO_BLOQUEADO
🔒 informe.pdf
→ informe.pdf.SIMULADO_BLOQUEADO
🔒 foto.jpg
→ foto.jpg.SIMULADO_BLOQUEADO
🔒 datos.csv
→ datos.csv.SIMULADO_BLOQUEADO
Aquí estamos representando visualmente la parte de ransomware.
Pero hay que entender exactamente qué está ocurriendo.
7. ¿Realmente estamos cifrando los archivos?
No.
Deliberadamente no utilizamos cifrado criptográfico real.
Simplemente hacemos que:
foto.jpg
pase a llamarse:
foto.jpg.SIMULADO_BLOQUEADO
Y:
informe.pdf
pase a:
informe.pdf.SIMULADO_BLOQUEADO
El contenido sigue siendo el mismo archivo ficticio.
No existe ninguna clave criptográfica.
No estamos haciendo inaccesibles los datos.
La finalidad es exclusivamente visual.
Queremos poder abrir:
laboratorio/PC_1/archivos/
y observar inmediatamente:
“Aquí nuestra simulación considera que esos archivos fueron afectados.”
Un ransomware real utilizaría mecanismos criptográficos para hacer que los datos resultaran inaccesibles sin la correspondiente clave de descifrado.
8. PC_1 pasa a estar “infectada”
Después del procesamiento:
🦠 PC_1: estado → INFECTADA (solo simulación)
Ahora tenemos:
PC_1 🦠 → PC_2 ○ → PC_3 🛡️ → PC_4 ○ → PC_5 ○ → PC_6 ○
Hasta aquí solamente hemos procesado una carpeta.
Ahora viene la parte realmente interesante.
9. PC_1 busca el siguiente objetivo
La consola muestra:
[ESCANEO SIMULADO] Revisando PC_2...
Pero cuidado con la palabra escaneo.
No estamos escaneando una red.
No hay paquetes, direcciones IP ni SMB.
Nuestro programa simplemente está mirando la siguiente carpeta permitida dentro de:
laboratorio/
y leyendo su:
estado.txt
Encuentra que PC_2 está marcada como vulnerable.
Por tanto comienza la siguiente fase.
10. PC_1 coloca una copia en PC_2
La consola muestra:
[PROPAGACIÓN] Preparando salto PC_1 → PC_2
Copiando la misma demo
[██ ] 20%
[████ ] 40%
[██████ ] 60%
[████████ ] 80%
[██████████] 100%
✓ Copia creada:
laboratorio/PC_2/gusano_simulado.py
Ahora nuestra estructura contiene:
laboratorio/
│
├── PC_1/
│
└── PC_2/
├── archivos/
├── estado.txt
└── gusano_simulado.py
Conceptualmente:
gusano_simulado.py
│
│ copiar
▼
PC_2/gusano_simulado.py
Pero aquí hay una distinción fundamental:
copiar un programa no significa ejecutarlo.
Si nos detuviéramos aquí, solamente tendríamos una copia inerte dentro de PC_2.
11. El momento clave: PC_1 ejecuta la copia
La consola muestra:
[EJECUCIÓN] PC_1 lanza REALMENTE la copia ubicada en PC_2
$ python laboratorio/PC_2/gusano_simulado.py --pc 2
Y entonces ocurre algo importantísimo:
el programa que estaba ejecutándose para PC_1 acaba de lanzar otra instancia del mismo programa desde PC_2.
Aparece:
┌───────────────────────────────────────────────────────────────────┐
│ ▶ NUEVA INSTANCIA EJECUTÁNDOSE EN PC_2 │
└───────────────────────────────────────────────────────────────────┘
[DEBUG] Script activo:
.../laboratorio/PC_2/gusano_simulado.py
[DEBUG] Proceso PID de Python: 12692
Comparemos:
PC_1 → PID 12691
PC_2 → PID 12692
Ahora podemos visualizar algo que antes solamente describíamos con palabras.
PC_2 está ejecutando otra instancia del programa.
No es simplemente PC_1 cambiando una variable.
Tenemos conceptualmente:
INSTANCIA PC_1
│
│ crea copia
▼
PC_2/gusano_simulado.py
│
│ ejecuta
▼
INSTANCIA PC_2
12. PC_2 ahora puede hacer lo mismo
La nueva instancia comienza:
Procesando PC simulada
Procesa los archivos ficticios de PC_2:
documento.txt
↓
documento.txt.SIMULADO_BLOQUEADO
foto.jpg
↓
foto.jpg.SIMULADO_BLOQUEADO
Y finalmente:
🦠 PC_2: estado → INFECTADA
Ahora tenemos:
PC_1 🦠 → PC_2 🦠 → PC_3 🛡️ → PC_4 ○ → PC_5 ○ → PC_6 ○
Aquí está una de las ideas fundamentales de todo el experimento:
PC_1 ya no necesita hacer personalmente todo el recorrido.
La instancia ejecutada desde PC_2 contiene la misma lógica.
Por tanto puede continuar.
13. PC_2 encuentra una máquina parcheada
PC_2 busca el siguiente objetivo:
[ESCANEO SIMULADO] Revisando PC_3...
Pero obtiene:
🛡️ PC_3: PARCHEADA → se omite.
Nuestra maqueta representa:
PC_2 🦠
│
▼
PC_3 🛡️
X
PC_3 permanece intacta.
Sus archivos continúan llamándose:
documento.txt
foto.jpg
informe.pdf
datos.csv
No recibe una copia ejecutada del programa.
Esto ayuda a visualizar algo importante del WannaCry real:
encontrar una máquina no garantizaba poder comprometerla.
En el ataque real dependía de factores técnicos como que el servicio correspondiente estuviera accesible y que el sistema fuera susceptible a la vulnerabilidad.
En nuestra maqueta lo hemos reducido artificialmente a:
estado.txt = parcheada
14. PC_2 continúa buscando
Después aparece:
[ESCANEO SIMULADO] Revisando PC_4...
PC_4 sí está marcada como vulnerable.
Entonces PC_2 hace exactamente lo que anteriormente hizo PC_1:
PC_2
│
│ copia
▼
PC_4/gusano_simulado.py
│
│ ejecuta
▼
NUEVA INSTANCIA PC_4
La consola muestra:
[PROPAGACIÓN] Preparando salto PC_2 → PC_4
✓ Copia creada:
laboratorio/PC_4/gusano_simulado.py
[EJECUCIÓN] PC_2 lanza REALMENTE la copia ubicada en PC_4
Después:
▶ NUEVA INSTANCIA EJECUTÁNDOSE EN PC_4
Y tendremos otro PID.
Conceptualmente:
PC_1 / proceso 1
│
▼
PC_2 / proceso 2
│
├──── X PC_3 🛡️
│
▼
PC_4 / proceso 3
15. Y la cadena continúa
PC_4 puede copiarse a PC_5.
PC_5 puede ejecutar su copia.
PC_5 puede colocar otra copia en PC_6.
PC_6 se ejecuta y finalmente descubre que ya no quedan más PCs ficticias.
La cadena completa queda:
PC_1 🦠
│
│ copia + ejecuta
▼
PC_2 🦠
│
│ busca
▼
PC_3 🛡️
│
│ parcheada: se omite
▼
PC_4 🦠
│
│ copia + ejecuta
▼
PC_5 🦠
│
│ copia + ejecuta
▼
PC_6 🦠
│
▼
FIN
Esto es mucho más interesante que simplemente copiar el mismo archivo seis veces desde el programa inicial.
Cada nueva copia participa en la continuación de la cadena.
16. ¿Cómo vemos todo desde una sola terminal?
Nuestra demostración utiliza:
laboratorio/registro.log
Las distintas instancias van escribiendo allí sus mensajes.
Conceptualmente:
PC_1 ─────┐
│
PC_2 ─────┤
│
PC_4 ─────┤
├──► registro.log
PC_5 ─────┤
│
PC_6 ─────┘
│
▼
ejecutar_gusano.py
│
▼
TERMINAL
ejecutar_gusano.py puede así enseñarnos todo el proceso de manera ordenada.
Es importante aclarar que esto no intenta representar un servidor de control utilizado por WannaCry.
El registro existe únicamente para nosotros.
Es nuestro observador del laboratorio.
17. El detalle más importante del código
Una de las operaciones fundamentales es conceptualmente:
shutil.copy2(
Path(__file__).resolve(),
copia
)
Significa:
“Toma el programa que se está ejecutando y crea una copia en la siguiente carpeta de nuestro laboratorio.”
Por ejemplo:
gusano_simulado.py
│
│ copiar
▼
laboratorio/PC_2/gusano_simulado.py
Después tenemos conceptualmente:
subprocess.run([
sys.executable,
str(copia),
"--pc",
str(siguiente)
])
Esto significa:
“Inicia otro proceso de Python ejecutando esa copia.”
Y ahí está la diferencia.
No hacemos:
PC_1 procesa PC_1
PC_1 procesa PC_2
PC_1 procesa PC_4
PC_1 procesa PC_5
PC_1 procesa PC_6
La idea es:
PC_1
│
│ ejecuta
▼
PC_2
│
│ ejecuta
▼
PC_4
│
│ ejecuta
▼
PC_5
│
│ ejecuta
▼
PC_6
18. ¿Dónde está el “gusano”?
En realidad, no hay una función mágica llamada:
infectar()
El comportamiento aparece al combinar varias acciones:
ejecutarse
↓
procesar archivos ficticios
↓
buscar siguiente PC del laboratorio
↓
comprobar su estado
↓
si está parcheada → omitir
↓
si es vulnerable → copiarse
↓
ejecutar la copia
↓
la nueva copia hace exactamente lo mismo
Eso es precisamente lo interesante.
El programa no necesita contener:
"infecta PC_2"
"infecta PC_4"
"infecta PC_5"
"infecta PC_6"
La copia que llega a PC_2 es el mismo programa.
Cuando arranca, conceptualmente piensa:
“Ahora estoy representando a PC_2. ¿Cuál es la siguiente PC?”
Encuentra PC_3.
Comprueba su estado.
La omite porque está parcheada.
Encuentra PC_4.
Y continúa.
19. Copiarse no es suficiente
Este detalle merece insistencia.
Supongamos que hacemos:
PC_1/
└── gusano.py
PC_2/
└── gusano.py
PC_3/
└── gusano.py
Eso solamente demuestra que existen tres copias.
No demuestra propagación autónoma.
La parte interesante es:
COPIA 1
│
│ crea COPIA 2
▼
COPIA 2
│
│ SE EJECUTA
▼
COPIA 2 crea COPIA 3
│
▼
COPIA 3 SE EJECUTA
Por eso utilizamos procesos diferentes.
20. ¿Qué estamos sustituyendo respecto a un gusano real?
Aquí está probablemente la distinción más importante de todo el laboratorio.
Nuestra demostración hace:
buscar carpeta
↓
leer estado.txt
↓
copiar archivo
↓
ejecutarlo localmente
Un gusano real tendría que resolver problemas completamente diferentes:
buscar otra máquina
↓
determinar si puede alcanzarla
↓
encontrar una vía de entrada
↓
explotar una vulnerabilidad
↓
conseguir ejecutar código remotamente
↓
colocar/ejecutar el payload
Nosotros eliminamos deliberadamente toda esa parte.
No implementamos SMB.
No implementamos EternalBlue.
No implementamos DOUBLEPULSAR.
No buscamos direcciones IP.
No enviamos tráfico.
No intentamos acceder a otros equipos.
Sustituimos:
MÁQUINA REMOTA
por:
CARPETA
y sustituimos:
¿ES VULNERABLE?
por:
estado.txt
Eso nos permite estudiar la arquitectura conceptual sin construir un mecanismo capaz de propagarse realmente.
21. ¿Y el “cifrado”?
En el ejemplo también simulamos la parte de ransomware.
Pero deliberadamente no utilizamos cifrado criptográfico real.
Nuestro cambio es simplemente:
documento.txt
a:
documento.txt.SIMULADO_BLOQUEADO
El contenido permanece intacto.
Así podemos observar visualmente qué archivos habría considerado “afectados” nuestra simulación.
Por ejemplo:
ANTES
foto.jpg
informe.pdf
datos.csv
documento.txt
DESPUÉS
foto.jpg.SIMULADO_BLOQUEADO
informe.pdf.SIMULADO_BLOQUEADO
datos.csv.SIMULADO_BLOQUEADO
documento.txt.SIMULADO_BLOQUEADO
La finalidad es únicamente visual.
Un ransomware real utilizaría mecanismos criptográficos para hacer que los datos resultaran inaccesibles sin la correspondiente clave de descifrado.
22. Comparándolo con WannaCry
Nuestra simulación:
PC_1
│
▼
buscar siguiente carpeta
│
▼
leer estado ficticio
│
▼
copiar programa
│
▼
ejecutar nueva copia
│
▼
PC_2 se convierte en propagador
WannaCry, conceptualmente:
Máquina infectada
│
▼
buscar otros equipos
│
▼
encontrar objetivo
│
▼
comprobar/explotar vulnerabilidad
│
▼
ejecutar código
│
▼
nueva máquina infectada
│
▼
buscar más objetivos
La diferencia fundamental está en cómo se encuentra y compromete la siguiente máquina.
Nuestro programa simplemente trabaja con:
laboratorio/PC_X/
WannaCry operaba sobre sistemas reales y utilizaba mecanismos de red y vulnerabilidades concretas para conseguir esa propagación.
23. Nuestra PC parcheada también enseña algo
En la demostración:
PC_3 🛡️
no resulta afectada.
Esto nos permite visualizar:
PC_2 🦠
│
▼
PC_3 🛡️
X
En nuestra maqueta ocurre porque:
estado.txt = parcheada
En WannaCry la situación era técnicamente mucho más compleja.
Pero el concepto que queremos recordar es:
estar al alcance de una máquina infectada no significa necesariamente poder ser comprometido.
Esto ayuda también a entender por qué instalar MS17-010 era tan importante.
24. El resultado final
Cuando termina nuestra simulación tendremos algo parecido a:
laboratorio/
│
├── PC_1/
│ ├── archivos/
│ │ ├── documento.txt.SIMULADO_BLOQUEADO
│ │ ├── foto.jpg.SIMULADO_BLOQUEADO
│ │ ├── informe.pdf.SIMULADO_BLOQUEADO
│ │ └── datos.csv.SIMULADO_BLOQUEADO
│ └── estado.txt → infectada
│
├── PC_2/
│ ├── archivos/
│ │ └── ...SIMULADO_BLOQUEADO
│ ├── estado.txt → infectada
│ └── gusano_simulado.py
│
├── PC_3/
│ ├── archivos/
│ │ ├── documento.txt
│ │ ├── foto.jpg
│ │ ├── informe.pdf
│ │ └── datos.csv
│ └── estado.txt → parcheada
│
├── PC_4/
│ ├── archivos/
│ │ └── ...SIMULADO_BLOQUEADO
│ ├── estado.txt → infectada
│ └── gusano_simulado.py
│
├── PC_5/
│ ├── archivos/
│ │ └── ...SIMULADO_BLOQUEADO
│ ├── estado.txt → infectada
│ └── gusano_simulado.py
│
├── PC_6/
│ ├── archivos/
│ │ └── ...SIMULADO_BLOQUEADO
│ ├── estado.txt → infectada
│ └── gusano_simulado.py
│
└── registro.log
PC_3 destaca inmediatamente:
PC_1 🦠
PC_2 🦠
PC_3 🛡️
PC_4 🦠
PC_5 🦠
PC_6 🦠
25. Lo que realmente acabamos de observar
La demostración completa puede resumirse así:
1. Arranca una primera instancia.
2. PC_1 procesa exclusivamente sus archivos ficticios.
3. Busca el siguiente objetivo del laboratorio.
4. Encuentra PC_2.
5. Coloca allí una copia del programa.
6. Ejecuta esa copia como otro proceso de Python.
7. PC_2 comienza a ejecutar la misma lógica.
8. PC_2 procesa sus propios archivos ficticios.
9. Encuentra PC_3.
10. PC_3 está parcheada y se omite.
11. PC_2 encuentra PC_4.
12. Coloca y ejecuta otra copia.
13. PC_4 se convierte en el siguiente propagador.
14. La cadena continúa con PC_5 y PC_6.
15. Finalmente no quedan más objetivos ficticios.
Y ahí está la idea esencial de un gusano informático:
una máquina infectada no es solamente el destino del ataque; puede convertirse en el origen del siguiente ataque.
26. De una máquina a muchas
Ahora podemos volver al dibujo del principio.
Un gusano real no tiene por qué formar una cadena perfecta:
A → B → C → D
Podría conceptualmente crecer así:
A 🦠
/ \
▼ ▼
B 🦠 C 🦠
/ \ \
▼ ▼ ▼
D 🦠 E 🦠 F 🦠
/ \
▼ ▼
G 🦠 H 🦠
Y aquí aparece la razón matemática por la que los gusanos pueden ser tan peligrosos.
Una víctima nueva puede convertirse en otro punto de propagación.
Después dos propagadores pueden convertirse en cuatro.
Cuatro pueden encontrar más objetivos.
Y así sucesivamente.
Nuestro laboratorio utiliza una cadena lineal para que sea fácil seguir qué instancia está trabajando en cada momento.
El WannaCry real no estaba limitado a seis carpetas ni a una ruta predeterminada como ésta.
27. La pieza que deliberadamente falta
Hay una parte de nuestra simulación que hemos sustituido por completo.
Entre:
“encuentro otra máquina”
y:
“ejecuto mi programa allí”
en un ataque real existe precisamente la parte difícil.
En WannaCry conceptualmente:
objetivo
│
▼
SMB accesible
│
▼
sistema susceptible
│
▼
explotación
│
▼
ejecución de código
│
▼
payload
En nuestro laboratorio hacemos:
carpeta PC_X
│
▼
estado.txt
│
▼
shutil.copy
│
▼
subprocess
No pretendemos que técnicamente sean lo mismo.
Precisamente los hemos separado para poder estudiar una parte sin implementar la otra.
Nuestro experimento responde a:
“Supongamos que ya hemos conseguido colocar y ejecutar una copia en el siguiente sistema. ¿Cómo puede esa nueva copia continuar el proceso?”
28. Ahora la palabra “gusano” resulta menos misteriosa
Antes de ver el experimento podríamos imaginar:
“¿Cómo puede un programa infectar miles de máquinas él solo?”
Ahora podemos dividir la pregunta.
Primero:
¿cómo llega a otra máquina?
En WannaCry entran aquí SMB, la vulnerabilidad y la explotación.
Después:
¿qué ocurre cuando consigue ejecutarse allí?
La nueva instancia puede repetir su comportamiento.
Por tanto:
MÁQUINA A
│
│ consigue ejecución en B
▼
MÁQUINA B
│
│ ahora ejecuta el programa
▼
B TAMBIÉN BUSCA
│
▼
MÁQUINA C
Ahí está la propiedad que queríamos hacer visible con nuestro laboratorio.
29. La lección final
En nuestro laboratorio hemos reemplazado:
red real
por:
carpetas
Hemos reemplazado:
vulnerabilidad
por:
estado.txt
Hemos reemplazado:
cifrado de ransomware
por:
.SIMULADO_BLOQUEADO
Y hemos reemplazado:
ejecución en una máquina remota
por:
subprocess ejecutando otra copia local
Pero hemos conservado una idea que resulta muy útil para comprender la arquitectura:
programa ejecutándose
│
▼
encuentra siguiente objetivo
│
▼
coloca una copia
│
▼
ejecuta esa copia
│
▼
NUEVA INSTANCIA
│
▼
nuevo propagador
Eso nos permite observar la mecánica fundamental sin enviar tráfico, explotar sistemas ni modificar equipos externos.
WannaCry llevó una idea similar al mundo real de una forma muchísimo más compleja y peligrosa: automatizó la búsqueda y explotación de sistemas vulnerables, y cada nueva máquina comprometida podía continuar el proceso.
Eso es lo que convirtió una infección individual en algo capaz de propagarse a una escala enorme.
Y quizá ahora resulte más fácil entender por qué WannaCry fue tan extraordinario.
El ransomware explicaba qué ocurría con los archivos.
EternalBlue y la vulnerabilidad de SMB ayudaban a explicar cómo podía saltar a determinados sistemas vulnerables.
Y el comportamiento de gusano explicaba por qué una nueva infección podía convertirse en el comienzo de muchas más.
En otras palabras:
VULNERABILIDAD
+
EJECUCIÓN AUTOMÁTICA
+
NUEVO PROPAGADOR
=
PROPAGACIÓN
Por eso la frase más importante de todo este laboratorio sigue siendo:
Una máquina infectada no es solamente el destino del ataque; puede convertirse en el origen del siguiente ataque.



