
Preuve de concept reproduisant la faille de clé codée en dur de CVE-2021-22681 et validant un correctif TLS mutuel/CRL par appareil sur EtherNet/IP simulé, avec mise en correspondance IEC 62443-4-2.
Quatre scripts exécutables. Trafic de protocole EtherNet/IP réel, cryptographie réelle, zéro logiciel ou licence Rockwell dans la chaîne. Conçus pour tester une affirmation avant de la documenter, pas pour la défendre par simple foi.
Provenance : construit le 2026-07-31, en parallèle d'une investigation sur la WWTF de Braham, MN — l'une des quatre installations publiquement divulguées lors de l'incident coordonné du secteur de l'eau du Minnesota des 26 et 27 juillet 2026. Le contexte de cet incident se trouve dans l'avis CISA AA26-097A (conjoint FBI/CISA/NSA/EPA/DOE/USCYBERCOM/Trésor ; publié le 2026-04-07, étendu le 2026-07-22), qui couvre la campagne CyberAv3ngers en cours, affiliée à l'IRGC. Réserve d'attribution, scrupuleusement respectée : aucune agence n'a officiellement attribué l'incident du Minnesota en particulier à ce groupe — seule la campagne plus large en cours l'est. Ce dossier est le volet correctif technique, volontairement tenu séparé de l'investigation sur l'incident.
Un dossier de divulgation se joue sur le fait de ne pas mélanger ces éléments, car chacun a un correctif différent :
Le correctif démontré ici — liaison d'identité par dispositif (Test 3) — répond à la défaillance de la clé de flotte.
Ne confondez pas les deux lignes. Le principe est prouvé. L'implémentation spécifique qu'en fait le fournisseur est crédible (c'est son intention de conception déclarée) mais non testée par nous sur du matériel réel.
test1_baseline_vulnerable.py — la base sans authentification, en directDémarre un véritable simulateur d'automate EtherNet/IP (cpppo, émulant un Allen-Bradley ControlLogix) et lit + écrit une balise de contrôle avec zéro identifiant. (Périmètre : il s'agit de la large base sans authentification sur laquelle s'appuyait la campagne — pas le mécanisme spécifique de clé codée en dur de CVE-2021-22681. Volontairement distinct ; voir « Trois défaillances différentes » ci-dessus.)
python test1_baseline_vulnerable.py
test2_shared_secret_fails.py — la forme de la faille de clé de flotte (pont narratif, pas un test)Deux points de terminaison détiennent une clé statique ; un identifiant du Dispositif A ouvre le Dispositif B sans modification — l'analogue structurel le plus proche de la faille une-clé-pour-tous de CVE-2021-22681. Mais c'est tautologique : les deux gestionnaires sont construits pour accepter cette clé, il n'existe donc aucun chemin d'exécution où elle peut échouer. Cela ne démontre rien que le code ne définisse pas lui-même. Conservé comme pont narratif du Test 1 au Test 3 ; il n'a aucun poids probant et n'est délibérément pas une étape de preuve.
python test2_shared_secret_fails.py
test3_mutual_tls_fix.py — le correctif, avec son témoin négatif et ses deux sensVraie CA, deux certificats de dispositif individuellement uniques — identité liée dans le SubjectAlternativeName, pas dans le CommonName déprécié. Cinq cas, tous exécutés :
device-a (check_hostname contre un vrai SAN). Mutuel — les deux extrémités lient l'identité.python test3_mutual_tls_fix.py
test4_revocation.py — le volet cycle de vie : la révocationUne CRL réelle signée par la CA. Un identifiant client (engineer-1) est accordé ; puis son numéro de série est ajouté à la CRL, et le même identifiant, toujours valide, non expiré, signé par la CA, est refusé — le contenu empirique de la clause de révocation CR 1.8 / 1.9. L'unicité (Test 3) ≠ la révocabilité ; cela montre qu'un identifiant peut être retiré.
python test4_revocation.py
test4_revocation.py) ; rotation — pas encore. L'unicité par dispositif (Test 3) n'est pas la même chose que la révocabilité ; le Test 4 comble cet écart — un identifiant toujours valide, non expiré, signé par la CA est accordé avant la révocation et refusé après, uniquement parce que la CRL signée par la CA liste désormais son numéro de série. La rotation (réémettre un identifiant de remplacement et retirer l'ancien) est étroitement liée et rendue possible par la même PKI, mais n'est pas démontrée séparément ici — donc « liaison d'identité par dispositif » ne doit pas encore s'étendre silencieusement en « rotation résolue ».presented == KEY, identity in SAN) ne sont pas à temps constant. Non exploitable ici — les valeurs comparées sont des chaînes d'identité quasi publiques et TLS a déjà effectué la véritable authentification cryptographique avant que la comparaison ne s'exécute — mais signalé car le motif est copié dans des endroits où cela compte vraiment.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, honnêtement classés par niveau, chaque lacune nommée ; le volet émission/validation/révocation des CR 1.2, CR 1.9 et CR 1.8 est désormais démontré). Avant le PSIRT ([email protected] / [email protected]) : vérifier le texte normatif de chaque CR par rapport à un exemplaire acheté de l'IEC 62443-4-2:2019.PHASED_ROLLOUT.md (Phase 0 stopper l'hémorragie · 1 segmenter · 2 contrôles compensatoires · 3 CIP Security/PKI, si le matériel le permet · 4 exploiter). Dimensionné pour une petite régie ; honnête sur le fait que CIP Security est conditionné par le matériel, donc les phases 0–2 portent la réduction des risques dans tous les cas.Chaque identifiant externe ici a été extrait d'une source en ligne le 2026-07-31, et non ressorti de mémoire d'entraînement : AA26-097A (multi-source, incl. WaterISAC / Tenable / SecurityWeek), Braham comme l'une des quatre victimes divulguées, CyberAv3ngers/IRGC, PN1550 a confirmé qu'il s'agissait du véritable avis Rockwell, avec sa citation de la ligne 2 vérifiée mot pour mot (« When properly deployed, CIP Security remediates this vulnerability » + « does not make use of any hardcoded keys »), « cannot be mitigated with a patch » mot pour mot, CVSS 10.0 / CRITIQUE (v3.1), numéro de suivi CISA ICSA-21-056-03, et 62443-4-2 CR 1.8 (PKI) + CR 3.1 (intégrité des communications) confirmés exacts.
Discipline pour le dossier : re-récupérer chaque identifiant depuis des sources primaires au moment de la soumission. Les avis sont renumérotés, étendus et remplacés — AA26-097A montre déjà une extension — donc « vérifié le 2026-07-31 » n'est pas « vérifié à la soumission ». La correspondance formelle complète 62443-4-2, CR par CR, est désormais rédigée (62443-4-2_SL2_MAPPING.md) — ce qui reste, c'est de re-récupérer son texte normatif cité par rapport à un exemplaire acheté de la norme avant soumission, pas de rédiger la correspondance elle-même.
l0gic — Patrick Crosby · 2026-07-31.
Journal de durcissement : le Test 3 a été renforcé pour inclure le témoin négatif (cas 4, prouvant la nécessité et pas seulement le déclenchement), le cas en sens inverse (cas 5, liaison mutuelle) et l'identité basée sur le SAN (pas le CN), puis re-vérifié en ré-exécutant les cinq cas ; le Test 4 (révocation par CRL) a été ajouté. Les légendes des Tests 1/2 ont été ajustées pour garder les trois classes de défaillance distinctes ; le Test 2 a été rétrogradé de « test » à pont narratif ; les limites de périmètre sur la révocation et le temps constant ont été ajoutées. La chaîne de citations a été extraite de sources primaires et marquée pour re-récupération à la soumission.
| Affirmation | Niveau de preuve | Pourquoi |
|---|
| Le principe architectural | « un secret partagé unique sur une flotte est compromis sur toute la flotte par une seule fuite ; l'authentification liée à l'identité par dispositif corrige cela » | PROUVÉ | démontré avec du code réel en cours d'exécution, y compris le témoin négatif qui prouve que le contrôle est nécessaire, pas seulement qu'il se déclenche : sur un point de terminaison strict, le certificat du Dispositif B, parfaitement valide pour la CA, est rejeté sur l'identité (Test 3 · cas 3), mais sur un point de terminaison à validité CA uniquement, le même certificat est accepté (cas 4 — le témoin) → « être simplement signé par une CA valide == accès à toute la flotte == Test 2 sous habillage TLS. » La liaison tient aussi en sens inverse : un serveur rogue présentant un certificat de flotte valide est rejeté par le client (cas 5). Le Test 1 montre séparément la base plus large sans authentification. |
| L'implémentation CIP Security spécifique de Rockwell se comporte à l'identique | « l'activation de CIP Security sur du matériel Rockwell réel corrige CVE-2021-22681 exactement de cette manière » | PISTE, sourcée non vérifiée | c'est le langage de l'avis de Rockwell lui-même (PN1550) — "When properly deployed, CIP Security remediates this vulnerability... does not make use of any hardcoded keys" — pas quelque chose que nous avons indépendamment confirmé sur du matériel Logix réel. Nous avons testé le principe que leur avis décrit, pas leur implémentation exacte au niveau filaire. |