Разработка аппаратного импланта: перехват управления контактором с мониторингом состояния ПЛК
Обзор серии
Эта статья – часть серии. Ниже приведены ссылки на все статьи серии:- Концепция аппаратного MitM: скрытый перехват управления на физическом уровне
- Обход систем мониторинга внешних устройств (EDM) реле безопасности
- Подмена энергетической сигнатуры: расчет балластной нагрузки (dummy load) для обмана ПЛК
- Архитектура Fail-to-Wire: использование SPDT-реле для защиты от обнаружения при отказах
- Безопасное чтение промышленных сигналов (24 В) микроконтроллером (3.3 В) через оптопару
- Построение внеполосного (OOB) канала управления через LoRa в условиях городской застройки
- Особенности монтажа мощных керамических резисторов на прототипах
- Проектирование узла радиоуправления на базе ESP32 с Web UI по Wi-Fi
- Асинхронная логика работы импланта: перехват управления без разрыва связи с ПЛК
Введение. Аппаратные импланты
В одной из предыдущих статей мы спроектировали и собрали промышленный узел управления для исследования кибератак на АСУ ТП. Настало время переходить к сценариям тестирования на проникновение, а также разработке систем защиты промышленных объектов.
Данная статья посвящена разработке прототипа физического импланта, который внедряется непосредственно в цепь управления стенда для скрытого перехвата контроля над контактором. В одной из следующих статей мы обсудим систему защиты от таких атак.
Такой класс атаки называется MiTM (Man-in-the-Middle), но реализуемый на физическом уровне.
Традиционный подход к взлому промышленных систем обычно фокусируется на сетевом и прикладном уровнях. Однако с каждым годом программный взлом контроллеров ПЛК становится сложнее.
Производители закрывают уязвимости в прошивках, внедряют криптографическую защиту блоков логики, а архитекторы безопасности жестко изолируют технологические сети (OT) от корпоративных (IT).
Оказавшись на территории охраняемого объекта, атакующая сторона (Red Team) сталкивается с реалиями промышленной среды:
Сетевой мониторинг
Современные системы обнаружения вторжений IDS, контроль подключаемых устройств по MAC-адресам, механизмы сетевого доступа на базе 802.1X и системы выявления аномалий значительно осложняют сетевые атаки, а также подключение постороннего оборудования к сети предприятия.
Визуальный контроль
Скрытая прокладка отдельного физического кабеля управления от шкафа автоматики до безопасной точки за пределами цеха приведет к тому, что посторонняя линия будет обнаружена инженерами при плановом обходе.
Решением становится аппаратный имплант, позволяющий осуществлять внешнее управление системой через воздушный зазор (air gap).
Для передачи команд используется радиоканал, а вместо взаимодействия с сетевым трафиком имплант воздействует на физический уровень системы, напрямую управляя электрическими сигналами в контролируемой цепи.
Целевая архитектура и EDM
Задачу передачи сигнала на расстояние в ~70-100 метров через железобетонные перекрытия в условиях отсутствия прямой видимости (NLOS) мы решили в одной из предыдущих статей: практическая реализация NLOS-радиолинии на LoRa 433 МГц.
Мы выяснили, что для таких целей отлично подходит технология LoRa – метод радиомодуляции, обеспечивающий высокую помехоустойчивость и дальность при минимальном энергопотреблении.
Теперь, когда у нас есть надежный внеполосный канал связи, перейдем к анализу самой цели. В качестве цели атаки выступает наш лабораторный стенд АСУ ТП, построенный в одной из предыдущих статей, архитектура которого типична для многих промышленных установок:
- Управляющий контроллер: ПЛК Siemens S7-1200.
- Исполнительный механизм: контактор Sirius, коммутирующий силовую нагрузку (условный двигатель или насос).
- Подсистема безопасности: промышленное реле безопасности Omron G9SA.
В штатном режиме ПЛК подает управляющий сигнал (напряжение 24 В постоянного тока), который проходит через реле безопасности и запитывает катушку контактора. Контактор замыкает силовую цепь, и установка начинает работу.
На первый взгляд, задача аппаратной MitM-атаки кажется тривиальной: достаточно разрезать управляющий кабель и вставить в разрыв свое реле, чтобы включать или отключать контактор по желанию.
Однако в современной промышленной среде существует несколько эшелонов аппаратной защиты, которые необходимо учитывать при проектировании импланта:
Диагностика целостности линии и потребления
Промышленные ПЛК (например, модули Siemens High Feature) и интеллектуальные системы распределения питания непрерывно измеряют ток на выходных каналах. Нормальное потребление катушки контактора составляет строго определенную величину – например, 70 мА.
Если атакующий просто перережет провод, ток упадет до нуля (или до микроампер тока утечки). Автоматика мгновенно зафиксирует обрыв линии, переведет установку в безопасное состояние и отправит сигнал тревоги на пульт оператора SCADA.
С другой стороны, если подключить имплант параллельно катушке без правильного расчета и дополнительной логики управления, ток превысит норму, что также вызовет срабатывание защиты от перегрузки.
Мониторинг внешних устройств (EDM)
Реле безопасности (такие как Omron G9SA, которая установлена в нашем лабораторном стенде АСУ ТП) используют функцию External Device Monitoring для контроля состояния исполнительных механизмов.
Контакторы часто оснащаются вспомогательными контактами (Auxiliary contacts), которые физически связаны с главными силовыми контактами контактора.
Если ПЛК выдал команду на запуск, а по цепи обратной связи не пришло подтверждение о фактическом механическом замыкании контактора, система расценит это как отказ оборудования или саботаж.
Дублирование каналов (Dual-Channel Safety)
В системах с еще более высоким классом безопасности (например, SIL 3 / PLe) применяются дублирующие цепи. Устанавливаются два контактора последовательно, и каждый контролируется своим независимым каналом реле безопасности.
Чтобы атаковать такую систему, имплант должен быть многоканальным и осуществлять перехват обеих линий абсолютно синхронно, иначе реле зафиксирует рассогласование каналов.
Промышленный узел с мониторингом внешних устройств будет выглядеть следующим образом:
Таким образом, перед нами стоит нетривиальная инженерная задача. В рамках исследовательского сценария, имитирующего действия Red Team, наш аппаратный имплант обязан имитировать токовую нагрузку катушки и обеспечивать корректную работу цепей обратной связи.
В этом случае система защиты и операторы мониторинга будут видеть штатную работу установки, в то время как реальный физический процесс будет находиться под нашим контролем.
Аппаратная инженерия и логика работы
Архитектура системы будет состоять из аппаратного импланта и вынесенного за пределы объекта узла радиоуправления.
Оператор взаимодействует с внешним управляющим узлом по локальной сети Wi-Fi через Web UI. Управляющий узел формирует команды и передаёт их аппаратному импланту по радиоканалу.
В качестве основы импланта выступает микроконтроллер Raspberry Pi Pico 2W. Он обладает достаточной вычислительной мощностью, поддерживает интерфейс SPI для связи с радиомодулем LoRa (SX1278) и имеет низкое энергопотребление.

