Привет, Хабр! Хочу рассказать об инструменте, который мы делали для реальных задач — аудита безопасности промышленных сетей. Называется Industrial Scanner Pro, написан на Go, имеет веб-интерфейс и умеет работать с тремя ключевыми промышленными протоколами. Репозиторий лежит на GitVerse.
Статья будет полезна тем, кто занимается ОТ-безопасностью, пишет инструменты для пентеста промышленных систем или просто интересуется, как устроены ICS-сети изнутри.
Зачем ещё один сканер?
Когда берёшься за аудит промышленной сети, инструментарий оказывается неожиданно скудным. Nmap умеет многое, но не понимает Modbus или S7. Специализированные коммерческие решения стоят десятки тысяч долларов и заточены под конкретных вендоров. Открытые альтернативы — PLCscan, modscan, s7scan — узкоспециализированы: каждый работает с одним протоколом, у большинства нет нормального UI, а агрегировать результаты приходится руками.
Нам нужно было:
-
Один инструмент для трёх основных промышленных протоколов
-
Оценка рисков по каждому обнаруженному устройству, а не просто список открытых портов
-
Веб-интерфейс — чтобы можно было показать заказчику прямо в браузере, без установки клиента
-
Кросс-платформенность — собирается под Linux, Windows и macOS из одного codebase
Так появился Industrial Scanner Pro.
Поддерживаемые протоколы
Modbus TCP (порт 502)
Самый распространённый промышленный протокол. Появился в 1979 году и до сих пор живёт в большинстве ПЛК, частотных преобразователях и промышленных контроллерах. Главная его проблема с точки зрения безопасности — полное отсутствие аутентификации. Любой, кто добрался до сети, может читать и писать регистры.
Сканер подключается к устройству, читает Holding Registers и Input Registers, опрашивает несколько Unit ID и строит карту доступных данных.
[Modbus] 192.168.1.10:502 Unit ID: 1 — доступен Holding Registers [0–9]: [1024, 0, 255, 0, 512, ...] Coils [0–7]: [1, 0, 1, 1, 0, 0, 1, 0] Риск: ВЫСОКИЙ — открытая запись регистров без аутентификации
Siemens S7 (порт 102)
Протокол семейства SIMATIC S7 — де-факто стандарт для европейской промышленности. Работает поверх ISO-on-TCP (RFC 1006). Содержит богатую диагностическую информацию: имя устройства, версию прошивки, серийный номер, тип CPU.
Именно эти данные особенно ценны при разведке: зная точную версию прошивки Siemens S7-300, можно проверить известные CVE.
[S7] 192.168.1.20:102 Имя: S7-300 CPU 315-2 DP Версия: V3.3.12 Серийный номер: S C-X4U487474 Тип модуля: CPU Риск: СРЕДНИЙ — доступна диагностическая информация
DNP3 (порт 20000)
Протокол, широко используемый в электроэнергетике, водоснабжении и нефтегазовой отрасли. Поддерживает метки времени, CRC-проверку и адресацию удалённых терминальных устройств (RTU). В отличие от Modbus, чуть сложнее в реализации, но принципиально та же история: в большинстве инсталляций аутентификация отсутствует или опциональна.
Архитектура
Проект разбит на чёткие слои:
industrial-network-scanner/├── main.go # Точка входа, HTTP-сервер, маршрутизация├── scanner/ # Ядро сканирования│ ├── scanner.go # Оркестратор: управление горутинами, агрегация│ ├── modbus.go # Modbus TCP клиент│ ├── s7.go # Siemens S7 клиент (ISO-on-TCP)│ └── dnp3.go # DNP3 клиент├── frontend/ # Финальная сборка веб-интерфейса├── frontend_modern/ # Исходники UI (современная версия)├── frontend_legacy/ # Исходники UI (легаси версия)├── go.mod├── build.sh # Сборка под Linux/macOS└── build_windows.bat # Сборка под Windows
Почему Go?
Три причины:
-
Горутины. Сканирование сети — задача с высоким параллелизмом. На /24-подсети это 254 хоста × 3 протокола = 762 потенциальных соединения. Go позволяет запускать их конкурентно без головной боли с thread pools.
-
Статическая компиляция. Бинарник не тянет зависимостей. Скопировал на машину — запустил. Для полевого аудита это критично.
-
Стандартная библиотека. Встроенный
net/httpпозволяет поднять веб-сервер буквально в десяток строк. Не нужен ни Flask, ни Node — сканер сам раздаёт свой фронтенд.
Как устроен сканер внутри
// Упрощённая схема оркестратораfunc (s *Scanner) Scan(targets []string) []Result { results := make(chan Result, len(targets)*3) var wg sync.WaitGroup for _, target := range targets { wg.Add(3) go func(t string) { defer wg.Done() results <- s.scanModbus(t) }(target) go func(t string) { defer wg.Done() results <- s.scanS7(t) }(target) go func(t string) { defer wg.Done() results <- s.scanDNP3(t) }(target) } wg.Wait() close(results) // агрегация и оценка рисков...}
Каждый протокольный модуль независим: у него своя логика подключения, таймауты и разбор ответа.
Оценка рисков
Это, пожалуй, самая интересная часть. Мало обнаружить устройство — важно объяснить, насколько оно опасно.
Модель оценки строится из нескольких факторов:
|
Фактор |
Описание |
|---|---|
|
Открытость протокола |
Доступен ли протокол без аутентификации |
|
Объём раскрытых данных |
Количество читаемых регистров / тип раскрытой информации |
|
Возможность записи |
Можно ли не только читать, но и изменять данные |
|
Идентификация устройства |
Доступны ли версия прошивки, серийный номер, тип CPU |
|
Критичность сегмента |
Энергетика, водоснабжение, производство — разный вес |
Итоговый уровень: LOW / MEDIUM / HIGH / CRITICAL.
Устройство: 192.168.1.10Протоколы: Modbus TCP, DNP3Открытая запись: ДА (Modbus holding registers)Раскрытие версии: НЕТИтоговый риск: CRITICALРекомендации: - Ограничить доступ к порту 502 с помощью промышленного firewall - Внедрить Modbus-proxy с контролем команд - Рассмотреть перевод на Modbus Security (RFC 2217 + TLS)
Форматы целей
Сканер умеет принимать цели в нескольких форматах:
# Одиночный хост./scanner 192.168.1.100# CIDR-диапазон./scanner 192.168.1.0/24# Список из файла./scanner -f targets.txt# Диапазон адресов./scanner 10.0.0.1-10.0.0.50
Веб-интерфейс
Статический фронтенд раздаётся прямо из бинарника — файлы встраиваются через //go:embed. Открываешь браузер на http://localhost:8080, и получаешь дашборд с:
-
картой обнаруженных устройств
-
детальными данными по каждому узлу
-
цветовой маркировкой уровней риска
-
возможностью экспорта в JSON и CSV
В репозитории есть две версии фронтенда: frontend_modern (актуальная) и frontend_legacy (совместимость со старыми браузерами промышленных HMI-станций — там до сих пор встречается IE11).
REST API
Помимо UI, сканер предоставляет API для интеграции с другими системами:
GET /api/scan?target=192.168.1.0/24 — запустить сканированиеGET /api/results — получить результатыGET /api/results/{ip} — результаты по конкретному хостуGET /api/export?format=json — экспортGET /api/export?format=csv — экспорт в CSV
Это позволяет встраивать сканер в пайплайны CI/CD безопасности или в SIEM-системы.
Сборка
# Linux / macOSgit clone https://gitverse.ru/plcstudio/industrial-network-scannercd industrial-network-scanner./build.sh# Windowsbuild_windows.bat# Или вручнуюgo build -o industrial-scanner main.go
Требования: Go 1.21+. Внешних зависимостей минимум — всё описано в go.mod.
Для сборки под все платформы сразу:
GOOS=linux GOARCH=amd64 go build -o dist/scanner-linux-amd64 main.goGOOS=windows GOARCH=amd64 go build -o dist/scanner-windows-amd64.exe main.goGOOS=darwin GOARCH=arm64 go build -o dist/scanner-darwin-arm64 main.go
Правовое предупреждение
Инструмент предназначен исключительно для авторизованного аудита безопасности. Сканирование промышленных сетей без разрешения владельца — уголовно наказуемое деяние во многих юрисдикциях, включая Россию (ст. 272, 273 УК РФ).
Всегда получайте письменное разрешение перед использованием.
Что дальше
В планах:
-
Поддержка EtherNet/IP (Rockwell/Allen-Bradley) — протокол широко используется в американских промышленных установках
-
Поддержка OPC-UA — современный стандарт, который активно вытесняет старые протоколы
-
Пассивный режим — обнаружение устройств через анализ трафика без активного сканирования (более безопасно для хрупких OT-устройств)
-
Интеграция с базой CVE для автоматического поиска известных уязвимостей по обнаруженным версиям прошивок
Итого
Industrial Scanner Pro — это попытка сделать адекватный open‑source инструмент для аудита ICS‑сетей: с поддержкой основных протоколов, оценкой рисков, нормальным UI и возможностью встраивания в автоматизированные пайплайны.
Код открыт, issues и PR приветствуются. Если занимаетесь ОТ‑безопасностью или просто интересуетесь темой — буду рад обратной связи в комментариях.
ссылка на оригинал статьи https://habr.com/ru/articles/1043682/