Operación ENCO: crónica de una intrusión en infraestructura crítica | HackConRD 2026

Cómo construí un laboratorio de alta fidelidad para emular el malware FrostyGoop y generar impacto físico real usando solo Modbus TCP.

Cómo construí un laboratorio de alta fidelidad para emular el malware FrostyGoop y generar impacto físico real usando solo Modbus TCP.

En enero de 2024, miles de residentes de Lviv, Ucrania, se quedaron sin calefacción en pleno invierno. No fue una falla mecánica. Fue un ataque dirigido contra la infraestructura de calefacción urbana de la ciudad. El culpable: FrostyGoop, el primer malware conocido en usar el protocolo Modbus TCP directamente para causar daño físico a infraestructura crítica, sin explotar ninguna vulnerabilidad de software.

Eso se me quedó grabado. Así que decidí replicarlo.

Este post es la crónica técnica del Proyecto ENCO, un laboratorio de alta fidelidad que presenté en la HackConRD 2026, emulando ese ataque de principio a fin: desde la intrusión inicial en un router perimetral hasta el apagado físico de una caldera simulada.

¿Por qué replicar FrostyGoop?

FrostyGoop rompe un mito cómodo en la industria: que los sistemas ICS son seguros porque un atacante necesita un conocimiento profundo de ingeniería industrial para causar daño. La realidad es más simple e incómoda: con saber Modbus es suficiente.

El objetivo del laboratorio era demostrar exactamente eso, de forma reproducible, con hardware real, y mapeando cada fase contra el framework MITRE ATT&CK for ICS.

Modelo de amenaza

Antes de hablar de hardware y código, definí el modelo de amenaza del laboratorio:

  • Vector de entrada: explotación remota de un router perimetral expuesto a Internet.
  • Interacción del usuario: ninguna. El ataque es totalmente remoto y automatizado.
  • Tipo de ataque: movimiento lateral de IT a OT, seguido de manipulación de la lógica industrial.
  • Impacto: interrupción de maquinaria crítica mediante falsificación de datos de sensores (sensor spoofing).

Montaje del entorno

Hardware: la planta simulada

Figura 1: Vista general del hardware del laboratorio.

La planta física está compuesta por:

  • ESP32 programado para emular un PLC con Modbus TCP.
  • Sensor DHT22 leyendo la temperatura ambiente real, haciendo que los datos del HMI sean genuinamente en vivo.
  • Relé de 5V + ventilador actuando como la "caldera". Cuando el PLC recibe la señal correcta, el relé arranca o detiene físicamente el ventilador.
  • Pantalla TFT integrada mostrando el HMI local del PLC en tiempo real.
  • Router GL-MT300N-V2 como el dispositivo perimetral vulnerable.

Software y virtualización

  • Kali Linux (VM): máquina del atacante.
  • Windows 10 (VM): estación de ingeniería (víctima intermedia).
  • Python 3.12 + pymodbus: herramientas del atacante y del operador.
  • Protocolos: WinRM/RDP para administración remota, Modbus TCP para comunicación con el PLC.

Infraestructura de red

Figura 2: Salida de ipconfig en la estación de ingeniería Windows 10 mostrando ambas interfaces de red IT/OT.

La red está dividida en dos segmentos para replicar una arquitectura industrial real:

Segmento IT: 192.168.8.0/24

  • Kali Linux (atacante): 192.168.8.169
  • Windows 10 (estación de ingeniería): 192.168.8.210
  • Router GL-MT300N-V2: 192.168.8.1

Segmento OT: 172.16.9.0/24

  • PLC ENCO (Modbus TCP): 172.16.9.118
  • Windows 10 (segunda interfaz OT): 172.16.9.220

El router actúa como punto de entrada y también como puente entre ambas redes, y es el primer objetivo del atacante.

El ataque: 5 fases

Fase 1: Acceso inicial

El GL-MT300N-V2 corría la versión de firmware 3.105, que contiene una vulnerabilidad de inyección de comandos en la API CGI. El problema crítico no era solo la vulnerabilidad en sí: el panel de administración estaba expuesto a Internet y funcionando con credenciales por defecto.

Figura 3: Panel de administración GL-iNet mostrando la pantalla de login por defecto.

Figura 4: Firmware GL-iNet desactualizado versión 3.105, la superficie de ataque inicial.

Usando un script de Python personalizado (mangopunch.py), la autenticación y la entrega del payload se automatizaron por completo. El resultado: una reverse shell con uid=0(root) en el router.

Figura 5: Ejecución de mangopunch.py logrando RCE autenticado en el GL-MT300N-V2.

Control total del dispositivo perimetral, en segundos.

Figura 6: Ejecución de mangopunch.py resultando en una reverse shell con root.

Fase 2: Movimiento lateral (IT → OT)

Desde el router comprometido, la enumeración del sistema reveló un archivo de configuración (setup_ot_bridge.bak) que contenía credenciales en texto plano para la estación de ingeniería Windows 10.

Con esas credenciales, se usó WinRM (Windows Remote Management) para iniciar sesión en la máquina de forma legítima. Sin alertas. Sin anomalías. Solo un inicio de sesión más.

Figura 7: Credenciales en texto plano encontradas en setup_ot_bridge.bak.

