Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
cip-security-poc — Концепт-доказательство, воспроизводящее уязвимость жёстко зашитого ключа CVE-2021-22681 и проверяющее исправление на основе взаимного TLS/CRL для каждого устройства поверх симулированного EtherNet/IP, с сопоставлением с IEC 62443-4-2. | Kitploit
Инструменты/GitHubGitHub/pcrosby-1990/cip-security-poc
Анализ уязвимостейБезопасность SCADA/ICSКриптографияРазведка угрозАутентификацияРеагирование на Инциденты
GitHubpcrosby-1990/cip-security-poc

cip-security-poc

Концепт-доказательство, воспроизводящее уязвимость жёстко зашитого ключа CVE-2021-22681 и проверяющее исправление на основе взаимного TLS/CRL для каждого устройства поверх симулированного EtherNet/IP, с сопоставлением с IEC 62443-4-2.

Репозиторий
61 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

cip-security-poc — доказательство принципа исправления CVE-2021-22681 (а не только самой уязвимости)

Шесть исполняемых скриптов — реальный трафик протокола EtherNet/IP (Тест 1), реальная механика TLS/PKI (Тесты 3–6) — без единого компонента Rockwell или лицензий где-либо в цепочке. Создано для проверки утверждения до его оформления, а не для защиты его на веру.

Происхождение: создано 2026-07-31, параллельно с расследованием инцидента на водоочистной станции в Брахаме, штат Миннесота — одной из четырёх объектов коммунального хозяйства, публично раскрытых в скоординированном инциденте в водном секторе Миннесоты 26–27 июля 2026 года. Контекст этого инцидента описан в консультативном бюллетене CISA AA26-097A (совместный FBI/CISA/NSA/EPA/DOE/USCYBERCOM/Mинфин; выпущен 2026-04-07, расширен 2026-07-22), который охватывает продолжающуюся кампанию CyberAv3ngers, связанную с IRGC. Оговорка об атрибуции, сформулированная точно: ни одно ведомство официально не приписывало конкретно инцидент в Миннесоте этой группе — только более широкую продолжающуюся кампанию. Эта папка — сторона технического исправления, намеренно отделённая от расследования инцидента.

Статус вендора (обновлено 2026-08-03)

В Rockwell PSIRT ([email protected]) и RA Secure Mail ([email protected]) обращались 2026-07-31, до публикации этого репозитория и отчёта (~за 30 минут до, по временным меткам файлов). Команда архитектуры безопасности Rockwell изучила репозиторий и ответила 2026-08-03. Цитируется дословно, без перефразирования в более сильное утверждение, чем они сделали:

Rockwell Automation не поддерживает и не подтверждает вашу интерпретацию, ваше сопоставление с IEC 62443-4-2 или любые выводы, сделанные на основе доказательства концепции. Пожалуйста, не представляйте эту работу как проверенную, одобренную или поддержанную Rockwell Automation... скрипты демонстрируют общие криптографические и аутентификационные принципы, а не что-то специфичное для CIP Security или CVE-2021-22681.

Эта работа не была проверена, одобрена или поддержана Rockwell Automation, точка. Их техническая характеристика — общие принципы, а не специфика CIP Security — это то же различие, которое таблица «Жёсткая граница» ниже уже проводит в отношении утверждений этого репозитория; их проверка подтверждает это независимо, а не оспаривает. Для объектов коммунального хозяйства на оборудовании, которое не поддерживает CIP Security, Rockwell указал на собственное Руководство по проектированию и внедрению Converged Plantwide Ethernet (CPwE) (цитируется в PHASED_ROLLOUT.md, Фаза 1) — существующий ресурс вендора, к которому этот проект пытается направлять людей, а не дублировать его.

Эта форма не уникальна для Rockwell

Вывод Теста 1 — отсутствие аутентификации в состоянии по умолчанию протокола — не уникален для EtherNet/IP. Modbus TCP, по-прежнему один из наиболее широко развёрнутых протоколов в системах управления водоснабжением/водоотведением, вообще не имеет концепции аутентификации в спецификации протокола; он восходит к последовательной связи 1979 года и никогда не проектировался с учётом безопасности. CISA неоднократно называла именно этот недостаток в консультативных бюллетенях по ICS (например, серия MELSEC iQ-F от Mitsubishi Electric: «MODBUS/TCP не имеет надлежащей аутентификации», что позволяет несанкционированное чтение/запись/остановку). Собственный ответ Организации Modbus, Modbus/TCP Security, — это инкапсуляция TLS с сертификатами X.509 — структурно та же категория исправления, которую демонстрирует Тест 3, стандартизированная на уровне организации протокола, а не одного вендора. DNP3 имеет опциональное расширение Secure Authentication (SAv5, стандартизировано в 2012 году); независимый анализ и отчёты интеграторов описывают его как редко настраиваемый на практике, ссылаясь на пробелы в совместимости между производителями ОТ и реальную сложность протокола — что оставляет ту же уязвимость, которую Тест 1 демонстрирует для EtherNet/IP.

Архитектурный тезис, сформулированный точно, чтобы не переоценивать его: исправление Теста 3 — взаимный TLS, привязка идентичности каждого устройства в сертификате (не только валидность CA), отзыв через CRL — работает на транспортном уровне, а не на прикладном протоколе ICS. Принцип в равной степени применим под Modbus, DNP3 или проприетарным протоколом; меняется обёртка, а не форма исправления. Этот репозиторий не создавал и не запускал PoC, специфичный для Modbus или DNP3 — это архитектурное обобщение на основе публичной документации, придерживающееся той же иерархии «продемонстрировано vs. подтверждено источниками», что и всё остальное здесь, а не новое проверенное утверждение.

Источники: Консультативные бюллетени CISA ICS о пробелах аутентификации Modbus/TCP — Industrial Cyber · Обзор Modbus/TCP Security — Veridify · Проблемы внедрения DNP3 SAv5/SAv6 — Step Function I/O

Три разных отказа — не смешивайте их

Пакет раскрытия живёт или умирает на том, чтобы не смешивать эти понятия, потому что у каждого своё исправление:

  • Отсутствие / отсутствующая аутентификация (Тест 1) — устройство, доступное без какого-либо уровня учётных данных. Широкая базовая линия, на которую опиралась кампания CyberAv3ngers (многие жертвы были доступны с отсутствующими или стандартными учётными данными).
  • Один жёстко заданный / общий ключ для всего парка (конкретная форма CVE-2021-22681, смоделированная Тестом 2) — извлеките один ключ один раз, подделывайте по всему парку. Это и есть собственно CVE.
  • Стандартные учётные данные — заводские учётные данные никогда не менялись. Здесь не моделируется; названо, чтобы не смешивать с двумя вышеуказанными.

Продемонстрированное здесь исправление — привязка идентичности каждого устройства (Тест 3) — устраняет отказ общего ключа парка.

Жёсткая граница (прочтите это первым)

УтверждениеУровеньПочему
Архитектурный принцип«один общий секрет для всего парка скомпрометирован по всему парку одной утечкой; привязка идентичности к каждому устройству закрывает это»ДОКАЗАНОпродемонстрировано реальным работающим кодом, включая отрицательный контроль, доказывающий, что проверка необходима, а не просто срабатывает: на строгой конечной точке Устройства B действительно валидный сертификат CA отклоняется по идентичности (Тест 3 · случай 3), но на конечной точке, проверяющей только валидность CA, тот же сертификат принимается (случай 4 — контроль) → «только валидная подпись CA == доступ ко всему парку == Тест 2 в обёртке TLS». Привязка также работает в обратную сторону: мошеннический сервер, предъявляющий валидный сертификат парка, отклоняется клиентом (случай 5). Тест 1 отдельно показывает более широкую базовую линию без аутентификации.
Конкретная реализация CIP Security от Rockwell ведёт себя идентично«включение CIP Security на реальном оборудовании Rockwell устраняет CVE-2021-22681 именно таким образом»ГИПОТЕЗА, подтверждена источниками, не проверенаэто формулировка собственного бюллетеня Rockwell (PN1550) — «При правильном развёртывании CIP Security устраняет эту уязвимость... не использует никаких жёстко заданных ключей» — а не то, что мы независимо подтвердили на реальном оборудовании Logix. Мы тестировали принцип, который описывает их бюллетень, а не их точную реализацию на уровне протокола.

Не смешивайте две строки. Принцип доказан. Конкретная реализация вендора правдоподобна (это их собственное заявленное проектное намерение), но не проверена нами на реальном оборудовании.

Инструменты

test1_baseline_vulnerable.py — базовая линия без аутентификации, вживую

Запускает реальный симулятор ПЛК EtherNet/IP (cpppo, эмулирующий Allen-Bradley ControlLogix) и читает + записывает управляющий тег с нулевыми учётными данными. (Область: это широкая базовая линия без аутентификации, на которую опиралась кампания — не конкретный механизм жёстко заданного ключа CVE-2021-22681. Намеренно различается; см. «Три разных отказа» выше.)

root@kitploit:~
python test1_baseline_vulnerable.py

test2_shared_secret_fails.py — форма уязвимости общего ключа парка (нарративный мост, не тест)

Две конечные точки держат один статический ключ; учётные данные от Устройства A открывают Устройство B без изменений — ближайший структурный аналог уязвимости CVE-2021-22681 «один ключ на всех». Но это тавтология: оба обработчика сконструированы так, чтобы принимать этот ключ, поэтому не существует пути выполнения, на котором он может не сработать. Он не демонстрирует ничего, что код не определяет в существование. Сохранён как нарративный мост от Теста 1 к Тесту 3; он не несёт никакого доказательного веса и намеренно не является опорой доказательства.

root@kitploit:~
python test2_shared_secret_fails.py

test3_mutual_tls_fix.py — исправление, с отрицательным контролем и в обоих направлениях

Реальный CA, два индивидуально уникальных сертификата устройств — идентичность привязана в SubjectAlternativeName, а не в устаревшем CommonName. Пять случаев, все выполняются:

  • [1] Собственный сертификат Устройства A → РАЗРЕШЕНО · [2] без сертификата → отклонено на этапе рукопожатия TLS · [3] валидный сертификат CA Устройства B → ОТКАЗАНО по идентичности (строгая конечная точка).
  • [4] КОНТРОЛЬ — тот же сертификат Устройства B против конечной точки, проверяющей только валидность CA → РАЗРЕШЕНО. Именно это придаёт [3] смысл: без проверки идентичности любой сертификат парка открывает любое устройство (== Тест 2, в обёртке TLS).
  • [5] ОБРАТНОЕ — мошеннический сервер, предъявляющий сертификат Устройства B, отклоняется клиентом, который привязывает device-a (check_hostname против реального SAN). Взаимно — обе стороны привязывают идентичность.
root@kitploit:~
python test3_mutual_tls_fix.py

test4_revocation.py — этап жизненного цикла: отзыв

Реальный CRL, подписанный CA. Учётные данные клиента (engineer-1) выдаются; затем их серийный номер добавляется в CRL, и те же всё ещё валидные, не истёкшие, подписанные CA учётные данные отклоняются — эмпирическое содержание пункта об отзыве CR 1.8 / 1.9. Уникальность (Тест 3) ≠ возможность отзыва; это показывает, что учётные данные можно забрать.

root@kitploit:~
python test4_revocation.py

test5_rotation.py — этап жизненного цикла, который Тест 4 не закрыл: ротация

Выдаёт заменяющие учётные данные (v2) для той же идентичности (engineer-1), которая уже имеет валидные (v1). КОНТРОЛЬ (случай 3): v1 предъявляется снова после того, как v2 существует, но до того, как v1 явно выведен из обращения → всё ещё РАЗРЕШЕНО — доказывая, что повторная выдача сама по себе не выводит старые учётные данные. Только после того, как v1 явно добавлен в CRL (случай 4), он отклоняется; v2 не затрагивается на протяжении всего процесса (случай 5) — идентичность никогда не теряет доступ во время перехода. «Выдать замену и вывести из обращения предыдущую» в CR 1.8 — это два действия, и здесь показаны оба, по отдельности.

root@kitploit:~
python test5_rotation.py

test6_tamper_injection.py — этап, который CR 3.1 назвал «по построению»: выделенный тест целостности

Релей на уровне записей находится между реальным клиентом и сервером с взаимным TLS, пересылая записи TLS, разбирая только 5-байтовый заголовок — он никогда не видит открытый текст зашифрованной полезной нагрузки. Контроль: каждый байт пересылается без изменений → сообщение доставляется нетронутым. Вмешательство: один бит перевёрнут внутри шифротекста живой записи Application Data → проверка AEAD принимающего стека TLS не срабатывает (SSLV3_ALERT_BAD_RECORD_MAC), и соединение разрывается — повреждённые данные никогда не доставляются так, как если бы они были валидными. Какой байт и почему это указано: тело записи AEAD TLS 1.2 — explicit_nonce(8) ‖ ciphertext ‖ auth_tag(16), поэтому байт 0 — это nonce, а не полезная нагрузка. Переворот nonce также вызывает сбой проверки AEAD — но из-за искажения расшифровки, а не из-за того, что тег ловит изменённую полезную нагрузку. CR 3.1 касается несанкционированной модификации передаваемой информации, поэтому переворот нацелен на байт в середине шифротекста, и тест затем демонстрирует именно то предложение, которое он утверждает.

root@kitploit:~
python test6_tamper_injection.py

Границы области (что НЕ утверждается)

  • Отзыв и ротация — оба теперь продемонстрированы. Уникальность каждого устройства (Тест 3) — это не то же самое, что возможность отзыва; Тест 4 закрывает этот пробел — всё ещё валидные, не истёкшие, подписанные CA учётные данные выдаются до отзыва и отклоняются после. Тест 5 закрывает оставшийся пробел жизненного цикла, ротацию — повторную выдачу заменяющих учётных данных для той же идентичности и явный вывод из обращения предыдущих, с собственным отрицательным контролем, показывающим, что это два отдельных действия.
  • TLS 1.2 в этих скриптах — АРТЕФАКТ ДЕТЕРМИНИРОВАННОСТИ ТЕСТА, а не рекомендация по развёртыванию. Каждый скрипт фиксирует maximum_version = TLSv1_2 по двум причинам, связанным с наблюдаемостью, а не безопасностью: в TLS 1.2 отсутствующий или отклонённый сертификат клиента завершается сбоем во время рукопожатия, поэтому тест получает детерминированную, атрибутируемую ошибку, а не сбой после рукопожатия, как в TLS 1.3; и тип содержимого записи остаётся видимым в открытом виде, что необходимо реле Теста 6 для идентификации записи Application Data вообще. Развёртывайте самую высокую версию TLS, которую поддерживают ваши устройства — TLS 1.3 там, где доступно. Ничто в этом репозитории не следует читать как совет ограничивать производственную систему версией 1.2.
  • Постоянное время (низкая серьёзность, названо для гигиены). Сравнения строк идентичности (presented == KEY, identity in SAN) не выполняются за постоянное время. Не эксплуатируемо здесь — сравниваемые значения — это публичные строки идентичности, и TLS уже выполнил реальную криптографическую аутентификацию до выполнения сравнения — но отмечено, потому что этот шаблон копируется в места, где это имеет значение.

Установка

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