Узел управления будет построен на базе микроконтроллера ESP32-WROOM-32.

К каждому из устройств будет подключен радио-трансивер LoRa Ra-02 433 МГц на базе чипа SX1278:

Логика работы импланта
Играть роль “куска провода” в выключенном / неактивном состоянии;
Следить за управляющим сигналом ПЛК;
Если ПЛК выдает “1” – начать прием команд по радиолинии;
При получении радиокоманды на отключение контактора не разрывать цепь, а пустить сигнал ПЛК через эквивалентную нагрузку, имитирующую катушку контактора. Это позволяет сохранить исходную сигнатуру потребления тока и избежать срабатывания защиты от обрыва цепи.
При получении радиокоманды на включение контактора переключить управляющий сигнал ПЛК обратно на оригинальную линию и восстановить цепь обратной связи, возвращая систему в штатный режим работы.
При отключении управляющего сигнала с ПЛК – вернуться в неактивное состояние (“кусок провода”).
Логика обоих микроконтроллеров работает при напряжении 3.3 В, тогда как промышленное оборудование (в нашем случае ПЛК Siemens) использует сигналы с уровнем 24 В постоянного тока. Однако даже при совпадении уровней напряжения гальваническая развязка остаётся необходимой.
Промышленные цепи являются источником помех, коммутационных выбросов и других нежелательных воздействий, поэтому их прямое подключение к чувствительной электронике микроконтроллера – плохая инженерная практика.
Архитектура импланта строится на четырех ключевых узлах:
1. Гальваническая развязка и перехват сигнала ПЛК
Для безопасного чтения команд от ПЛК используется оптопара. Мы будем использовать модуль на базе оптопары TLP281.

В одной из предыдущих статей мы уже говорили про необходимость гальванической развязки, а также обсуждали принцип работы оптопары.
Светодиод оптопары через токоограничивающий резистор (4.7 кОм) подключается параллельно выходу ПЛК. Когда ПЛК подает 24 В на включение контактора, светодиод загорается и открывает фототранзистор на стороне импланта.
Почему номинал резистора именно 4.7 кОм? Для светодиода оптопары TLP281 ток в 5 мА – достаточный уровень для обнаружения логического уровня. На входе у нас 24 В: $$ R = \frac{V}{I} = \frac{24 \text{ В}}{0.005 \text{ мА}} = 4800 \text{ Ом} $$
Ближайший стандартный номинал – 4.7 кОм.
Таким образом, Raspberry Pi Pico безопасно(*) получает логический сигнал (0 или 1) о текущем состоянии промышленного процесса.
Примечание: это не идеальный случай, так как при общем GND формируется земляная петля (ground loop), о которой мы говорили в предыдущей статье. В таком случае оптопара будет защищать только сигнальную линию.
Для полной гальванической изоляции между группами контактов оптопары не должно быть ни одного общего провода. Это решается установкой изолирующего понижающего преобразователя вместо обычного.
2. Архитектура Fail-to-Wire и отказобезопасность
При проектировании аппаратной закладки важно предусмотреть сценарий выхода импланта из строя. Зависание микроконтроллера и потеря питания не должны приводить к нарушению работы атакуемой системы, иначе устройство будет обнаружено ремонтной бригадой.
Для решения этой задачи управление перехватом реализуется через электромагнитное реле с перекидным контактом – SPDT (Single Pole Double Throw).
У SPDT-реле три контакта на выходной (силовой) стороне:
| Контакт | Название | Что делает |
|---|---|---|
| COM | Common (общий) | Центральный подвижный контакт |
| NO | Normally Open | Нормально разомкнутый (открыт при обесточенном реле) |
| NC | Normally Closed | Нормально замкнутый (замкнут при обесточенном реле) |
Когда на катушку реле не подаётся напряжение:
- COM соединён с NC
Когда на катушку подаётся напряжение (реле срабатывает):
- COM переключается на NO, а NC размыкается.
Управляющий провод 24 В, идущий к катушке контактора, разрезается, и оба конца подключаются к контактам реле: COM (Общий) и NC (Нормально закрытый).
В обесточенном состоянии (или при штатной работе) реле замкнуто. Имплант действует как обычный кусок провода. Физическая цепь между ПЛК и контактором не нарушена.
Нам понадобится двухканальное реле – один канал для управления питанием катушки, второй для управления цепью обратной связи. Двухканальное реле, поддерживающее управляющий сигнал 24 В DC:

3. Подмена энергетической сигнатуры
Когда имплант получает по радиоканалу команду на атаку (MitM), реле переключается с контакта NC на контакт NO (нормально открытый). Связь с контактором физически разрывается, и исполнительный механизм отключается.
Здесь возникает проблема мониторинга линии, о которой мы говорили ранее. Ток в цепи ПЛК не должен упасть до нуля. Для этого к контакту NO мы подключаем специально рассчитанную балластную нагрузку – мощный керамический резистор.
Сопротивление этого резистора необходимо рассчитать так, чтобы он потреблял ровно столько же тока, сколько потребляет реальная катушка контактора.
В момент перехвата управления (щелчка реле) ток мгновенно перенаправляется с реального контактора на наш dummy load. Система защиты ПЛК не замечает подмены: напряжение есть, ток соответствует эталонному значению.
Проводим замер потребления тока катушкой контактора:
- Обесточиваем стенд;
- Переключаем мультиметр в режим “10A”, а красный щуп переставляем в одноименное гнездо “10A”;
- Отключаем провод, который заходит в гнездо “A1+” контактора Siemens Sirius;
- Черный щуп мультиметра вставляем в освободившееся гнездо;
- Надеваем клемму-“крокодил” на красный щуп и вешаем его на отключенный провод из предыдущего шага;
- Включаем стенд и подаем управляющий сигнал на контактор, производим замер.
- Отключаем стенд, восстанавливаем оригинальную схему подключения контактора;
- Важно: обязательно отключаем красный щуп из гнезда “10A” и возвращаем его в гнездо “V”.
Получаем результат – 180 мА:

Расчет балластной нагрузки: $$ R = \frac{V}{I} = \frac{24 \text{ В}}{0.180 \text{ А}} = 133.3(3) \text{ Ом} $$
Для реального импланта можно подобрать наиболее близкое значение разными методами, включая последовательное/параллельное подключение нескольких резисторов, но для прототипа импланта достаточно взять керамический резистор стандартного номинала в 120 Ом.
Рассеиваемая мощность: $$ P = I * V = \frac{V^2}{R} = \frac{24^2}{120} = 4.8 \text{ Вт} $$
Важно: стандартные металлоплёночные резисторы обычно способны рассеивать от 0.125 Вт до 0.5 Вт, поэтому для нашей задачи нам необходим именно керамический резистор на 10 Вт.

Обход цепей обратной связи (EDM Spoofing)
Реле безопасности Omron ожидает подтверждения от контактора при его активации и деактивации:
- При выключенном контакторе реле ожидает, что цепь EDM будет сомкнута;
- При включенном контакторе реле ожидает, что цепь EDM будет разомкнута.
Поэтому нам потребуется задействовать второй канал релейного модуля на импланте.
Устанавливаем этот релейный канал в разрыв цепи EDM последовательно с цепью EDM контактора: одна часть цепи заходит в COM, вторая в NC. Контакт NO остается пустым.
Разберем все возможные случаи в контексте цепи EDM:
| Состояние ПЛК | Имплант | Поведение импланта (EDM) | Состояние цепи EDM |
|---|---|---|---|
| ПЛК выдает сигнал | Обесточен | Пассивен как провод | Разомкнута из-за контактора |
| ПЛК не выдает сигнал | Обесточен | Пассивен как провод | Замкнута из-за контактора |
| ПЛК выдает сигнал | Включен, команды нет | Пассивен как провод | Разомкнута из-за контактора |
| ПЛК не выдает сигнал | Включен, команды нет | Пассивен как провод | Замкнута из-за контактора |
| ПЛК не выдает сигнал | Включен, команда на отключение | Пассивен как провод – игнорирует команды, если управляющего сигнала ПЛК нет | Замкнута из-за контактора |
| ПЛК выдает сигнал | Включен, команда на отключение | Разрывает цепь EDM | Разомкнута из-за импланта |
Благодаря последовательному подключению импланта в цепь EDM, во всех случаях, когда он пассивен – цепь EDM управляется реальным контактором и поведение системы ожидаемое и консистентное.
Благодаря архитектуре и логике работы имплант функционирует в режиме сигнатурной маскировки. Будучи внедрённым в цепь управления контактором, он воспроизводит ожидаемую нагрузочную сигнатуру катушки и сохраняет корректное состояние диагностических контуров. Это позволяет избежать аномалий, наблюдаемых реле безопасности и средствами контроля цепи управления.
Примечание: данный механизм распространяется только на цепь управления контактором и не затрагивает электрическую сигнатуру коммутируемой силовой нагрузки.
Со стороны системы управления выход ПЛК продолжает наблюдать ожидаемую электрическую нагрузку, система контроля линий регистрирует штатное потребление тока, а реле безопасности получает корректные сигналы обратной связи.
При этом фактический контроль над кинетикой процесса (включением или отключением исполнительного механизма на время наличия управляющего сигнала с ПЛК) переходит в руки оператора, находящегося за пределами периметра.
Узел управления: компоновка и схема подключения
Как мы уже говорили, система состоит из двух устройств: аппаратного импланта и узла управления. Приступим к проектированию компоновки.
Как и ранее, при разработке стенда АСУ ТП, мы используем open-source решение QElectroTech.
Создаем два Folio, один называем Remote Control Layout, второй – Remote Control Wiring. Мы собираем прототипы,
поэтому имплант и узел управления будут собираться на макетной плате.
Создаем новый элемент, называем его protoboard и схематично изображаем макетную плату:

Размещаем плату, далее создаем элемент для ESP32:

Создаем элемент для модуля LoRa Ra-02, и добавляем его на схему:

Далее добавляем вид спереди, создав соответствующие элементы для каждого компонента:

Эта проекция нам пригодится при планировании компоновки импланта.
Переходим к схеме подключения. Создаем схематичное изображение ESP32 и LoRa Ra-02, располагаем их на схеме:

Разводим шину SPI. Мы подробно разбирали шину SPI в одной из предыдущих статей. В классическом виде она состоит из 4-х проводов: SCK, MOSI, MISO и CS(NSS):

Подключаем линию прерываний DIO0, питание 3.3V, GND и антенну.
Помним правило радиопередающего оборудования: никогда не подавать питание и не инициировать передачу (TX) на модуле, к которому не подключена антенна, иначе отраженная волна приведет к выгоранию чипа.

