
Aviso técnico público y evidencia de reproducción para CVE-2026-52134 que afecta el manejo de reproducción de GOOSE en libiec61850 v1.6.
Se ha asignado CVE-2026-52134. La publicación del registro CVE correspondiente está pendiente.
src/goose/goose_receiver.cparseGoosePayload()La ruta de recepción del suscriptor GOOSE en libiec61850 v1.6 no rechaza adecuadamente ciertos mensajes GOOSE reinyectados u obsoletos antes de actualizar el estado visible por el suscriptor e invocar la devolución de llamada (callback) del listener registrado.
Dos experimentos controlados demuestran un comportamiento relacionado en la misma ruta de recepción:
stNum inferior: después de que el suscriptor procesara , reinyectar una trama capturada previamente hizo que el listener volviera a informar el estado y los datos anteriores.stNum=2stNum=1sqNum no creciente: cuando se reinyectó una trama capturada previamente con el mismo stNum pero un sqNum más antiguo, la trama se marcó como no válida, pero los callbacks del listener siguieron ocurriendo y los datos reinyectados permanecieron visibles.Estos se presentan como dos observaciones relacionadas de un único problema de manejo de replay/frescura de mensajes, no como dos CVEs separados.
Un atacante debe poder:
0x88B8Esto no es un ataque remoto arbitrario basado en Internet.
La lógica de recepción relevante comprueba sqNum cuando el stNum recibido es igual al stNum almacenado. La ruta de código probada no rechaza un stNum inferior antes de que se actualice el estado del suscriptor y se invoque al listener.
El archivo de la librería probado no fue modificado. Las copias original y de trabajo de src/goose/goose_receiver.c tenían el mismo valor SHA-256:
c42f2aec80f605c458d0bca524ccb09f2e35f9b83a02f854f95d9444616c075b

veth0 / veth1 de LinuxtcpdumpEl banco de pruebas produjo transiciones de estado controladas e imprimió los valores de stNum, sqNum, validez y datos visibles por el callback. El archivo vulnerable de la librería no fue modificado.
El publicador controlado envió dos estados:
State A: stNum=1, sqNum=0, data=1111
State B: stNum=2, sqNum=0, data=2222
La captura de paquetes de línea base contenía dos tramas GOOSE en este orden:
Frame 1: stNum=1, sqNum=0
Frame 2: stNum=2, sqNum=0

La salida del suscriptor también contenía un callback auxiliar para stNum=1, sqNum=0 marcado como valid=false antes del Estado B. Este callback auxiliar se conserva en las evidencias, pero no se utiliza como base para la conclusión del retroceso. El estado decisivo previo a la reinyección fue el callback posterior que contenía stNum=2 y el valor de datos 2222.
El script de replay cargó la captura de línea base de dos tramas, seleccionó la trama 1 y la envió una vez a través de veth0.
Inmediatamente antes del replay, el listener había informado:
stNum=2, sqNum=0, valid=true, allData={2222}
Después de que la trama antigua se reinyectó una vez, el listener informó:
stNum=1, sqNum=0, valid=true, allData={1111}

Esto demuestra un retroceso observado del estado del suscriptor de stNum=2 a stNum=1 después de reinyectar una trama capturada previamente con un stNum inferior.
Se enviaron cuatro copias más de la misma trama antigua. Las cuatro contenían stNum=1, sqNum=0.
Las copias posteriores se informaron como valid=false, pero los números de callback continuaron aumentando y los datos reinyectados permanecieron visibles:

Esta observación secundaria muestra que marcar una trama repetida como no válida no impidió la entrega al listener en la ruta de recepción probada.
Una reproducción anterior utilizó el publicador y el suscriptor de ejemplo oficiales. El publicador produjo una secuencia normal con:
stNum=1
sqNum=0, 1, 2, 3
La primera trama capturada (stNum=1, sqNum=0) se reinyectó después de que el suscriptor ya hubiera procesado el valor posterior de la secuencia.

Las copias reinyectadas se informaron como no válidas porque el sqNum=0 recibido no era más reciente que el valor de secuencia almacenado. Sin embargo, el suscriptor continuó imprimiendo eventos del listener que contenían los datos reinyectados:

Este experimento respalda una observación más limitada pero relacionada:
Las capturas de pantalla originales sin procesar del replay se conservan como material de respaldo:
Esas imágenes sin procesar contienen advertencias de importación de módulos opcionales de Scapy no relacionadas. Las advertencias no impidieron que el script informara de las tramas GOOSE capturadas y completara la transmisión, pero las capturas de pantalla más limpias de arriba son las preferidas para revisar el resultado técnico.
Los experimentos demuestran diferentes ramas del mismo problema de replay/frescura de mensajes de GOOSE:
| Observación | Mensaje recibido | Resultado observado |
|---|---|---|
Replay de stNum inferior | stNum=2 almacenado; recibido stNum=1 antiguo | El estado y los datos antiguos se entregaron al listener y se informaron como válidos en la ejecución probada |
Replay de sqNum no creciente | Mismo stNum; recibido sqNum más antiguo o duplicado | El mensaje se informó como no válido, pero los callbacks del listener y la entrega de los datos reinyectados continuaron |
La primera observación es el hallazgo principal del CVE porque demuestra un retroceso de un estado más nuevo a un estado más antiguo. La segunda observación es evidencia de respaldo sobre cómo los replays no válidos del mismo estado continúan a través de la ruta del listener.
El impacto demostrado a nivel de software es:
stNum más nuevo a un stNum más antiguo.Las aplicaciones que consumen datos del callback sin una aplicación independiente de frescura pueden procesar valores obsoletos o reinyectados.
El efecto posterior depende de la aplicación del suscriptor, la configuración, la lógica de enclavamiento y la lógica de protección.
No se probó ni operó ningún relé de protección físico, circuito de disparo, disyuntor ni red de subestación de producción en estos experimentos.
Antes de actualizar el estado del suscriptor o invocar al listener:
stNum recibido que sea más antiguo que el último stNum aceptado.stNum no haya cambiado, rechazar un sqNum no creciente.stNum y valores repetidos de sqNum.Las siguientes imágenes proporcionan información de procedencia y del entorno. Respaldan la reproducción, pero no son individualmente necesarias para comprender el resultado principal.





El resultado demostrado es la aceptación de replay y la entrega de estado obsoleto. No depende de demostrar que la autenticación criptográfica estaba habilitada en el despliegue probado.
Informado por: