Screenshot_12.png


Хочу рассказать об инструменте, который мы делали для реальных задач — аудита безопасности промышленных сетей. Называется 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?​

Три причины:

  1. Горутины. Сканирование сети — задача с высоким параллелизмом. На /24-подсети это 254 хоста × 3 протокола = 762 потенциальных соединения. Go позволяет запускать их конкурентно без головной боли с thread pools.
  2. Статическая компиляция. Бинарник не тянет зависимостей. Скопировал на машину — запустил. Для полевого аудита это критично.
  3. Стандартная библиотека. Встроенный 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)
    // агрегация и оценка рисков...
}

Каждый протокольный модуль независим: у него своя логика подключения, таймауты и разбор ответа.

Оценка рисков​

Это, пожалуй, самая интересная часть. Мало обнаружить устройство — важно объяснить, насколько оно опасно.

Модель оценки строится из нескольких факторов:

Screenshot_11.png


Итоговый уровень: 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 / 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 приветствуются. Если занимаетесь ОТ‑безопасностью или просто интересуетесь темой — буду рад обратной связи в комментариях.