
Avviso tecnico pubblico e prove di riproduzione per la CVE-2026-52134 che riguarda la gestione del replay GOOSE in libiec61850 v1.6.
CVE-2026-52134 è stato assegnato. La pubblicazione del corrispondente record CVE è in sospeso.
src/goose/goose_receiver.cparseGoosePayload()Il percorso di ricezione del subscriber GOOSE in libiec61850 v1.6 non rifiuta adeguatamente alcuni messaggi GOOSE riprodotti (replay) o obsoleti prima di aggiornare lo stato visibile al subscriber e invocare la callback del listener registrato.
Due esperimenti controllati dimostrano un comportamento correlato nello stesso percorso di ricezione:
stNum inferiore: dopo che il subscriber ha elaborato , la riproduzione di un frame catturato in precedenza ha causato la segnalazione da parte del listener dello stato e dei dati più vecchi.stNum=2stNum=1sqNum non crescente: quando è stato riprodotto un frame catturato in precedenza con lo stesso stNum ma un sqNum più vecchio, il frame è stato contrassegnato come non valido, ma le callback del listener si sono comunque verificate e i dati riprodotti sono rimasti visibili.Questi sono presentati come due osservazioni correlate di un unico problema di gestione del replay/freschezza dei messaggi, non come due CVE separati.
Un attaccante deve essere in grado di:
0x88B8Non si tratta di un attacco remoto arbitrario basato su Internet.
La logica di ricezione pertinente controlla sqNum quando lo stNum ricevuto è uguale allo stNum memorizzato. Il percorso di codice testato non rifiuta uno stNum inferiore prima che lo stato del subscriber venga aggiornato e il listener venga invocato.
Il file di libreria testato non è stato modificato. La copia originale e quella di lavoro di src/goose/goose_receiver.c avevano lo stesso valore SHA-256:
c42f2aec80f605c458d0bca524ccb09f2e35f9b83a02f854f95d9444616c075b

veth0 / veth1 di LinuxtcpdumpIl banco di prova ha prodotto transizioni di stato controllate e ha stampato i valori di stNum, sqNum, validità e dati visibili dalla callback. Il file di libreria vulnerabile stesso non è stato modificato.
Il publisher controllato ha inviato due stati:
State A: stNum=1, sqNum=0, data=1111
State B: stNum=2, sqNum=0, data=2222
La cattura di pacchetti di riferimento conteneva due frame GOOSE in questo ordine:
Frame 1: stNum=1, sqNum=0
Frame 2: stNum=2, sqNum=0

L'output del subscriber conteneva anche una callback ausiliaria per stNum=1, sqNum=0 contrassegnata come valid=false prima dello Stato B. Questa callback ausiliaria è conservata nell'evidenza ma non viene utilizzata come base per la conclusione del rollback. Lo stato decisivo pre-replay era la callback successiva contenente stNum=2 e il valore di dati 2222.
Lo script di replay ha caricato la cattura di riferimento a due frame, ha selezionato il frame 1 e lo ha inviato una volta attraverso veth0.
Immediatamente prima del replay, il listener aveva riportato:
stNum=2, sqNum=0, valid=true, allData={2222}
Dopo che il vecchio frame è stato riprodotto una volta, il listener ha riportato:
stNum=1, sqNum=0, valid=true, allData={1111}

Questo dimostra un rollback osservato dello stato del subscriber da stNum=2 a stNum=1 dopo aver riprodotto un frame con stNum inferiore catturato in precedenza.
Sono state inviate altre quattro copie dello stesso vecchio frame. Tutte e quattro contenevano stNum=1, sqNum=0.
Le copie successive sono state riportate come valid=false, ma i numeri delle callback hanno continuato ad aumentare e i dati riprodotti sono rimasti visibili:

Questa osservazione secondaria mostra che contrassegnare come non valido un frame ripetuto non ha impedito la consegna al listener nel percorso di ricezione testato.
Una riproduzione precedente ha utilizzato il publisher e il subscriber di esempio ufficiali. Il publisher ha prodotto una sequenza normale con:
stNum=1
sqNum=0, 1, 2, 3
Il primo frame catturato (stNum=1, sqNum=0) è stato quindi riprodotto dopo che il subscriber aveva già elaborato il valore di sequenza successivo.

Le copie riprodotte sono state riportate come non valide perché lo sqNum=0 ricevuto non era più recente del valore di sequenza memorizzato. Tuttavia, il subscriber ha continuato a stampare eventi del listener contenenti i dati riprodotti:

Questo esperimento supporta un'osservazione più ristretta ma correlata:
Gli screenshot grezzi del replay originale sono conservati come materiale di supporto:
Queste immagini grezze contengono avvisi non correlati relativi all'importazione di moduli opzionali di Scapy. Gli avvisi non hanno impedito allo script di segnalare i frame GOOSE catturati e di completare la trasmissione, ma per esaminare il risultato tecnico sono preferiti gli screenshot più puliti mostrati sopra.
Gli esperimenti dimostrano rami diversi dello stesso problema di replay/freschezza dei messaggi GOOSE:
| Osservazione | Messaggio ricevuto | Risultato osservato |
|---|---|---|
Replay con stNum inferiore | stNum=2 memorizzato; ricevuto vecchio stNum=1 | Lo stato e i dati vecchi sono stati consegnati al listener e riportati come validi nell'esecuzione testata |
Replay di sqNum non crescente | Stesso stNum; ricevuto sqNum più vecchio o duplicato | Il messaggio è stato riportato come non valido, ma le callback del listener e la consegna dei dati riprodotti sono continuate |
La prima osservazione è il risultato principale della CVE perché dimostra il rollback da uno stato più recente a uno più vecchio. La seconda osservazione è un'evidenza di supporto su come i replay non validi dello stesso stato continuino attraverso il percorso del listener.
L'impatto dimostrato a livello software è:
stNum più recente a uno stNum più vecchio.Le applicazioni che consumano i dati della callback senza un controllo indipendente della freschezza potrebbero elaborare valori obsoleti o riprodotti.
L'effetto a valle dipende dall'applicazione subscriber, dalla configurazione, dalla logica di interblocco e dalla logica di protezione.
In questi esperimenti non è stato testato o utilizzato alcun relè di protezione fisico, circuito di sgancio, interruttore automatico o rete di sottostazione di produzione.
Prima di aggiornare lo stato del subscriber o di invocare il listener:
stNum ricevuto più vecchio dell'ultimo stNum accettato.stNum è invariato, rifiutare uno sqNum non crescente.stNum e valori sqNum ripetuti.Le seguenti immagini forniscono informazioni sulla provenienza e sull'ambiente. Supportano la riproduzione ma non sono singolarmente necessarie per comprendere il risultato principale.





Il risultato dimostrato è l'accettazione del replay e la consegna di stato obsoleto. Non dipende dalla dimostrazione che l'autenticazione crittografica fosse abilitata nell'ambiente testato.
Segnalato da: