- PVSM.RU - https://www.pvsm.ru -
Привет! Хочу рассказать об инструменте, который мы делали для реальных задач — аудита безопасности промышленных сетей. Называется Industrial Scanner Pro, написан на Go, имеет веб-интерфейс и умеет работать с тремя ключевыми промышленными протоколами. Репозиторий лежит на GitVerse [1].
Статья будет полезна тем, кто занимается ОТ-безопасностью, пишет инструменты для пентеста промышленных систем или просто интересуется, как устроены ICS-сети изнутри.
Когда берёшься за аудит промышленной сети, инструментарий оказывается неожиданно скудным. Nmap умеет многое, но не понимает Modbus или S7. Специализированные коммерческие решения стоят десятки тысяч долларов и заточены под конкретных вендоров. Открытые альтернативы — PLCscan, modscan, s7scan — узкоспециализированы: каждый работает с одним протоколом, у большинства нет нормального UI, а агрегировать результаты приходится руками.
Нам нужно было:
Один инструмент для трёх основных промышленных протоколов
Оценка рисков по каждому обнаруженному устройству, а не просто список открытых портов
Веб-интерфейс — чтобы можно было показать заказчику прямо в браузере, без установки клиента
Кросс-платформенность — собирается под Linux, Windows и macOS из одного codebase
Так появился Industrial Scanner Pro.
Самый распространённый промышленный протокол. Появился в 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]
Риск: ВЫСОКИЙ — открытая запись регистров без аутентификации
Протокол семейства 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
Риск: СРЕДНИЙ — доступна диагностическая информация
Протокол, широко используемый в электроэнергетике, водоснабжении и нефтегазовой отрасли. Поддерживает метки времени, 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
Три причины:
Горутины. Сканирование сети — задача с высоким параллелизмом. На /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).
Помимо 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 / macOS
git clone https://gitverse.ru/plcstudio/industrial-network-scanner
cd industrial-network-scanner
./build.sh
# Windows
build_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.go
GOOS=windows GOARCH=amd64 go build -o dist/scanner-windows-amd64.exe main.go
GOOS=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 приветствуются. Если занимаетесь ОТ‑безопасностью или просто интересуетесь темой — буду рад обратной связи в комментариях.
Автор: ura-ch
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/golang/452598
Ссылки в тексте:
[1] GitVerse: https://gitverse.ru/plcstudio/industrial-network-scanner
[2] Источник: https://habr.com/ru/articles/1043682/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1043682
Нажмите здесь для печати.