Хабр. Антон Дятлов, инженер по защите информации в Selectel, рассказывает о Сканере-ВС 7, в котором изменилась логика работы с API. Старый скрипт перестал корректно работать, и улучшения напрашивались сами собой. Рассмотрим основные изменения и улучшения.
Описание Сканера-ВС 7
Сканер-ВС 7 — инструмент для анализа сетевой защиты, который сканит порты на IP и подсетях для выявления брешей и уязвимостей в системе. Разворачивается в локальной сети организации. Благодаря наличию API работу сканера можно неплохо автоматизировать — подготовить скрипты, которые будут запускать проверку по расписанию, собирать уязвимости и формировать отчеты.Основные изменения в новой версии скрипта
В новой версии скрипта для Сканера-ВС 7 сохранены ключевые идеи предыдущих решений, но существенно упрощен пайплайн и интегрированы новые возможности API. Скрипт полностью автоматизирует весь цикл, начиная от сканирования сети и поиска уязвимостей и заканчивая созданием отчета и алертом об этом в мессенджере. Минимизировано любое ручное вмешательство, чтобы автоматизация была действительно полной и еще автономной.Новые требования и возможности в версии 3.0
Новые требования и возможности в версии 3.0 включают:- Гибкий формат входных данных, поддержка работы с отдельными IP-адресами и подсетями.
- Группировка по клиентам и спейсам для внутренней инфраструктуры.
- Пошаговый пайплайн с сохранением состояния.
Автообновление и авторизация теперь включают проверку кода ответа после каждого запроса к API, что устраняет ситуации, когда токен истекал и скрипт падал. Обработка ошибок и восстановление включают функцию recreatetaskon_error, которая удаляет неудачную задачу и создает новую с теми же параметрами.
print("Не удалось пересоздать задачу.")
return None
Это обеспечивает самовосстановление: больше не требуется вручную чистить и заново запускать задачи. Ранее при возникновении проблем приходилось вручную удалять задачу, поскольку из-за нее весь пул задач не мог продвинуться дальше.
Отказ от прямой работы с БД. В версии 2.0 приходилось использовать SQL-команды для очистки «зависших» записей в базе, как советовал саппорт. Сейчас это не требуется: скрипт, как и раньше, удаляет созданные assets и tasks через API по завершении работы.
Гибкий ввод IP и сетей
Как и в 2.0, в JSON-списке клиентов можно указывать либо полеip, либо net. Теперь скрипт сначала обнаруживает активные адреса в подсетях, а затем уже группирует их. В начале выполнения, если stage = netscan, скрипт пробегает по всем записям с ключом net, пингует их и создает новые записи для «живых» IP.
def getaliveips(network: str):
net = ipaddress.ipnetwork(network, strict=False)
alive = []
for ip in net.hosts():
ipstr = str(ip)
try:
result = subprocess.run(
["ping", "-c", "1", "-W", "1", ipstr],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
if result.returncode == 0:
alive.append(ipstr)
except Exception:
continue
return alive
aliveips = getaliveips(net)
print(f"В сети {net} для клиента {name} найдено живых IP: {len(aliveips)}")
Функция getaliveips(network) в цикле пингует каждый адрес в сети. В итоге все рабочие адреса из подсети добавляются как отдельные элементы списка клиентов. Для автоматизации это отличное решение: скрипт сам определяет и добавляет все живые хосты, так как добавить подсеть целиком через API нельзя.
Группировка по именам
Затем объединяются адреса по клиентам с одинаковым полемname. В результате для каждого уникального поля формируется группа:
def groupclientsbyname(clientslist):
groups = {}
for c in clientslist:
name = c.get("name")
if not name:
continue
if name not in groups:
groups[name] = {
"name": name,
"ips": [],
"assets": [],
"idnetscan": None,
"idvulnscan": None,
"status": None,
}
В версии 3.0 для каждой группы хранятся не только список IP, но и идентификаторы задач и статус. Это, как и раньше, помогает отслеживать прогресс, но теперь, при наличии обработчика ошибок, если в группе есть задача с ошибкой, она перезапускается автоматически.
Новая структура кода и конфигурация
Некоторые другие изменения в версии 3.0 касаются организации кода и параметров запуска. Перенесена авторизация в отдельный скрипт curl, в основном коде выполняетсяsubprocess.run(["bash", CURLFILE]), а затем читается файл с куки. Внешний модуль в git — это база. Кроме того, переменные для Telegram: TELEGRAMBOTTOKEN и TELEGRAMCHATID — теперь читаются из окружения, что очень безопасно.
Отдельно про Telegram. В прошлой статье упоминалось, что изучалась возможность выгрузки отчетов в мессенджер, чтобы сразу скачивать отчеты без проблем. Однако в процессе реализации было принято решение отказаться от этой идеи. Пересылать полные отчеты об уязвимостях через сторонние платформы — это неоправданный риск, а безопасность все же нужно соблюдать. В итоге в Telegram оставлены только оперативные алерты, а сами данные должны оставаться в защищенном контуре.
Итоги улучшений v3.0
Новая версия скрипта — результат работы над ошибками, накопленного опыта и адаптации под нововведения Сканера-ВС 7. Из ключевых преимуществ нового кода можно выделить несколько моментов:
Появилась гибкость ввода
Указывается сеть или IP, а скрипт сам проверит рабочие хосты в подсетях. Теперь потребуется минимум ручной работы: один JSON-файл со списком адресов иcron для запуска — это все, что нужно для автоматизации.
Повысилась надежность
Скрипт проверяет статусы, перезаходит, пересоздает упавшие задачи, и даже если машина со сканером уйдет в ребут — после восстановления продолжит работу с того места, где закончили.Удобство использования
Список адресов с именами позволяет оптимизировать работу сканера, не перегружать веб и управлять большим количеством клиентов или внутренних пространств.Отчеты почти не тронуты — единственное, для большей безопасности были обезличены переменные с токеном и чат IP. В итоге доработка скрипта оказалась полезной и опробованной на боевом сканировании: ошибочные задачи были пересозданы, при каждом запуске всегда срабатывала новая авторизация, и ошибки 4ХХ не сыпались в CLI.