Dentro de la estación de trabajo, el directorio C:\ENCO_Tools contenía herramientas de diagnóstico industrial dejadas por los operadores, incluyendo un README con una nota crítica sobre el Registro 101: "Si se pone en 1, la caldera entra en Modo de Protección contra Heladas (Logic Hijack)."

Los atacantes no solo habían encontrado la forma de entrar. Habían encontrado el manual.

Figura 8: README de ENCO_Tools documentando el Registro 101, el vector de secuestro de lógica.

Fase 3: Reconocimiento OT (Living off the Land)

Aquí la operación adopta la filosofía central de FrostyGoop: no despliegues malware nuevo si puedes usar lo que ya está ahí.

El script discovery.py, dejado por los propios operadores, usaba pymodbus para leer los registros 100-109 del PLC en tiempo real. El atacante simplemente lo ejecutó, sin modificarlo. En segundos tenía un flujo de datos en vivo del PLC: temperatura real del sensor DHT22, estados de actuadores, todos los valores operativos.

Figura 9: Código fuente de discovery.py y salida en vivo de DATA_STREAM mostrando los valores de los registros del PLC en tiempo real a 24.4 °C, condiciones normales de operación antes del ataque.

Temperatura: 24.4 °C. Setpoint configurado: 35 °C. El sistema funcionaba con normalidad. Por ahora.

Fase 4: Manipulación de la lógica (el efecto FrostyGoop)

Con un mapa completo de la lógica del PLC, se desplegó el payload final: frosty_trigger.py. Este script no explota ninguna vulnerabilidad de software. Simplemente abre una conexión Modbus TCP al puerto 502 y escribe dos valores:

  • Registro de temperatura: inyecta 450 (que representa 45.0 °C), muy por encima del setpoint de 35 °C.
  • Registro 101 (Override): escribe 1, activando el Modo de Protección contra Heladas.

Figura 10: Ejecución de frosty_trigger.py estableciendo un enlace industrial con el PLC y confirmando la inyección de lógica exitosa vía Modbus TCP.

El PLC recibe datos perfectamente válidos, desde una IP autorizada, por el protocolo correcto, en el formato correcto. No hay nada que un sistema de seguridad convencional pueda detectar. La propia lógica de protección de la planta hace exactamente lo que fue diseñada para hacer.

Confirmado en el DATA_STREAM:

Figura 11: Salida de discovery.py posterior al ataque confirmando el valor de temperatura inyectado de 45.0 °C y el Registro 101 en 1.

Fase 5: Impacto físico

El PLC interpreta los 45 °C como una condición de sobrecalentamiento. Siguiendo su lógica interna de protección, ejecuta el mecanismo de seguridad configurado: ordena el apagado de la caldera.

El relé se abre. El ventilador se detiene. En el HMI:

  • Temperatura reportada: 45.0 °C
  • Setpoint: 35 °C
  • Caldera: OFF (IDLE)

En un sistema real, esto es una planta de calefacción urbana dejando a miles de personas sin calor en pleno invierno. En el laboratorio, es un pequeño ventilador que deja de girar. La lógica es idéntica.

Figura 12: Dashboard en la pantalla TFT del HMI mostrando BOILER: OFF (IDLE) a 45.0 °C, junto al hardware físico con el relé abierto y el ventilador detenido, impacto físico confirmado.

Figura 13: Dashboard web del HMI mostrando BOILER: OFF (IDLE) a 45.0 °C, junto al hardware físico con el relé abierto y el ventilador detenido, impacto físico confirmado.

Mapeo de TTP: MITRE ATT&CK for ICS

Cada fase del ataque mapea directamente al framework:

Tabla 1. Mapeo de TTP de FrostyGoop.

FrostyGoop en MITRE ATT&CK

Recomendaciones

Lo que este laboratorio deja claro va más allá de lo técnico. Las defensas que habrían detenido este ataque son bien conocidas:

Segmentación estricta de red entre IT y OT, sin rutas directas desde Internet hacia los controladores. Si el router no hubiera sido el puente hacia la red OT, el ataque termina en la Fase 1.

Autenticación multifactor (MFA) en todos los accesos remotos. Las credenciales en texto plano dentro de un archivo de configuración son una falla básica de higiene que hizo trivial la Fase 2.

Monitoreo de protocolos industriales: desplegar capacidades de detección específicamente sobre el tráfico Modbus TCP para alertar de escrituras inusuales en registros de control o reconfiguraciones no autorizadas.

Plan de respuesta a incidentes OT con procedimientos de operación manual, para que un ataque como este no deje a los operadores sin opciones de recuperación cuando los sistemas automatizados están comprometidos.

Conclusión

El Proyecto ENCO demuestra algo que la industria necesita escuchar más a menudo: los atacantes no necesitan entender de ingeniería industrial para apagar una planta. Necesitan acceso a la red y conocimiento del protocolo. Eso es todo.

La convergencia IT/OT es inevitable. Modbus tiene 45 años y no va a desaparecer mañana. La brecha entre esas dos realidades es exactamente donde viven ataques como FrostyGoop, y donde laboratorios como ENCO intentan encender una luz antes de que alguien apague la calefacción.

Presentado en la HackConRD 2026 · Seguridad de Infraestructura Crítica (OT/ICS)

¿Preguntas sobre el montaje o quieres replicarlo? Los comentarios están abiertos.

Si te interesa seguir mis próximos artículos sobre OT/ICS, certificaciones, contenido de HTB y experiencias de Red Team, te invito a conectar conmigo en LinkedIn.