Если вы не знаете, что такое Сканер-ВС, краткое пояснение:
Сканер-ВС 7 — инструмент для анализа сетевой защиты, который сканит порты на IP и подсетях для выявления брешей и уязвимостей в системе. Разворачивается в локальной сети организации. Благодаря наличию API работу сканера можно неплохо автоматизировать — подготовить скрипты, которые будут запускать проверку по расписанию, собирать уязвимости и формировать отчеты.
В новой версии скрипта для Сканера-ВС 7 сохранены ключевые идеи предыдущих решений, но существенно упрощен пайплайн и интегрированы новые возможности API.
Скрипт полностью автоматизирует весь цикл, начиная от сканирования сети и поиска уязвимостей и заканчивая созданием отчета и алертом об этом в мессенджере. Я минимизирую любое ручное вмешательство, чтобы автоматизация была действительно полной и еще автономной.
Ранее на примере сканера шестой версии я показывал, как работает API сканера и как автоматизировать обычный процесс — создать задачу для разных спейсов, запустить и отслеживать сетевой скан и скан уязвимостей, и в итоге получить отчеты с алертом.
Но все стремится к упрощению и гармонии. Желание упростить переход между стадиями, обеспечить более гибкую обработку входных данных и повысить устойчивость процесса не давало мне покоя. В итоге в версии 3.0 были добавлены новые фичи, а также усовершенствованы существующие механизмы.
Новые требования и возможности
В версии 3.0 я стремился сделать скрипт универсальнее и надежнее. Рассмотрим основные задачи, которые были закрыты в версии 2.0.
Сделать наконец гибкий формат входных данных. Поддерживается работа с отдельными IP-адресами и подсетями. Если в JSON указана подсеть — скрипт автоматически «тыкает» все адреса в этой подсети и добавляет живые хосты для сканирования.
Группировка по клиентам и спейсам для внутренней инфраструктуры. Все адреса, будь то подсеть или единичный IP, объединяются по атрибуту name в одну группу. Каждой группе соответствует один netscan, один vulnscan и один отчет. Это снижает нагрузку на сканер, так как вместо десятков задач по одному IP, что сразу влечет за собой зависание веба, создается одна на всю группу.
Пошаговый пайплайн с сохранением состояния. Скрипт продолжает использовать файл JSON для хранения прогресса, но теперь полностью автоматизирован переход между этапами. В начале каждого запуска проверяется поле stage в JSON: netscan, vulnscan или report. В зависимости от этого запускаем нужный этап.
После завершения текущего этапа — сохраняем в JSON новый stage и выходим. Таким образом, скрипт можно поставить на автозапуск в планировщике cron так часто, как нужно, а работа будет продолжена с места остановки, а не создавать каждый раз netscan для всех ваших активов.
Новые вызовы, которые закрывает v3.0
Автообновление и авторизация. Как и раньше, используется внешний скрипт с помощью curl для авторизации и получения cookie. Но теперь после каждого запроса к API проверяем код ответа: если это 401 или 403 (главное, чтобы не 404), скрипт автоматически переавторизуется. Это устраняет ситуации, когда токен истекал и скрипт падал, а такое бывало нередко.
Обработка ошибок и восстановление. Появилась функция recreate_task_on_error. Если при проверке статуса задачи видим, что она в состоянии error, failed или not_found, скрипт сам удаляет неудачную задачу и создает новую с теми же параметрами. Приведу пример кода:
def recreate_task_on_error(
auth_cookies, task_type, client_name, old_task_id, create_func, create_args
):
print(f"Задача {old_task_id} в ошибке. Пересоздаем...")
delete_task(auth_cookies, old_task_id)
new_task_id = create_func(auth_cookies, client_name, *create_args)
if new_task_id:
run_task(auth_cookies, new_task_id)
print(f"Задача пересоздана. Новый ID: {new_task_id}")
return new_task_id
print("Не удалось пересоздать задачу.")
return None
Это обеспечивает самовосстановление: нам больше не нужно вручную чистить и заново запускать задачи. Раньше если что-то шло не так, то приходилось вручную сносить задачу, потому что из-за нее весь пул задач не мог продвинуться дальше.
Отказ от прямой работы с БД. В версии 2.0 приходилось прибегать к SQL-командам для очистки «зависших» записей в базе, как советовал саппорт. Сейчас это не нужно: скрипт, как и раньше, удаляет созданные assets и tasks через API по завершении работы.
В итоге версия 3.0 выполняет все те же действия, но с пользовательским опытом добавились новые фичи: более надежный код, автопроверка задач и гибкость входных данных. За фидбэк спасибо коллегам Ване и Руслану!
Гибкий ввод IP и сетей
Как и в 2.0, в JSON-списке клиентов можно указывать либо поле ip, либо net . Но теперь скрипт сначала обнаруживает активные адреса в подсетях, а потом уже группирует их. В начале выполнения, если stage = netscan, скрипт пробегает по всем записям с ключом net, пингует их и создает новые записи для «живых» IP.
def get_alive_ips(network: str):
net = ipaddress.ip_network(network, strict=False)
alive = []
for ip in net.hosts():
ip_str = str(ip)
try:
result = subprocess.run(
["ping", "-c", "1", "-W", "1", ip_str],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
if result.returncode == 0:
alive.append(ip_str)
except Exception:
continue
return alive
]
[
alive_ips = get_alive_ips(net)
print(f"В сети {net} для клиента {name} найдено живых IP: {len(alive_ips)}")
Функция get_alive_ips(network) в цикле пингует каждый адрес в сети. В итоге все рабочие адреса из подсети добавляются как отдельные элементы списка клиентов. Для автоматизации это отличное решение: скрипт сам определяет и добавляет все живые хосты, так как добавить подсеть целиком через API нельзя.
Группировка по именам
Затем мы объединяем адреса по клиентам с одинаковым полем name. В результате для каждого уникального поля формируется группа:
def group_clients_by_name(clients_list):
groups = {}
for c in clients_list:
name = c.get("name")
if not name:
continue
if name not in groups:
groups[name] = {
"name": name,
"ips": [],
"assets": [],
"id_netscan": None,
"id_vulnscan": None,
"status": None,
}
В версии 3.0 мы храним для каждой группы не только список IP, но и идентификаторы задач и статус. Это, как и раньше, помогает отслеживать прогресс, но теперь, при введенном обработчике ошибок, если в группе есть задача с ошибкой, она перезапускается автоматически.
Новая структура кода и конфигурация
Некоторые другие изменения в версии 3.0 касаются организации кода и параметров запуска.
Перенесена авторизация в отдельный скрипт curl, в основном коде выполняется subprocess.run(["bash", CURL_FILE]), а затем читается файл с куки. Внешний модуль в git — это база. Кроме того, переменные для Telegram: TELEGRAM_BOT_TOKEN и TELEGRAM_CHAT_ID — теперь читаются из окружения, что очень безопасно.
Отдельно про Telegram. В прошлой статье я упоминал, что изучу возможность выгрузки отчетов в мессенджер, чтобы сразу скачивать отчеты без проблем. Однако в процессе реализации я сознательно отказался от этой идеи. Пересылать полные отчеты об уязвимостях через сторонние платформы — это неоправданный риск, а безопасность все же нужно соблюдать. В итоге я оставил в Telegram только оперативные алерты, а сами данные должны оставаться в защищенном контуре.
Итоги улучшений v3.0
Новая версия скрипта — результат работы над ошибками, накопленного опыта и адаптации под нововведения Сканера-ВС 7. Из ключевых преимуществ нового кода можно выделить несколько моментов.
Появилась гибкость ввода. Мы просто указываем сеть или IP, а скрипт сам проверит рабочие хосты в подсетях. Теперь потребуется минимум ручной работы: один JSON-файл со списком адресов и cron для запуска — это все, что нужно для автоматизации.
Повысилась надежность. Скрипт проверяет статусы, перезаходит, пересоздает упавшие задачи, и даже если машина со сканером уйдет в ребут — после восстановления продолжит работу с того места, где закончили.
Удобство использования. Список адресов с именами позволяет оптимизировать работу сканера, не перегружать веб и управлять большим количеством клиентов или внутренних пространств.
Отчеты почти не тронуты — единственное, для большей безопасности были обезличены переменные с токеном и чат IP. В итоге доработка скрипта оказалась полезна и опробована на боевом сканировании: ошибочные задачи были пересозданы, при каждом запуске всегда срабатывала новая авторизация, и ошибки 4ХХ не сыпались нам в CLI. Надеюсь, данная статья поможет вам поймать попутный ветер в направлении автоматизации своих сканирований.