Следующие шаги (все названные пункты закрыты по состоянию на 2026-08-03 — всё ниже опубликовано, запушено, ничего не удержано)

  • Сопоставление 62443-4-2 SL 2 — ЧЕРНОВИК ГОТОВ → 62443-4-2_SL2_MAPPING.md (CR 1.2 / 1.8 / 1.9 / 1.14 / 3.1, честно распределено по уровням, каждый пробел назван; CR 1.2, CR 1.9 и часть выдачи/проверки/отзыва CR 1.8 теперь продемонстрированы). Перед PSIRT ([email protected] / [email protected]): сверить нормативный текст каждого CR с приобретённой копией IEC 62443-4-2:2019.
  • Поэтапное развёртывание — ЧЕРНОВИК ГОТОВ → PHASED_ROLLOUT.md (Фаза 0 остановка кровотечения · 1 сегментация · 2 компенсирующие меры · 3 CIP Security/PKI, если позволяет оборудование · 4 эксплуатация). Соразмерно для небольшого коммунального предприятия; честно признаёт, что CIP Security ограничен оборудованием, поэтому Фазы 0–2 несут снижение риска в любом случае.
  • Последовательность ответственного раскрытия — ГОТОВО. PSIRT уведомлён 2026-07-31, репозиторий/отчёт опубликованы ~30 минут спустя в тот же день, ответ Rockwell 2026-08-03. Полные детали в разделе «Статус вендора» выше; по этому пункту ничего не осталось открытым.
  • Добавлено 2026-08-03 — превращение советов в артефакты, которые небольшое коммунальное предприятие может реально использовать: PHASE0_INVENTORY_WORKSHEET.md (заполняемая инвентаризация устройств, а не просто инструкция составить её), RESOURCES.md (бесплатная помощь CISA / EPA / WaterISAC / AWWA, проверена вживую, не по памяти), и INCIDENT_RESPONSE_QUICK_REFERENCE.md (карточка на первые 60 минут, явно не полный план реагирования на инциденты — безопасность операций всегда на первом месте в ней).
  • Оба ранее названных технических пункта — ГОТОВО (2026-08-03). test5_rotation.py переводит CR 1.8 из «включено» в полностью продемонстрированный (ротация, с собственным контролем); test6_tamper_injection.py переводит CR 3.1 из «по построению» в продемонстрированный (реальный переворот бита, отклонённый проверкой AEAD TLS). Оба многократно перезапускались без сбоев перед добавлением сюда. Также добавлено: PHASE3_CA_QUICKSTART.md (CA «в несколько строк кода», как реальные проверенные команды openssl) и конкретный пример белого списка в PHASED_ROLLOUT.md, Фаза 1.
  • Само поэтапное развёртывание — ГОТОВО, все пять фаз (0–4). Каждая фаза была проверена и исправлена на внутреннюю согласованность, а не просто написана один раз: найдена и закрыта реальная уязвимость в настройке CA Фазы 3, теперь принято и сформулировано отсутствовавшее решение о поведении CRL при отказе (fail-open/fail-closed), истечение срока сертификата названо тем новым режимом отказа, которым оно является, назван молчаливый эффект Фазы 3 на мониторинг Фазы 2 с предложенными заменами, NTP указан как предварительное требование, и каждый вспомогательный документ (GLOSSARY.md, INTEGRATOR_CHECKLIST.md, PHASE3_CA_QUICKSTART.md) теперь реально связан из плана, а не висит без ссылок. Ничего в этом списке больше не в статусе ЧЕРНОВИК — всё выше и ниже запушено и опубликовано в публичном репозитории.

Цитирования — получены, не по памяти (и повторно извлечь перед подачей)

