Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
cip-security-poc — 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. | Kitploit
Outils/GitHubGitHub/pcrosby-1990/cip-security-poc
Analyse des VulnérabilitésSécurité SCADA/ICSCryptographieRenseignement sur les MenacesAuthentificationRéponse aux Incidents
GitHubpcrosby-1990/cip-security-poc

cip-security-poc

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.

Voir le dépôt
7il y a 1 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

cip-security-poc — prouver le principe de correction derrière CVE-2021-22681 (pas seulement sa faille)

Six scripts exécutables — trafic réel du protocole EtherNet/IP (Test 1), mécanismes réels TLS/PKI (Tests 3–6) — zéro logiciel ou licence Rockwell dans toute la chaîne. Conçus pour tester une affirmation avant de la rédiger, pas pour la défendre par simple conviction.

Provenance : construit le 2026-07-31, en parallèle d'une enquête sur la station de traitement des eaux usées 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 figure dans l'avis CISA AA26-097A (conjoint FBI/CISA/NSA/EPA/DOE/USCYBERCOM/Treasury ; publié le 2026-04-07, étendu le 2026-07-22), qui couvre la campagne en cours CyberAv3ngers affiliée à l'IRGC. Réserve d'attribution, tenue avec précision : aucune agence n'a formellement attribué l'incident du Minnesota spécifiquement à ce groupe — seule la campagne plus large en cours l'est. Ce dossier est le volet technique de la correction, volontairement séparé de l'enquête sur l'incident.

Statut du fournisseur (mis à jour le 2026-08-03)

Rockwell PSIRT ([email protected]) et RA Secure Mail ([email protected]) ont été contactés le 2026-07-31, avant la mise en ligne de ce dépôt et de cette analyse (~30 minutes avant, selon les horodatages des fichiers). L'équipe d'architecture de sécurité de Rockwell a examiné le dépôt et a répondu le 2026-08-03. Citation directe, non reformulée en une affirmation plus forte que la leur :

Rockwell Automation n'approuve ni ne valide votre interprétation, votre correspondance avec l'IEC 62443-4-2, ni aucune conclusion tirée de la preuve de concept. Veuillez ne pas présenter ce travail comme ayant été examiné, approuvé ou cautionné par Rockwell Automation... les scripts démontrent des principes généraux de cryptographie et d'authentification plutôt que quoi que ce soit de spécifique à CIP Security ou à CVE-2021-22681.

Ce travail n'a pas été examiné, approuvé ni cautionné par Rockwell Automation, point final. Leur caractérisation technique — principes généraux, pas spécifiques à CIP Security — est la même distinction que le tableau « La frontière stricte » ci-dessous établit déjà concernant les affirmations de ce dépôt ; leur examen la confirme indépendamment plutôt que de la contester. Pour les installations sur du matériel qui ne peut pas atteindre CIP Security, Rockwell a renvoyé vers son propre guide de conception et de mise en œuvre Converged Plantwide Ethernet (CPwE) (cité dans PHASED_ROLLOUT.md Phase 1) — la ressource fournisseur existante vers laquelle ce projet tente d'orienter les gens plutôt que de la dupliquer.

Cette forme n'est pas spécifique à Rockwell

La conclusion du Test 1 — aucune authentification dans l'état par défaut du protocole — n'est pas propre à EtherNet/IP. Modbus TCP, toujours l'un des protocoles les plus déployés dans les systèmes de contrôle de l'eau et des eaux usées, ne comporte aucune notion d'authentification dans la spécification du protocole ; il date des communications série de 1979 et n'a jamais été conçu avec la sécurité à l'esprit. La CISA a régulièrement cité exactement cette défaillance dans ses avis ICS (par ex. la série MELSEC iQ-F de Mitsubishi Electric : « MODBUS/TCP manque d'authentification appropriée », permettant des lectures/écritures/ arrêts non autorisés). La réponse propre de la Modbus Organization, Modbus/TCP Security, est une encapsulation TLS avec certificats X.509 — structurellement la même catégorie de correction que le Test 3 démontre ici, normalisée au niveau de l'organisation du protocole plutôt que chez un seul fournisseur. DNP3 dispose d'une extension optionnelle Secure Authentication (SAv5, normalisée en 2012) ; des analyses indépendantes et des témoignages d'intégrateurs décrivent tous deux qu'elle est rarement configurée en pratique, citant des écarts d'interopérabilité entre fabricants d'OT et une complexité protocolaire réelle — laissant la même exposition que le Test 1 démontre pour EtherNet/IP.

Le point architectural, énoncé avec précision pour ne pas être survendu : la correction du Test 3 — TLS mutuel, identité par périphérique liée dans le certificat (pas seulement la validité de l'AC), révocation via CRL — opère au niveau de la couche transport, pas au niveau du protocole applicatif ICS. Le principe est également applicable sous Modbus, DNP3 ou un protocole propriétaire ; ce qui change, c'est l'emballage, pas la forme de la correction. Ce dépôt n'a pas construit ni exécuté de PoC spécifique Modbus ou DNP3 — il s'agit d'une généralisation architecturale à partir de documentation publique, soumise au même classement « démontré vs sourcé » que tout le reste ici, pas d'une nouvelle affirmation testée.

Sources : Avis ICS de la CISA sur les lacunes d'authentification Modbus/TCP — Industrial Cyber · Vue d'ensemble de Modbus/TCP Security — Veridify · Défis d'adoption DNP3 SAv5/SAv6 — Step Function I/O

Trois défaillances différentes — à garder distinctes

Un dossier de divulgation se joue ou se perd sur le fait de ne pas mélanger ces éléments, car chacun a une correction différente :

  • Absence / pas d'authentification (Test 1) — un équipement exposé sans aucune couche d'identifiants. La base large sur laquelle s'appuyait la campagne CyberAv3ngers (de nombreuses victimes étaient joignables avec des identifiants absents ou par défaut).
  • Une clé codée en dur / partagée sur tout un parc (la forme spécifique de CVE-2021-22681, modélisée par le Test 2) — extraire l'unique clé une fois, forger à l'échelle du parc. C'est la véritable CVE.
  • Identifiants par défaut — identifiants d'usine jamais modifiés. Non modélisés ici ; nommés pour ne pas être confondus avec les deux précédents.

La correction démontrée ici — liaison d'identité par périphérique (Test 3) — répond à la défaillance de la clé de parc.

La frontière stricte (à lire en premier)

AffirmationNiveauPourquoi
Le principe architectural« un secret unique partagé sur un parc est compromis à l'échelle du parc par une seule fuite ; une authentification liée à l'identité par périphérique comble cette faille »PROUVÉdémontré avec du code réellement exécuté y compris le contrôle 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 réellement valide CA du périphérique B 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 contrôle) → « une signature CA valide seule == accès à l'échelle du parc == Test 2 en habit TLS ». La liaison tient aussi dans le sens inverse : un serveur rogue présentant un certificat de parc valide est rejeté par le client (cas 5). Le Test 1 montre séparément la base plus large sans authentification.
L'implémentation spécifique de CIP Security chez Rockwell se comporte à l'identique« activer CIP Security sur du matériel Rockwell réel corrige CVE-2021-22681 exactement de cette façon »PISTE, sourcée non vérifiéec'est le langage de l'avis propre de Rockwell (PN1550) — « Lorsqu'il est correctement déployé, CIP Security corrige cette vulnérabilité... n'utilise aucune clé codée en dur » — pas quelque chose que nous avons confirmé indépendamment contre du matériel Logix réel. Nous avons testé le principe que leur avis décrit, pas leur implémentation exacte au niveau du câble.

Ne confondez pas les deux lignes. Le principe est prouvé. L'implémentation spécifique du fournisseur est crédible (c'est leur intention de conception déclarée) mais non testée par nous contre du matériel réel.

Outils

test1_baseline_vulnerable.py — la base sans authentification, en direct

Lance un véritable simulateur PLC EtherNet/IP (cpppo, émulant un Allen-Bradley ControlLogix) et lit + écrit une balise de contrôle avec zéro identifiant. (Portée : il s'agit de la base large sans authentification sur laquelle s'appuyait la campagne — pas le mécanisme spécifique de clé codée en dur de CVE-2021-22681. Gardée distincte volontairement ; voir « Trois défaillances différentes » ci-dessus.)

root@kitploit:~
python test1_baseline_vulnerable.py

test2_shared_secret_fails.py — la forme de la faille de clé de parc (pont narratif, pas un test)

Deux points de terminaison détiennent une clé statique ; un identifiant du périphérique A ouvre le périphérique 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é, donc il n'existe aucun chemin d'exécution où elle peut échouer. Il ne démontre rien que le code ne définisse pas par lui-même. Conservé comme pont narratif du Test 1 au Test 3 ; il ne porte aucun poids probatoire et n'est délibérément pas une jambe de preuve.