Узел управления будет питаться от переносного аккумулятора USB.
Имплант: компоновка и схема подключения
Переходим к проектированию компоновки импланта. Устройство включает следующие компоненты:
- RPI Pico 2W
- Понижающий DC-DC преобразователь MP1584
- Оптопара TLP281
- Двухканальное реле с перекидным контактом 30VDC
- Радио-трансмиттер LoRa Ra-02
- Керамический резистор 120 Ом на 10 Вт
Создаем два новых Folio, называем их Hardware Implant Layout и Hardware Implant Wiring. Размещаем макетную плату
на схеме, а также создаем элемент для RPI Pico 2W.
Размещаем рядом понижающий DC-DC преобразователь, предварительно создав для него новый элемент в QElectroTech:

Далее создаем элемент для двухканального реле:

Размещаем на схеме оптопару и керамический резистор:

Теперь необходимо учесть два момента. Первое – требуется разместить радио-трансмиттер. Второе – согласно приведённым выше расчётам, на резисторе будет рассеиваться мощность около 5 Вт, что может привести к его нагреву до температуры свыше 100 °C.
Решением является размещение обоих компонентов над основной платой. Радио-трансмиттер будет закреплён над микроконтроллером, что позволит сократить длину соединений шины SPI.
Керамический резистор также будет поднят над устройством, благодаря чему тепло будет отводиться непосредственно в окружающий воздух, а не передаваться на макетную плату и соседние компоненты. Это позволит избежать перегрева основания устройства, деформации пластиковых элементов и повреждения проводников из-за высокой температуры резистора.
Добавляем вид спереди, чтобы показать вертикальное расположение элементов и их взаимное положение по высоте относительно основной платы. Изображаем резистор, закрепленный над платой:

Добавляем модуля LoRa на фронтальную проекцию. Для повышения наглядности добавляем выносной вид сверху этого модуля, так как на фронтальной проекции отображается только его боковая грань:

Переходим к схеме подключения. Размещаем общую шину 24 В на входе и подключаем проходные клеммы с плавкими предохранителями для предотвращения КЗ на линии.
К одной из линий общей шины подключаем понижающий DC-DC преобразователь. Он будет понижать 24 В до 5 В, от которых будет запитан имплант:

Далее нем необходимо отобразить существующую структуру стенда, управление над которым будет перехватывать аппаратный имплант.
Показываем подключение реле безопасности Omron. Более подробно о подключении реле безопасности с системой аварийной остановки мы уже говорили в одной из предыдущих статей.
Подключение реле безопасности:
- Нулевой выход ПЛК заходит на клемму реле 13;
- Клеммы T11 и T12, как и T21 с T22 – система аварийной остановки E-STOP; кнопка с двумя NC-контактами.
- Клемма A1 – питание +24 В; клемма A2 – 0V;
- Перемычка на контактах A и B – реле будет работать в режиме feedback loop и реагировать на положительный фронт сигнала в цепи EDM T31-T32.
- Земля PE обязательно подключена.

Добавляем на схему катушку перехватываемого контактора, обратный диод и NC-выход катушки для цепи EDM.
Цепь EDM реле безопасности T31-T32 проходит через NC-выход катушки контактора, а диод подключен обратной полярностью параллельно катушке – катод диода к плюсовой клемме катушки (A1+), анод диода к минусовой клемме (A2-).
Катушка контактора в данном случае управляется самим ПЛК через реле безопасности – контакт 14 на реле безопасности и есть управляющий сигнал. Он заходит на анод катушки контактора. Катод катушки контактора уходит в 0 В.
Это заводское подключение атакуемого узла управления:

Начинаем интеграцию импланта. Добавляем на схему двухканальное реле с перекидным контактом в разрыв управляющего сигнала:
- Теперь, управляющий сигнал идет от клеммы 14 реле безопасности на COM вход первого канала реле импланта.
- Согласно реализуемой архитектуре “fail-to-wire”, чтобы играть роль “куска провода” в случае отсутствия питания или сбоя импланта, вторую часть цепи, идущую на катушку контактора, подключаем к NC-контакту первого канала реле импланта.
- Через NO-контакт первого канала пойдет балластная нагрузка – искусственное сопротивление, эмулирующее катушку контактора.
Второй канал реле двухканального реле импланта устанавливается в разрыв EDM-цепи реле безопасности:
- Сигнал EDM из клеммы T31 реле безопасности проходит через NC-контакты контактора;
- Далее сигнал заходит в COM второго канала реле импланта;
- Для поддержания архитектуры “fail-to-wire” – вторую часть цепи EDM, которая возвращается в клемму T32 реле безопасности – подключаем к NC-контакту второго канала реле импланта.
- NO-контакт второго канала остается неподключенным,

Подключаем балластную нагрузку – керамический резистор R1 номиналом 120 Ом на 10 Вт – от NO-контакта первого канала реле импланта в 0 В общей шины.
Создаем новый элемент в QElectroTech для RPI Pico 2W с нужными пинами:
- Заводим плюсовую клемму понижающего DC-DC преобразователя на пин VSYS микроконтроллера;
- Минусовую клемму преобразователя соединяем с пином GND микроконтроллера;
- Добавляем распределительную колодку для локальной шины 3.3 В от пина 3.3V микроконтроллера;
Подключаем блок реле импланта:
- Каналы управления реле IN1 и IN2 соединяем с пинами микроконтроллера GP14 и GP15 соответственно;
- Оба пина GND на блоке реле подключаем к шине 0 В понижающего преобразователя. Примечание: это не идеальный случай, так как при общей земле формируется земляная петля (ground loop), о которой мы говорили в предыдущей статье. Оптопара, встроенная в реле, будет защищать только сигнальную линию. Для полной гальванической изоляции между группами контактов оптопары не должно быть ни одного общего провода.
- Пин JD-VCC – то есть питание катушек – подключаем на 5 В понижающего DC-DC преобразователя;
- Пин VCC – питание оптопары – подключаем к локальной шине 3.3 В от микроконтроллера.
Подключаем оптопару для чтения управляющего сигнала ПЛК:
- Выход управляющего сигнала с реле безопасности на клемме 14 уже идет в первый канал реле импланта на COM;
- Делаем от него ответвление, которое через резистор R2 номиналом 4.7 кОм заходит в оптопару со стороны входа;
- Проходя через светодиод оптопары, эта часть управляющего сигнала уходит в общую шину 0 В стенда;
- В коллектор фототранзистора попадает 3.3 В от шины микроконтроллера, а эмиттер заходит на пин GP13.

Последний этап – подключение радио-трансмиттера LoRa Ra-02:
- Разводим шину SPI: SCK, MOSI, MISO и NSS;
- Подключаем линию прерываний DIO0, питание 3.3V и GND;
- Подключаем антенну.

Финальная схема подключения в хорошем качестве:

Закупка компонентов, инструментов и расходников
Спецификация компонентов:
| Компонент | Кол-во / Примечание |
|---|---|
| Raspberry Pi Pico 2W | 1 |
| ESP32-WROOM-32 | 1 |
| LoRa RA-02 | 1 |
| Понижающий DC-DC преобразователь MP1584 | 1 |
| Двухканальное реле 30 V DC с перекидными контактами | 1 |
| Модуль оптопары TLP281 | 1 |
| Керамический резистор 10 Вт 120 Ом | 1 |
| Металлопленочный резистор 4.7 кОм | 1 |
| Макетная плата 830 | x2 |
Расходники и инструменты:
| Элемент | Кол-во / Примечание |
|---|---|
| Джамперы F–F 30 см | x40 |
| Джамперы M–F 30 см | x40 |
| Джамперы M–M 30 см | x40 |
| Проходные клеммы WAGO | x8 |
| Паяльник | 1 |
| Гель-флюс | 1 |
| Припой | 1 |
| Контактная гребёнка 40 pin 2.54 мм | x4 |
Ядро аппаратной части:

Пайка необходимых компонентов
На ESP32 в модификации ESP32-WROOM-32 пины уже распаяны.
Однако некоторые микроконтроллеры и модули поставляются без распаянных пинов, как, например, Raspberry Pi Pico 2W, модули LoRa Ra-02 и преобразователь MP1584.
Для этого нам понадобится паяльник, флюс-гель и припой:

Берем Raspberry PI Pico 2W. Видно, что пины не распаяны:

Устанавливаем пины на макетную плату:

Устанавливаем RPI Pico 2W поверх пинов и закрепляем, а далее:
- Нанести гель-флюс на контакты RPI
- Для паяльника удобно выбрать ножевидное жало (“жало-К”)
- Температуру нагрева выставить 320 °C
- Расплавить одну каплю олова на жале паяльника
- Коснуться жалом контакта RPI и пина одновременно
- Гель-флюс закипит и испарится, очистив контакт от окисленной пленки
- Поднести припой, и через довольно короткий промежуток времени припой растечется по контактной площадке, образуя форму “вулкана”
- Важно не перегреть плату, а также убедиться в отсутствии “мостов” – мест, где припой бы соединял две соседние контактные площадки.
Примечание: жало паяльника довольно быстро окисляется, поэтому на него нужно наносить олово в качестве защитного слоя, вне зависимости от того, включен он или нет. Однако перед непосредственным использованием – слой олова нужно стереть с нагретого жала подходящей тканью.
После того как плата остынет, можно использовать концентрированный изопропиловый спирт 90–99% (IPA, Isopropyl Alcohol) чтобы очистить плату от остатков флюса.
Результат пайки одной из сторон:

Заканчиваем пайку Raspberry PI Pico 2W, преобразователя MP1584 и двух модулей LoRa Ra-02.
Сборка узла управления
Итак, открываем компоновочную схему для узла управления, составленную выше. Узел состоит из микроконтроллера ESP32 и модуля LoRa Ra-02, соединенных шиной SPI, поэтому RPI Pico 2W пока откладываем в сторону.
Устанавливаем ESP32 на макетную плату:

Далее согласно схеме подключения выше разводим шину SPI и обязательно подключаем антенну:

Модуль LoRa Ra-02 установлен сверху – это сделано для того, чтобы удобно закрепить антенну – качество сигнала будет лучше при вертикальном расположении.
Подключаем узел управления к внешнему источнику питания:

Узел управления собран. Переходим к сборке импланта.
Сборка аппаратного импланта
Ориентируемся на компоновочную схему, разработанную в одном из предыдущих разделов. Первым делом устанавливаем Raspberry PI Pico 2W на макетную плату:

Далее идет понижающий DC-DC преобразователь MP1584:

Теперь устанавливаем реле. Из-за своих габаритов релейный модуль не помещается в стандартную контактную область макетной платы. Однако по углам платы реле предусмотрены четыре монтажных отверстия, которые можно использовать для его крепления.
Для фиксации модуля можно использовать стандартные штыревые разъёмы с шагом 2.54 мм. От длинной гребенки отламываем четыре секции по два контакта, которые затем вставляем в монтажные отверстия релейного модуля.
Для наших целей получившиеся стойки достаточно надёжно входят в отверстия макетной платы и обеспечивают достаточную механическую фиксацию даже без пайки.
Важно отметить, что монтажные отверстия электрически не связаны со схемой релейного модуля. Поэтому, несмотря на то что пины вмонтированы в шины питания макетной платы, это не приводит к возникновению нежелательных электрических соединений.

При необходимости конструкцию можно доработать, закрепив контакты пайкой или используя макетную плату большего размера.
Теперь устанавливаем оптопару. Конструкция модуля на базе оптопары TLP281 позволяет без дополнительных модификаций установить его непосредственно на макетную плату:

При размещении штыревыми контактами вниз модуль занимает устойчивое положение и обеспечивает удобный доступ ко всем необходимым выводам:

Следующим этапом является установка балластного резистора номиналом 120 Ом мощностью 10 Вт. Как отмечалось ранее, при работе устройства на резисторе будет рассеиваться до 5 Вт мощности, что приводит к его заметному нагреву.
Поэтому, чтобы снизить тепловое воздействие резистора на окружающие компоненты, проводники и саму плату – мы устанавливаем его на некотором расстоянии от макетной платы.
В промышленном исполнении для подобных задач обычно применяются специальные керамические стойки или монтажные элементы, рассчитанные на работу с мощными резисторами. Однако поскольку в данном случае собирается прототип устройства, было выбрано более простое решение.
Для крепления резистора использовались проходные клеммы WAGO, к которым были подключены короткие отрезки одножильного телефонного провода. Благодаря достаточной жёсткости жилы такая конструкция обеспечивает необходимую механическую поддержку и позволяет закрепить резистор над поверхностью макетной платы.

Несмотря на простоту реализации, данный способ оказался вполне достаточным для проведения испытаний, измерений и проверки работоспособности схемы. Вот таким образом резистор устанавливается на прототип:

Начинаем подключение с разводки SPI. Подключаем MOSI, MISO, NSS, SCK, DIO0, 3.3V и GND согласно схеме; подключаем выход понижающего конвертера к шинам питания макетной платы, а так же пины RPI: VSYS и GND.

Далее подключаем реле: JD-VCC (питание катушек) – от шины 5V, VCC (питание оптопары реле) от шины 3.3V, GND и входы IN1 и IN2 – согласно схеме подключения:

Теперь подключаем оптопару: HGND, HVCC (3.3V), GNC, IN1 через резистор в 4.7 кОм, а OUT1 на вход в RPI.

Далее собираем цепь управляющего сигнала, который будет приходить со стенда АСУ ТП в COM одного из каналов. NO-контакт уходит на балластную нагрузку – керамический резистор:

Оставшуюся часть – а именно питание на вход понижающего преобразователя, управляющих сигнал со стенда и цепь обратной связи мы подключим в следующей главе.
Интеграция аппаратного импланта
Приступаем к интеграции импланта в лабораторный стенд АСУ ТП, построенный в одной из предыдущих статей:

Нас интересует следующий узел: реле безопасности – flyback-диод – контактор:

Управляющий сигнал приходит от выхода ПЛК на 13-й контакт реле безопасности. Далее он выходит из 14-го контакта реле безопасности и заходит на катод flyback-диода.
Наша задача – “врезать” один из каналов реле импланта в разрыв этой цепи, а именно: провод от 14-й клеммы должен зайти на контакт COM реле импланта, и “выйти обратно” через NC-контакт, чтобы при потере питания имплант вел себя как кусок провода.
Также не забываем про ответвление на вход оптопары через уже установленный резистор 4.7 кОм.
Другой канал реле импланта “устанавливается” в разрыв цепи обратной связи EDM контактора: контакт 22NC контактора Sirius заходит в COM контакт реле импланта и “выходит обратно” через NC-контакт реле импланта, опять же, чтобы при потере питания имплант вел себя как кусок провода (fail-to-wire).
Для удобства демонстрации и подключения, провода были вынесены за пределы кабельных каналов стенда:

Заканчиваем интеграцию импланта согласно архитектуре, которую мы обсудили выше:
- Питание с шины 24V идет на вход понижающего конвертера;
- Управляющий сигнал заходит в COM и выходит через NC-контакт;
- EDM-цепь заходит в COM другого канала и также выходит через NC;
- Подключаем шину 3.3V от соответствующего пина RPI Pico 2W: 3V3(OUT).

Разработка программной части узла управления
Узел управления на базе микроконтроллера ESP32 функционирует в режиме локальной Wi-Fi-точки доступа, предоставляя оператору веб-интерфейс (Web UI).
С его помощью осуществляется дистанционное управление аппаратным имплантом и регулировка мощности радиопередатчика. Полученные от пользователя команды обрабатываются микроконтроллером и транслируются на целевое устройство по радиоканалу LoRa.
В одной из прошлых статей мы уже поднимали радиолинию на LoRa. Там же есть и шаги по прошивке ESP32 на Micropython, а также установке драйвера LoRa на ESP32.
Для работы с чипом SX1278, который установлен на модуле LoRa Ra-02 мы используем модифицированный драйвер wybiral/micropython-lora.
После установки драйвера нам нужно инициализировать SPI-интерфейс:
spi = SPI(SPI_ID, baudrate=1000000, sck=Pin(PIN_SCK), mosi=Pin(PIN_MOSI), miso=Pin(PIN_MISO))
И LoRa:
lora = LoRa(spi, cs=Pin(PIN_CS, Pin.OUT), rx=Pin(PIN_RX, Pin.IN))
После чего у нас появляются очень удобные команды:
lora.set_tx_power(tx_power)
lora.send("1")
Остается настроить параметры Wi-Fi сети, поднять веб сервер и показать интерфейс (HTML опущен для краткости).
Значения GPIO должны соответствовать схеме подключения, разработанной на этапе аппаратной интеграции.
Прошивка узла управления на ESP32
import network
import socket
from machine import Pin, SPI
import time
from lora import LoRa
# --- LoRa SPI settings ---
SPI_ID = 2
PIN_SCK = 18
PIN_MOSI = 23
PIN_MISO = 19
PIN_CS = 5
PIN_RX = 36
# Initialize SPI interface and LoRa module
spi = SPI(SPI_ID, baudrate=1000000, sck=Pin(PIN_SCK), mosi=Pin(PIN_MOSI), miso=Pin(PIN_MISO))
lora = LoRa(spi, cs=Pin(PIN_CS, Pin.OUT), rx=Pin(PIN_RX, Pin.IN))
# --- Access point setup ---
ssid = 'CONTROL_NODE'
password = 'changeit'
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid=ssid, password=password, authmode=3)
print("Access point enabled. IP address:", ap.ifconfig()[0])
# Set initial transmission power
tx_power = 2
lora.set_tx_power(tx_power)
# --- HTML payload ---
def web_page(current_pwr):
# Web UI HTML omitted for brevity
return html
# --- Web server initialization ---
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 80))
s.listen(5)
s.settimeout(0.2)
print("Web server listening on port 80...")
while True:
try:
conn, addr = s.accept()
conn.settimeout(1.0)
try:
request = conn.recv(1024).decode('utf-8', 'ignore')
if not request:
conn.close()
continue
first_line = request.split('\r\n')[0]
# Process incoming HTTP commands
if 'GET /?cmd=1' in first_line:
print(f"Override signal initiated. Request source: {addr[0]}")
lora.send("1")
conn.send('HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n')
elif 'GET /?cmd=0' in first_line:
print(f"Normal state restored. Request source: {addr[0]}")
lora.send("0")
conn.send('HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n')
elif 'GET /?pwr=' in first_line:
try:
p_val = int(first_line.split('/?pwr=')[1].split(' ')[0])
tx_power = max(2, min(p_val, 17))
lora.set_tx_power(tx_power)
print(f"Transmission power set to: {tx_power} dBm")
except:
pass
conn.send('HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n')
else:
resp = web_page(tx_power).encode('utf-8')
conn.send('HTTP/1.1 200 OK\r\n')
conn.send('Content-Type: text/html\r\n')
conn.send(f'Content-Length: {len(resp)}\r\n')
conn.send('Connection: close\r\n\r\n')
conn.sendall(resp)
except Exception as e:
pass
finally:
conn.close()
except OSError:
pass
time.sleep_ms(10)
Разработка программной части аппаратного импланта
Для аппаратного импланта на базе RPI Pico 2W, как и для узла управления, мы используем модифицированный драйвер wybiral/micropython-lora.
Прошиваем контроллер на Micropython, ставим драйвер (см. статью про NLOS-радиолинию), задаем значения GPIO в соответствии со схемой подключения, разработанной на этапе аппаратной интеграции.
Инициализируем spi и lora:
spi = SPI(SPI_ID, baudrate=1000000, sck=Pin(PIN_SCK), mosi=Pin(PIN_MOSI), miso=Pin(PIN_MISO))
lora = LoRa(spi, cs=Pin(PIN_CS, Pin.OUT), rx=Pin(PIN_RX, Pin.IN))
Input с оптопары:
opto_in = Pin(13, Pin.IN, Pin.PULL_DOWN)
И два управляющих канала реле:
relay_attack = Pin(14, Pin.OUT, value=1)
contactor_attack = Pin(15, Pin.OUT, value=1)
Получение команд асинхронное; on_recv – handler при получении данных по радиолинии:
lora.on_recv(on_recv)
lora.recv()
Основу прошивки составляет цикл, который непрерывно контролирует наличие управляющего сигнала от ПЛК. При его отсутствии устройство сбрасывает режим атаки, возвращает управление ПЛК и прекращает приём радио-команд.
При наличии управляющего сигнала состояние режима атаки определяется принятой командой управления. Далее выполняется коммутация двух каналов реле: один канал управляет катушкой контактора, второй – цепью EDM.
Прошивка аппаратного импланта на RPI Pico 2W
from machine import Pin, SPI
import time
from lora import LoRa
# --- LoRa settings ---
SPI_ID = 1
PIN_SCK = 10
PIN_MOSI = 11
PIN_MISO = 8
PIN_CS = 9
PIN_RX = 27
# Initialize SPI and LoRa transceiver
spi = SPI(SPI_ID, baudrate=1000000, sck=Pin(PIN_SCK), mosi=Pin(PIN_MOSI), miso=Pin(PIN_MISO))
lora = LoRa(spi, cs=Pin(PIN_CS, Pin.OUT), rx=Pin(PIN_RX, Pin.IN))
# Opto-isolator for monitoring PLC input
opto_in = Pin(13, Pin.IN, Pin.PULL_DOWN)
# Relay control pins
# Active-low configuration: initialized to 1 (high) to prevent accidental triggering on startup
relay_attack = Pin(14, Pin.OUT, value=1)
contactor_attack = Pin(15, Pin.OUT, value=1)
led = Pin("LED", Pin.OUT)
packet_flag = False
packet_data = b""
# Callback function for LoRa packet reception
def on_recv(payload):
global packet_flag, packet_data
packet_data = payload
packet_flag = True
lora.on_recv(on_recv)
lora.recv()
print("System initialized. Receiver active on 433 MHz.")
last_plc_state = -1
while True:
# 1. Monitor PLC control signal
plc_state = opto_in.value()
if plc_state != last_plc_state:
if plc_state == 1:
print("PLC signal detected: High (24 V)")
packet_flag = False
packet_data = None
led.value(1)
else:
print("PLC signal cleared: Low (0 V)")
led.value(0)
relay_attack.value(1) # Deactivate relays, restoring default signal path
contactor_attack.value(1)
packet_flag = False
packet_data = None
last_plc_state = plc_state
# 2. Process incoming wireless commands (only if PLC signal is active)
if packet_flag and plc_state == 1:
packet_flag = False
try:
msg = packet_data.decode()
rssi = lora.get_rssi()
print(f"Command received [RSSI: {rssi} dBm]: {msg}")
# Signal path override logic
if msg == "1":
print("Bypass path activated (Override)")
relay_attack.value(0) # Enable relays (Active-Low) to divert signal to dummy load
contactor_attack.value(0)
elif msg == "0":
print("Bypass path deactivated. Normal path restored.")
relay_attack.value(1) # Disable relays, returning to default signal path
contactor_attack.value(1)
except Exception as e:
print(f"Error processing packet: {e}")
time.sleep_ms(10)
Первый запуск системы
Важно: перед первым запуском системы необходимо ещё раз проверить схему подключения и убедиться в отсутствии КЗ. В противном случае существует риск повреждения контроллера, реле, оптопары и других компонентов схемы.
Подаём питание на стенд и нажимаем кнопку “Старт” на штатном пульте управления (HMI). ПЛК начинает выдавать управляющий сигнал. Об успешной коммутации нагрузки свидетельствует включение штатной сигнальной лампы стенда.
Кроме того, на RPI Pico 2W загорается зелёный светодиод, сигнализирующий о наличии управляющего сигнала от ПЛК. Светодиод включается программно при обнаружении управляющего сигнала независимо от дальнейшей логики обработки. Такое решение было реализовано специально для упрощения отладки и визуального контроля работы системы.