Каждый внешний идентификатор здесь был извлечён из живого источника 2026-07-31, а не по памяти из обучения: AA26-097A (мультиисточник, включая WaterISAC / Tenable / SecurityWeek), Брахам как одна из четырёх раскрытых жертв, CyberAv3ngers/IRGC, PN1550 подтверждён как реальный бюллетень Rockwell с цитатой для строки 2, проверенной дословно («При правильном развёртывании CIP Security устраняет эту уязвимость»

  • «не использует никаких жёстко заданных ключей»), «не может быть устранено патчем» дословно, CVSS 10.0 / CRITICAL (v3.1), отслеживание CISA ICSA-21-056-03, и 62443-4-2 CR 1.8 (PKI) + CR 3.1 (целостность связи) подтверждены точно. Дисциплина для пакета: повторно извлечь каждый идентификатор из первоисточников в момент подачи. Бюллетени перенумеровываются, расширяются и заменяются — AA26-097A уже показывает одно расширение — поэтому «проверено 2026-07-31» — это не «проверено при подаче». Полное формальное сопоставление 62443-4-2 по каждому CR теперь написано (62443-4-2_SL2_MAPPING.md) — осталось повторно извлечь цитируемый нормативный текст из приобретённой копии стандарта перед подачей, а не писать само сопоставление.

l0gic — Patrick Crosby · 2026-07-31.

Журнал усиления, 2026-08-03: добавлены test5_rotation.py и test6_tamper_injection.py, закрывающие два технических пункта, названных открытыми с 2026-07-31 — каждый перезапущен три раза без сбоев перед описанием здесь. PHASE3_CA_QUICKSTART.md (реальные, проверенные команды openssl), конкретный пример белого списка межсетевого экрана для Фазы 1, PHASE0_INVENTORY_WORKSHEET.md, RESOURCES.md, INCIDENT_RESPONSE_QUICK_REFERENCE.md и обобщение для Modbus/DNP3 также добавлены в тот же день.

Журнал усиления, 2026-08-03 (продолжение) — два независимых прохода проверки, оба применены: группа красной команды по безопасности нашла и исправила реальную уязвимость PKI в кратком руководстве по CA (-copy_extensions copyall позволял вредоносному запросу сертификата самому объявлять CA:TRUE; исправлено через явный -extfile, проверено против намеренно вредоносного запроса в обоих направлениях) и исправила test6, чтобы переворачивать именно шифротекст, а не байт 0 (nonce), плюс реальное исправление потокобезопасности и фиксация зависимостей. Отдельный структурный аудит — чтение фаз как системы во времени, а не чек-листа — нашёл и исправил: заголовок «несколько строк» Фазы 3 скрывал, что отзыв/ротация не просты; решение о поведении CRL при отказе (fail-open/fail-closed) никогда не было принято (теперь принято, с значением по умолчанию и обоснованием); истечение срока сертификата было новым, неназванным режимом отказа (Фаза 4 теперь несёт урок безопасного перекрытия из Теста 5); Фаза 3 молча ослепляет сигнализатор записи Фазы 2 (теперь названо, с предложенными заменами); NTP был неуказанным предварительным требованием; CR 1.14 был сформулирован как «не выполнен», тогда как «не применим к исправленной конструкции» — точная формулировка; и INTEGRATOR_CHECKLIST.md/GLOSSARY.md были осиротевшими документами, на которые ничто не ссылалось (теперь связаны из Фазы 3 и начала этого плана). Каждое исправление проверено повторным запуском затронутых тестов, а не только перечитыванием диффа. Запушено и опубликовано — все пять фаз плана развёртывания готовы, проверены дважды, и ничего из сегодняшнего больше не осталось локально.

Журнал усиления: Тест 3 был усилен, чтобы включить отрицательный контроль (случай 4, доказывающий необходимость, а не просто срабатывание), случай обратного направления (случай 5, взаимная привязка) и идентичность на основе SAN (не CN), затем повторно проверен повторным запуском всех пяти случаев; добавлен Тест 4 (отзыв через CRL). Подписи Тестов 1/2 были соразмерно скорректированы, чтобы держать три класса отказов различными; Тест 2 понижен с «теста» до нарративного моста; добавлены границы области для отзыва и постоянного времени. Цепочка цитирований была извлечена из первоисточников и помечена для повторного извлечения при подаче.

Скачать инструмент