root@kitploit:~
python test2_shared_secret_fails.py

test3_mutual_tls_fix.py — la correction, avec son contrôle négatif et ses deux directions

Vraie AC, deux certificats de périphérique individuellement uniques — identité liée dans le SubjectAlternativeName, pas dans le CommonName obsolète. Cinq cas, tous exécutés :

  • [1] Certificat propre du périphérique A → ACCORDÉ · [2] pas de certificat → rejeté à la poignée de main TLS · [3] Certificat valide CA du périphérique B → REFUSÉ sur l'identité (point de terminaison strict).
  • [4] LE CONTRÔLE — le même certificat du périphérique B contre un point de terminaison à validité CA uniquement → ACCORDÉ. C'est ce qui donne son sens à [3] : sans le contrôle d'identité, tout certificat de parc ouvre tout périphérique (== Test 2, en habit TLS).
  • [5] INVERSE — un serveur rogue présentant le certificat du périphérique B est rejeté par un client qui lie device-a (check_hostname contre un vrai SAN). Mutuel — les deux extrémités lient l'identité.
root@kitploit:~
python test3_mutual_tls_fix.py

test4_revocation.py — la jambe du cycle de vie : la révocation

Une vraie CRL signée 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é 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é.

root@kitploit:~
python test4_revocation.py

test5_rotation.py — la jambe du cycle de vie que le Test 4 n'a pas fermée : la rotation

Émet un identifiant de remplacement (v2) pour la même identité (engineer-1) détenant déjà un identifiant valide (v1). LE CONTRÔLE (cas 3) : v1 est présenté à nouveau après l'existence de v2 mais avant le retrait explicite de v1 → toujours ACCORDÉ — prouvant que la seule réémission ne retire pas l'ancien identifiant. Ce n'est qu'après l'ajout explicite de v1 à la CRL (cas 4) qu'il est refusé ; v2 n'est pas affecté tout au long (cas 5) — l'identité ne perd jamais l'accès pendant la transition. Le « émettre un remplacement et retirer le précédent » de CR 1.8 est deux actions, et cela montre les deux, séparément.

root@kitploit:~
python test5_rotation.py

test6_tamper_injection.py — la jambe que CR 3.1 n'a nommée que « par construction » : un test d'intégrité dédié

Un relais au niveau des enregistrements se place entre un vrai client et un vrai serveur TLS mutuel, transférant les enregistrements TLS en analysant uniquement l'en-tête de 5 octets — il ne voit jamais le texte clair de la charge utile chiffrée. Contrôle : chaque octet transféré sans modification → message délivré intact. Altération : un bit inversé dans le texte chiffré d'un enregistrement Application Data en direct → le contrôle AEAD de la pile TLS réceptrice échoue (SSLV3_ALERT_BAD_RECORD_MAC) et la connexion est déchirée — des données corrompues ne sont jamais délivrées comme si elles étaient valides. Quel octet, et pourquoi il est spécifié : un corps d'enregistrement AEAD TLS 1.2 est explicit_nonce(8) ‖ ciphertext ‖ auth_tag(16), donc l'octet 0 est le nonce, pas la charge utile. Inverser le nonce déclenche aussi le contrôle AEAD — mais en brouillant le déchiffrement plutôt qu'en faisant attraper par la balise une charge utile altérée. CR 3.1 concerne la modification non autorisée des informations transmises, donc l'inversion cible un octet au milieu du texte chiffré, et le test démontre alors exactement la phrase qu'il revendique.

root@kitploit:~
python test6_tamper_injection.py

