
Prova di concetto che riproduce il difetto della chiave hardcoded di CVE-2021-22681 e convalida una correzione mutual TLS/CRL per dispositivo su EtherNet/IP simulato, con mappatura IEC 62443-4-2.
Quattro script eseguibili. Traffico reale del protocollo EtherNet/IP, crittografia reale, zero software Rockwell o licenze in qualsiasi punto della catena. Realizzati per verificare un'affermazione prima di scriverla, non per sostenerla per fede.
Provenienza: realizzato il 2026-07-31, parallelamente a un'indagine sul WWTF di Braham, MN — uno dei quattro servizi pubblicamente divulgati nell'incidente coordinato del settore idrico del Minnesota del 26–27 luglio 2026. Il contesto di quell'incidente è nell'advisory CISA AA26-097A (congiunta FBI/CISA/NSA/EPA/DOE/USCYBERCOM/Treasury; emessa il 2026-04-07, ampliata il 2026-07-22), che copre la campagna in corso CyberAv3ngers affiliata all'IRGC. Caveat sull'attribuzione, mantenuto con precisione: nessuna agenzia ha formalmente attribuito specificamente l'incidente del Minnesota a quel gruppo — solo la più ampia campagna in corso. Questa cartella è il lato della correzione tecnica, tenuta separata di proposito dall'indagine sull'incidente.
Un disclosure packet si gioca tutto sul non confonderli tra loro, perché ciascuno ha una correzione diversa:
La correzione dimostrata qui — binding dell'identità per dispositivo (Test 3) — affronta il guasto della chiave di flotta.
Non confondete le due righe. Il principio è provato. L'implementazione specifica del fornitore è credibile (è la loro dichiarata intenzione progettuale) ma non testata da noi su apparecchiature reali.
test1_baseline_vulnerable.py — la baseline senza autenticazione, dal vivoAvvia un simulatore reale di PLC EtherNet/IP (cpppo, che emula un Allen-Bradley ControlLogix) e legge + scrive un tag di controllo con zero credenziali. (Ambito: questa è l'ampia baseline senza autenticazione su cui ha fatto leva la campagna — non il meccanismo specifico di chiave hardcoded di CVE-2021-22681. Tenuta distinta di proposito; vedi "Tre diversi tipi di guasto" sopra.)
python test1_baseline_vulnerable.py
test2_shared_secret_fails.py — la forma del difetto della chiave di flotta (ponte narrativo, non un test)Due endpoint detengono un'unica chiave statica; una credenziale del Dispositivo A apre il Dispositivo B invariata — l'analogo strutturale più vicino al difetto one-key-fits-all di CVE-2021-22681. Ma è tautologico: entrambi gli handler sono costruiti per accettare quella chiave, quindi non esiste un percorso di esecuzione in cui possa fallire. Non dimostra nulla che il codice non definisca già. Tenuto come ponte narrativo dal Test 1 al Test 3; non ha alcun peso probatorio ed è deliberatamente non una gamba della prova.
python test2_shared_secret_fails.py
test3_mutual_tls_fix.py — la correzione, con il suo controllo negativo ed entrambe le direzioniCA reale, due certificati dispositivo individualmente unici — identità vincolata nel SubjectAlternativeName, non nel deprecato CommonName. Cinque casi, tutti eseguiti:
device-a (check_hostname contro un SAN reale). Mutuo — entrambe le estremità vincolano l'identità.python test3_mutual_tls_fix.py
test4_revocation.py — la gamba del ciclo di vita: la revocaUna CRL reale firmata dalla CA. Una credenziale client (engineer-1) viene concessa; poi il suo seriale viene aggiunto alla CRL, e la stessa credenziale ancora valida, non scaduta, firmata dalla CA viene negata — il contenuto empirico della clausola di revoca CR 1.8 / 1.9. Unicità (Test 3) ≠ revocabilità; questo mostra che una credenziale può essere ripresa indietro.
python test4_revocation.py
test4_revocation.py); rotazione — non ancora. L'unicità per dispositivo (Test 3) non è la stessa cosa della revocabilità; il Test 4 chiude questa lacuna — una credenziale ancora valida, non scaduta, firmata dalla CA viene concessa prima della revoca e negata dopo, unicamente perché la CRL firmata dalla CA ora elenca il suo seriale. Rotazione (riemissione di una credenziale sostitutiva e ritiro della vecchia) è strettamente correlata ed abilitata dalla stessa PKI, ma non è dimostrata separatamente qui — quindi "binding dell'identità per dispositivo" non deve espandersi silenziosamente in "rotazione risolta".presented == KEY, identity in SAN) non sono a tempo costante. Non sfruttabile qui — i valori confrontati sono stringhe di identità semi-pubbliche e TLS ha già svolto la vera autenticazione crittografica prima che il confronto venga eseguito — ma segnalato perché il pattern viene copiato in luoghi dove invece conta.python -m venv venv
venv\Scripts\activate # or: source venv/bin/activate
pip install -r requirements.txt
62443-4-2_SL2_MAPPING.md (CR 1.2 / 1.8 / 1.9 / 1.14 / 3.1, classificato onestamente per livelli, ogni lacuna nominata; CR 1.2, CR 1.9 e la gamba emissione/validazione/revoca di CR 1.8 sono ora dimostrate). Prima del PSIRT ([email protected] / [email protected]): verificare il testo normativo di ogni CR rispetto a una copia acquistata di IEC 62443-4-2:2019.PHASED_ROLLOUT.md (Fase 0 stop-the-bleeding · 1 segmentazione · 2 controlli compensativi · 3 CIP Security/PKI, se l'hardware lo consente · 4 operare). Dimensionato correttamente per una piccola utility; onesto sul fatto che CIP Security è vincolato all'hardware, quindi le Fasi 0–2 portano comunque la riduzione del rischio.Ogni identificatore esterno qui è stato recuperato da una fonte viva il 2026-07-31, non ricordato dall'addestramento: AA26-097A (multi-fonte, incl. WaterISAC / Tenable / SecurityWeek), Braham come uno dei quattro divulgati, CyberAv3ngers/IRGC, PN1550 ha confermato la reale advisory Rockwell con la sua citazione della Riga 2 verificata verbatim ("When properly deployed, CIP Security remediates this vulnerability" + "does not make use of any hardcoded keys"), "cannot be mitigated with a patch" verbatim, CVSS 10.0 / CRITICAL (v3.1), CISA tracking ICSA-21-056-03, e 62443-4-2 CR 1.8 (PKI) + CR 3.1 (integrità delle comunicazioni) confermati esatti.
Disciplina per il pacchetto: ripescare ogni identificatore dalle fonti primarie al momento dell'invio. Le advisory vengono rinumerate, ampliate e sostituite — AA26-097A mostra già un ampliamento — quindi "verificato il 2026-07-31" non è "verificato all'invio." Il mapping formale completo CR-per-CR 62443-4-2 è ora scritto (62443-4-2_SL2_MAPPING.md) — ciò che resta è ripescare il testo normativo citato contro una copia acquistata dello standard prima dell'invio, non scrivere il mapping stesso.
l0gic — Patrick Crosby · 2026-07-31.
Registro di indurimento: Il Test 3 è stato rafforzato per includere il controllo negativo (caso 4, che prova la necessità non solo lo scatto), il caso direzione inversa (caso 5, binding mutuo), e l'identità basata su SAN (non CN), poi riverificato rieseguendo tutti e cinque i casi; è stato aggiunto il Test 4 (revoca CRL). Le didascalie dei Test 1/2 sono state calibrate per mantenere distinte le tre classi di guasto; il Test 2 è stato declassato da "test" a ponte narrativo; sono stati aggiunti i confini di ambito per revoca e tempo costante. La catena di citazioni è stata recuperata dalle fonti primarie e timbrata per il ripescaggio all'invio.
| Affermazione | Livello | Perché |
|---|
| Il principio architetturale | "un singolo segreto condiviso su una flotta è compromesso a livello di flotta da una singola fuga; l'autenticazione legata all'identità per dispositivo lo chiude" | PROVATO | dimostrato con codice reale in esecuzione incluso il controllo negativo che prova che il controllo è necessario, non solo che scatta: su un endpoint rigoroso, il certificato genuinamente valido per la CA del Dispositivo B viene rifiutato per identità (Test 3 · caso 3), ma su un endpoint solo validità-CA lo stesso certificato viene accettato (caso 4 — il controllo) → "essere firmato validamente dalla CA da solo == accesso all'intera flotta == Test 2 in abiti TLS." Il binding vale anche al contrario: un server rogue che presenta un certificato di flotta valido viene rifiutato dal client (caso 5). Il Test 1 mostra separatamente la baseline più ampia senza autenticazione. |
| L'implementazione CIP Security specifica di Rockwell si comporta in modo identico | "abilitare CIP Security su hardware Rockwell reale corregge CVE-2021-22681 esattamente in questo modo" | LEAD, con fonte ma non verificato | questo è il linguaggio dell'advisory Rockwell (PN1550) — "When properly deployed, CIP Security remediates this vulnerability... does not make use of any hardcoded keys" — non qualcosa che abbiamo confermato indipendentemente contro hardware Logix reale. Abbiamo testato il principio che la loro advisory descrive, non la loro esatta implementazione a livello di wire. |