Подаем питание на узел управления; со смартфона находим Wi-Fi “CONTROL_NODE” и подключаемся к нему.

После этого заходим на Web UI по IP адресу. Для ESP32-WROOM-32 по-умолчанию IP будет 192.168.4.1:

Посылаем команду на отключение системы, и видим, что целевой объект атаки – сигнальная лампа на стенде – отключена:

Кроме этого – загораются светодиоды на двухканальном реле импланта, сигнализируя, что произошло переключение перекидного контакта. Светодиод на RPI Pico 2W продолжает гореть, т.к. управляющий сигнал ПЛК все еще на месте.
Подключаем оба устройства к ПК и смотрим на логи:

На скриншоте выше показаны логи узла управления (слева) и аппаратного импланта (справа).
После запуска узел управления переводит ESP32 в режим точки доступа Wi-Fi, поднимает веб-интерфейс управления и ожидает подключение оператора. Все поступающие через Web UI команды фиксируются в журнале с указанием IP-адреса источника запроса.
Справа отображается журнал аппаратного импланта. После инициализации устройство начинает контролировать состояние управляющего сигнала от ПЛК и принимать радиокоманды от узла управления. При обнаружении управляющего сигнала в журнале фиксируется его текущее состояние.
Каждая полученная радиокоманда также логируется вместе со значением RSSI, что позволяет оценивать качество радиоканала и уровень принимаемого сигнала.
RSSI (Received Signal Strength Indicator) – уровень мощности принятого сигнала. Он измеряется в дБм (децибел-милливатт). Это всегда отрицательное число – чем ближе к нулю, тем сигнал сильнее. Подробно об RSSI мы говорили в одной из прошлых статей.
Из приведённого журнала видно, что команды, отправленные оператором через веб-интерфейс, успешно принимаются имплантом и приводят к переключению между штатным и обходным режимами работы.
Видна корректная работа всей цепочки взаимодействия: оператор → узел управления → радиоканал → аппаратный имплант.
Испытания в реальных условиях
Приступаем к проверке работы системы в условиях, приближенных к реальным:
- Аппаратный имплант размещён внутри квартиры на десятом этаже жилого железобетонного здания, на значительном удалении от оконных проёмов и балкона.
- Узел управления находится у оператора и вынесен на расстояние около 70 метров от здания.
- Управление осуществляется со смартфона через штатный веб-интерфейс узла управления по Wi-Fi.
Несмотря на отсутствие прямой видимости и наличие многочисленных препятствий в виде железобетонных конструкций, деревьев, элементов городской инфраструктуры и соседних зданий, система сохраняет устойчивую работоспособность, а команды успешно доставляются до аппаратного импланта.
При использовании параметра spreading factor 7 (SF7) система обеспечивает уверенную работу на расстоянии около 70 метров. В ходе испытаний уровень принимаемого сигнала (RSSI) составлял порядка −106 dBm.
Увеличение spreading factor до значения SF12 позволяет увеличить дальность связи более чем до 140 метров в условиях плотной городской застройки.
Компромисс между дальностью связи и радиозаметностью
Следует отметить, что увеличение значения spreading factor не является “бесплатным” с точки зрения характеристик системы. В одной из прошлых статей мы уже говорили, что рост SF достигается за счёт снижения скорости передачи данных и увеличения времени нахождения передатчика в эфире.
В результате улучшается чувствительность приёмника и увеличивается дальность связи, однако значительно возрастает вероятность обнаружения работы радиоканала средствами радиомониторинга.
С точки зрения Red Team такой компромисс требует отдельной оценки, поскольку максимальная дальность связи не всегда является оптимальным выбором.
Во многих сценариях более предпочтительным может оказаться использование меньших значений SF, обеспечивающих сокращение эфирного времени и снижение радиозаметности системы.
Заключение
В данной работе представлен процесс проектирования, сборки и лабораторного тестирования прототипа аппаратного импланта для перехвата сигналов в цепи управления 24 В постоянного тока.
Проведенные испытания подтвердили техническую реализуемость обхода систем диагностики (EDM, контроль обрыва линии) за счет динамической эмуляции электрических параметров нагрузки и состояний вспомогательных контактов контактора.
Разработанное устройство является прототипом (Proof of Concept) и обладает рядом ограничений, критичных для применения вне лабораторной среды:
Односторонний канал связи (нет ACK)
Уязвимость к replay-атакам
Радиозаметность
В следующей части исследования мы рассмотрим технические решения для оптимизации радиоканала и методы противодействия подобным угрозам: повышение скрытности и безопасности канала управления (взгляд Red Team) и методы обнаружения и анализа несанкционированных передатчиков (взгляд Blue Team).
Авторство и отказ от ответственности
Данная инженерно-исследовательская статья является независимой работой Марка Чеснавского (2026). Структура подачи материала, аналитические разборы, исходный код и практические реализации (PoC) представляют собой оригинальный авторский труд. Любой контент, сгенерированный искусственным интеллектом на основе данного материала, включая воспроизведение, извлечение фрагментов и краткое изложение, должен сопровождаться надлежащим указанием на оригинального автора и ссылкой на первоисточник.
Несанкционированное вмешательство в работу АСУ ТП и КИИ является уголовным преступлением. Автор не несет ответственности за противоправные действия третьих лиц, возможный ущерб, выведение из строя оборудования или нарушение регламентов радиосвязи.