Limites de portée (ce qui n'est PAS revendiqué)

  • Révocation et rotation — toutes deux désormais démontrées. L'unicité par périphérique (Test 3) n'est pas la même chose que la révocabilité ; le Test 4 comble cette lacune — un identifiant toujours valide, non expiré, signé CA est accordé avant la révocation et refusé après. Le Test 5 comble la lacune restante du cycle de vie, la rotation — réémettre un identifiant de remplacement pour la même identité et retirer explicitement le précédent, avec son propre contrôle négatif montrant que les deux sont des actions séparées.
  • TLS 1.2 dans ces scripts est un ARTEFACT DE DÉTERMINISME DE TEST, pas une recommandation de déploiement. Chaque script fixe maximum_version = TLSv1_2 pour deux raisons qui concernent l'observabilité, pas la sécurité : sous TLS 1.2, un certificat client manquant ou rejeté échoue pendant la poignée de main, donc le test obtient une erreur déterministe et attribuable plutôt que l'échec post-poignée de main de TLS 1.3 ; et le type de contenu de l'enregistrement reste visible en clair, ce dont le relais du Test 6 a besoin pour identifier un enregistrement Application Data. Déployez la version TLS la plus élevée que vos périphériques supportent — TLS 1.3 là où c'est disponible. Rien dans ce dépôt ne doit être lu comme un conseil de plafonner un système de production à 1.2.
  • Temps constant (gravité faible, nommé pour l'hygiène). Les comparaisons de chaînes d'identité (presented == KEY, identity in SAN) ne sont pas à temps constant. Non exploitables 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ées parce que le motif est copié dans des endroits où cela compte.

Installation

root@kitploit:~
python -m venv venv
venv\Scripts\activate        # ou : source venv/bin/activate
pip install -r requirements.txt

Prochaines étapes (tous les éléments nommés clos au 2026-08-03 — tout ce qui suit est en ligne, poussé, rien n'est retenu)

  • Correspondance 62443-4-2 SL 2 — RÉDIGÉE → 62443-4-2_SL2_MAPPING.md (CR 1.2 / 1.8 / 1.9 / 1.14 / 3.1, honnêtement classée, chaque lacune nommée ; CR 1.2, CR 1.9 et la jambe émission/validation/révocation de CR 1.8 sont désormais démontrées). Avant PSIRT ([email protected] / [email protected]) : vérifier le texte normatif de chaque CR contre un exemplaire acheté de l'IEC 62443-4-2:2019.
  • Déploiement par phases — RÉDIGÉ → PHASED_ROLLOUT.md (Phase 0 stopper l'hémorragie · 1 segmenter · 2 contrôles compensateurs · 3 CIP Security/PKI, selon le matériel · 4 exploiter). Dimensionné pour une petite installation ; honnête sur le fait que CIP Security est limité par le matériel, donc les Phases 0–2 portent la réduction des risques dans tous les cas.
  • Séquencement de la divulgation responsable — FAIT. PSIRT contacté le 2026-07-31, dépôt/analyse en ligne ~30 minutes plus tard le même jour, réponse de Rockwell le 2026-08-03. Détail complet dans « Statut du fournisseur » ci-dessus ; rien d'ouvert sur cet élément.
  • Ajouté le 2026-08-03 — transformer les conseils en artefacts qu'une petite installation peut réellement utiliser : PHASE0_INVENTORY_WORKSHEET.md (un inventaire de périphériques à remplir, pas seulement l'instruction d'en faire un), RESOURCES.md (assistance gratuite CISA / EPA / WaterISAC / AWWA, vérifiée en direct, non reconstituée de mémoire), et INCIDENT_RESPONSE_QUICK_REFERENCE.md (une fiche des 60 premières minutes, explicitement pas un plan complet de réponse aux incidents — la sécurité des opérations y prime toujours).
  • Les deux éléments techniques précédemment nommés — FAITS (2026-08-03). test5_rotation.py fait passer CR 1.8 de « activé » à pleinement démontré (rotation, avec son propre contrôle) ; test6_tamper_injection.py fait passer CR 3.1 de « par construction » à démontré (une vraie inversion de bit, rejetée par le contrôle AEAD de TLS). Les deux ont été réexécutés à plusieurs reprises sans aucune instabilité avant d'être ajoutés ici. Également ajoutés : PHASE3_CA_QUICKSTART.md (l'AC « en quelques lignes de code », sous forme de vraies commandes openssl testées) et un exemple concret de liste blanche dans PHASED_ROLLOUT.md Phase 1.
  • Le déploiement par phases lui-même — FAIT, les cinq phases (0–4). Chaque phase a été relue et corrigée pour la cohérence interne, pas seulement rédigée une fois : une vraie vulnérabilité trouvée et fermée dans la configuration AC de la Phase 3, la décision CRL fail-open/fail-closed qui manquait est désormais prise et énoncée, l'expiration des certificats est nommée comme le nouveau mode de panne qu'elle est, l'effet silencieux de la Phase 3 sur la surveillance de la Phase 2 est nommé avec des remplacements, NTP est listé comme prérequis, et chaque document de support (GLOSSARY.md, INTEGRATOR_CHECKLIST.md, PHASE3_CA_QUICKSTART.md) est désormais réellement lié depuis le plan au lieu de rester sans référence. Rien sur cette liste n'est encore en BROUILLON — tout ce qui précède et suit est poussé et en ligne sur le dépôt public.

Citations — récupérées, pas reconstituées de mémoire (et à re-récupérer avant soumission)

Chaque identifiant externe ici a été extrait d'une source en direct le 2026-07-31, pas reconstitué de mémoire depuis l'entraînement : AA26-097A (multi-sources, y compris WaterISAC / Tenable / SecurityWeek), Braham comme l'une des quatre victimes divulguées, CyberAv3ngers/IRGC, PN1550 confirmé comme le véritable avis Rockwell avec sa citation de la ligne 2 vérifiée mot pour mot (« Lorsqu'il est correctement déployé, CIP Security corrige cette vulnérabilité » + « n'utilise aucune clé codée en dur »), « ne peut pas être corrigé par un correctif » mot pour mot, CVSS 10.0 / CRITIQUE (v3.1), 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 auprès 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 CR par CR 62443-4-2 est désormais rédigée (62443-4-2_SL2_MAPPING.md) — ce qui reste est de re-récupérer son texte normatif cité contre un exemplaire acheté de la norme avant soumission, pas de rédiger la correspondance.


l0gic — Patrick Crosby · 2026-07-31.

Journal de durcissement, 2026-08-03 : test5_rotation.py et test6_tamper_injection.py ajoutés, fermant les deux éléments techniques nommés ouverts depuis le 2026-07-31 — chacun réexécuté trois fois sans aucune instabilité avant d'être documenté ici. PHASE3_CA_QUICKSTART.md (de vraies commandes openssl testées), un exemple concret de liste blanche de pare-feu pour la Phase 1, PHASE0_INVENTORY_WORKSHEET.md, RESOURCES.md, INCIDENT_RESPONSE_QUICK_REFERENCE.md et la généralisation Modbus/DNP3 ont également été ajoutés le même jour.

Journal de durcissement, 2026-08-03 (suite) — deux passes de relecture indépendantes, toutes deux appliquées : une équipe rouge de sécurité a trouvé et corrigé une vraie vulnérabilité PKI dans le démarrage rapide AC (-copy_extensions copyall permettait à une demande de certificat malveillante de s'auto-déclarer CA:TRUE ; corrigé via un -extfile explicite, vérifié contre une demande délibérément malveillante dans les deux sens) et a corrigé le test6 pour inverser le texte chiffré spécifiquement plutôt que l'octet 0 (le nonce), plus une vraie correction de sécurité des threads et l'épinglage des dépendances. Un audit structurel séparé — lisant les phases comme un système dans le temps, pas comme une liste de contrôle — a trouvé et corrigé : le titre « quelques lignes » de la Phase 3 masquait que la révocation/rotation ne sont pas simples ; le fail-open/fail-closed de la CRL n'avait jamais été décidé (il l'est désormais, avec une valeur par défaut et un raisonnement) ; l'expiration des certificats était un nouveau mode de panne non nommé (la Phase 4 porte désormais la propre leçon de chevauchement sûr du Test 5) ; la Phase 3 aveugle silencieusement l'alerteur d'écriture de la Phase 2 (désormais nommé, avec des remplacements suggérés) ; NTP était un prérequis non énoncé ; CR 1.14 était formulé comme « non satisfait » là où « non applicable à la conception corrigée » est la formulation exacte ; et INTEGRATOR_CHECKLIST.md/GLOSSARY.md étaient des documents orphelins auxquels rien ne renvoyait (désormais liés depuis la Phase 3 et le haut de ce plan). Chaque correction vérifiée en réexécutant les tests concernés, pas seulement en relisant le diff. Poussé et en ligne — les cinq phases du plan de déploiement sont terminées, relues deux fois, et rien d'aujourd'hui ne reste en local.

Journal de durcissement : le Test 3 a été renforcé pour inclure le contrôle négatif (cas 4, prouvant la nécessité et pas seulement le déclenchement), le cas en direction inverse (cas 5, liaison mutuelle), et l'identité basée sur SAN (pas CN), puis re-vérifié en réexécutant les cinq cas ; le Test 4 (révocation CRL) a été ajouté. Les légendes des Tests 1/2 ont été redimensionnées pour garder les trois classes de défaillance distinctes ; le Test 2 a été rétrogradé de « test » à pont narratif ; les limites de portée sur la révocation et le temps constant ont été ajoutées. La chaîne de citations a été récupérée auprès des sources primaires et horodatée pour une re-récupération à la soumission.

Télécharger l’outil