РАЗБОР На проверке 

Автоматизация пентест-лаборатории: Vagrant + Ansible

Сергей Попов
Сергей Попов Red Team · 6,4 тыс. сообщений
Подписаться
51
Режим чтения
Тёмная лаборатория с тремя изогнутыми мониторами — единственным источником света в кадре. На экранах видны терминал с командами Vagrant, плейбук Ansible и схема сети с узлами DC, рабочих станций и...


Последний раз, когда я собирал AD-лабораторию вручную - контроллер домена на Server 2022, две рабочих станции Windows 11, Kali в качестве атакующей машины - ушло шесть часов. Через неделю экспериментов с Kerberoasting и relay-атаками стенд превратился в кашу: сломанные GPO, потерянные снапшоты VirtualBox, откуда-то взявшийся второй host-only адаптер. Пересобирать - ещё шесть часов. Знакомо?

Год назад я перевёл всё на Infrastructure as Code. Теперь пересборка выглядит так: vagrant destroy -f && vagrant up, потом ansible-playbook site.yml - 12 минут, и чистый стенд с Kerberos на RC4, отключённым SMB Signing и двумя доменными пользователями без прав готов к работе. Можно ломать.

Зачем инфраструктура как код для пентест-лаборатории​

Снапшоты решают одну задачу - откат. Остальное не закрывают:
  • Воспроизводимость. Коллега просит ваш стенд - кидаете Vagrantfile + playbook.yml из git-репозитория. Идентичная среда за 15 минут вместо пересылки 40 ГБ образов.
  • Версионирование. Вчера тестировали Unconstrained Delegation - сегодня нужна чистая среда для RBCD. Два коммита, два состояния домашней лаборатории для пентеста.
  • Параллельные конфигурации. Проверить один payload на Server 2016, 2019 и 2022 - три ветки конфигов, три независимых стенда.
  • Скорость итерации. Privilege escalation через PrintSpooler сломал DC - vagrant provision dc, десять минут, всё на месте.
Русскоязычные материалы по запросу «автоматизация пентеста» почти целиком про автоматизацию самого тестирования - Nuclei-шаблоны, PT Dephaze, сканеры. Настройка киберполигона своими руками через IaC не покрыта практически никем. Англоязычное сообщество давно использует связку IaC-инструментов для сборки offensive-лабораторий - блоги Pentest Partners (Packer + Terraform + Ansible на ESXi), проект DetectionLab, доклады HashiCorp по rapid cyber range development. Адаптируем этот подход под наши реалии.

Три инструмента закрывают полный цикл виртуальной лаборатории для пентестера:

ИнструментРоль в стекеКогда подходитКогда НЕ подходит
VagrantУправление жизненным циклом VMЛокальная лаба на VirtualBox/libvirt, быстрая итерацияОблачные ресурсы, масштаб >10 VM
AnsibleКонфигурационный менеджментУстановка ПО, настройка AD, намеренные misconfigurationsСоздание VM или сетевой инфраструктуры с нуля
TerraformПровижининг инфраструктурыОблако (Azure/AWS), ESXi, сетевые ресурсыКонфигурация ОС внутри машины

Vagrant и Terraform не конкурируют - работают на разных уровнях абстракции. Vagrant создаёт VM, Terraform управляет облачной инфраструктурой, Ansible настраивает уже созданные системы agentless. Для домашней лаборатории Vagrant закрывает создание VM, Ansible - их конфигурацию, Terraform подключается при масштабировании в облако или на bare-metal сервер.

Vagrant: домашняя лаборатория для пентеста на VirtualBox​

Vagrant управляет виртуальными машинами через единый Vagrantfile - создаёт, запускает, останавливает, уничтожает. Провайдер по умолчанию - VirtualBox, но поддерживаются libvirt, VMware, Hyper-V.

Предусловия: Vagrant >= 2.3, VirtualBox >= 7.0 (или libvirt), от 16 ГБ RAM на хосте для трёхмашинного стенда (впритык, комфортнее - 32 ГБ), SSD с 100 ГБ свободного места. Виртуализация должна быть включена в BIOS (VT-x/AMD-V).

Типовая AD-лаборатория - контроллер домена + атакующая машина в изолированной подсети:
Ruby:
Vagrant.configure("2") do |config|
  config.vm.define "dc" do |dc|
    dc.vm.box = "gusztavvargadr/windows-server-2022-standard"
    dc.vm.network "private_network", ip: "192.168.56.10"
    dc.vm.provider "virtualbox" do |v| v.memory = 4096 end
  end
  config.vm.define "kali" do |k|
    k.vm.box = "kalilinux/rolling"
    k.vm.network "private_network", ip: "192.168.56.100"
  end
end
Рабочую станцию Windows 10 добавляете аналогичным блоком config.vm.define "ws01" с образом gusztavvargadr/windows-10 и IP 192.168.56.11. Все машины попадают в подсеть 192.168.56.0/24 на host-only адаптере - изолированы от основной сети, но видят друг друга. vagrant up поднимает всё параллельно.

Грабли Vagrant, которые сэкономят часы​

Сетевые конфликты. Если на хосте уже есть host-only адаптер с той же подсетью, Vagrant выбросит A host only network interface...was not found. Проверяйте через VBoxManage list hostonlyifs, удаляйте дубликаты через VBoxManage hostonlyif remove vboxnetN или берите другую подсеть. Я на этом терял минут сорок, пока не запомнил.

WinRM вместо SSH. Vagrant управляет Windows-машинами через WinRM, не SSH. Публичные боксы на Vagrant Cloud обычно содержат преднастроенный WinRM-listener, но при сборке кастомного образа через Packer нужно явно сконфигурировать WinRM-порты. Pentest Partners для Windows-образов на ESXi используют DetectionLab как базу Packer-шаблонов - подход переносится и на VirtualBox.

Вес образов. Windows Server 2022 - около 8 ГБ. Первый vagrant up будет долгим - заварите чай. После скачивания бокс кешируется: vagrant destroy удаляет VM, но не сам образ. При регулярной пересборке экономит десятки минут.

Ansible: развёртывание стенда для пентеста с уязвимыми конфигурациями​

Vagrant создал чистые VM. Ansible превращает их в воспроизводимый стенд для тестирования - с Active Directory, доменными пользователями, намеренными misconfigurations. Каждая misconfiguration открывает конкретный вектор атаки.

Предусловия: Ansible >= 2.14 на управляющей машине (Linux/macOS/WSL), Python 3.x, пакет pywinrm для Windows-целей.

Inventory описывается в INI или YAML: IP-адреса из Vagrantfile, тип подключения (ansible_connection=winrm), Vagrant-учётные данные. Плейбук для контроллера домена с намеренно слабой конфигурацией:
YAML:
- hosts: dc
  tasks:
    - name: Install AD-DS role
      win_feature:
        name: AD-Domain-Services
        state: present
        include_management_tools: yes
    - name: Promote to Domain Controller
      win_domain:
        dns_domain_name: lab.local
        safe_mode_password: "P@ssw0rd123!"
      register: domain_result
    - name: Reboot after DC promotion
      win_reboot:
      when: domain_result.reboot_required | default(true)
    - name: Disable SMB Signing
      win_regedit:
        path: HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
        name: RequireSecuritySignature
        data: 0
Каждая misconfiguration привязана к конкретной технике. Отключённый SMB Signing - открытая дверь для NTLM Relay. Включённый LLMNR (через win_regedit для ключа EnableMulticast в HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient) - для Responder и poisoning. SPN на сервисной учётке с поддержкой RC4 и слабым паролем - для Kerberoasting. Доменный пользователь с паролем Summer2024! - для password spraying. Таски добавляются в тот же плейбук: win_domain_user для пользователей, win_regedit для реестра, win_shell для более хитрой логики.

Идемпотентность и Ansible-роли​

Плейбук можно запускать повторно: если SMB Signing уже отключён - таск пропустится со статусом ok. При отладке это критично - запускаете ansible-playbook site.yml после каждого изменения, Ansible доводит стенд до нужного состояния без побочных эффектов.

При регулярной работе конфигурации выносятся в Ansible-роли: roles/ad-misconfig, roles/dvwa, roles/disable-defender, roles/juice-shop. Стенд собирается как конструктор - в основном плейбуке остаётся roles: [ad-misconfig, dvwa, disable-defender]. Нужен стенд для веб-пентеста - заменяете ad-misconfig на juice-shop. Нужен стенд с работающим EDR для тренировки evasion - убираете disable-defender и добавляете roles/sysmon-config. Провижининг уязвимых сред перестаёт зависеть от памяти и настроения - зависит от git.

Нюанс: модуль win_domain при повторном запуске может попытаться заново промоутить сервер в DC. Решение - добавлять условие when: с проверкой текущей роли сервера через ansible_domain_role или регистрацию результата win_shell: (Get-WmiObject Win32_ComputerSystem).DomainRole. Без этой проверки плейбук на втором прогоне может упасть - проверено на собственном опыте.

Terraform для пентест-лаборатории: масштабирование в облако и ESXi​

Vagrant хорош для локальной работы на ноутбуке, но ограничен ресурсами одной физической машины. Когда нужен стенд из 8-10 машин с несколькими VLAN или отдельный ESXi-сервер в качестве cyber range - пора подключать Terraform.

Terraform работает не внутри ОС, а с инфраструктурой: создаёт VM, сети, firewall-правила через API провайдера. Описание хранится в .tf-файлах на языке HCL.

Предусловия: Terraform >= 1.5, API-credentials провайдера (Azure: az ad sp create-for-rbac --role="Contributor", AWS: IAM-ключи, ESXi: root + SSH).

Два подхода из англоязычных первоисточников:

Azure AD Pentest Lab (logos-red.com). Весь стенд - в четырёх файлах: main.tf (провайдер + генератор случайных паролей), network_security.tf (VPC 10.0.0.0/16 с подсетями для AD-лаборатории и Bastion), VMs.tf (Windows Server DC, два Windows 11 клиента, Kali, Ubuntu с OpenVPN), variables.tf (регион, размер машин, имена). Развёртывание: terraform init -upgrade и terraform apply. Стенд в Azure поднимается за 15-20 минут. Трёхэтапный workflow - write, plan, apply - позволяет проверить изменения до их применения: terraform plan покажет, что будет создано или изменено, без реального действия. Удобно, когда не хочется случайно снести чужую подсеть.

ESXi bare-metal (Pentest Partners). Связка Packer + Terraform + Ansible. Packer собирает золотые образы Windows из ISO (автоматическая установка через unattend.xml, настройка WinRM). Terraform разворачивает из этих образов контроллер домена и рабочие станции на ESXi через community-провайдер josenk/esxi (требует включённого SSH на ESXi-хосте; провайдер протестирован на ESXi 6.5–7.0, на ESXi 8.x возможны проблемы совместимости - загляните в issue tracker на GitHub перед использованием). Ansible доводит до нужного состояния. По данным авторов, Packer собирает образ за 9 минут, Terraform деплоит три VM за пару минут, Ansible-провижининг - ещё 5-10.

Terraform хранит состояние в state-файле terraform.tfstate. Этот файл содержит все параметры и пароли в открытом виде - прямое попадание под T1552.001 (Credentials In Files, Credential Access). Не коммитьте .tfstate в публичные репозитории. Для командной работы - remote backend (S3, Azure Blob) с шифрованием и terraform state для управления.

CI/CD для пентест окружения: пересборка по коммиту​

Финальный уровень автоматизации пентест-лаборатории - привязка пересборки к git-событиям. Пушнули изменение в плейбук - пайплайн уничтожает старый стенд и разворачивает новый.

Для домашней лаборатории достаточно Makefile с тремя целями: make up (поднять), make provision (переконфигурировать без пересоздания VM), make nuke (уничтожить и пересоздать с нуля - vagrant destroy -f && vagrant up && ansible-playbook site.yml). Продвинутый вариант - GitLab CI runner на хост-машине с правами на VirtualBox, срабатывающий при пуше в ветку lab/ad-kerberos.

Главная ценность - не разовая экономия времени, а возможность гарантированно воссоздать среду спустя месяцы. Разделение ответственности между инструментами (Terraform = spinning up/down, Ansible = configuring/running) позволяет привязать сканы к конкретным конфигурациям через git-историю: коммит a1b2c3f = стенд с Kerberoasting-уязвимостью, коммит d4e5f6g = стенд с relay-уязвимостью. Воспроизводимость на уровне хеша коммита - попробуйте добиться того же со снапшотами.

Тот же heapspray.io показывает Terraform-конфигурацию для SpiderFoot в контейнере - recon-инструмент поднимается за секунду вместо минут. Для веб-приложений (DVWA, Juice Shop) контейнеры работают отлично, но для AD-лаборатории - нет: Windows в Docker не запустить.

Типичные грабли при автоматическом развёртывании уязвимых машин​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

, написанная под Server 2019, может не работать на Server 2022 из-за изменённых ключей реестра или модулей PowerShell. Версия ОС - обязательный параметр в vars/ каждой роли. Без этого плейбук молча отработает без ошибок, но misconfiguration не применится. Самое неприятное - вы об этом узнаете только когда атака не сработает и непонятно, то ли техника нерабочая, то ли стенд криво собран.

Поднять воспроизводимый стенд - задача на один вечер, если использовать готовые боксы и минимальный плейбук. Основное время уйдёт не на IaC, а на понимание, какие именно misconfigurations нужны для конкретного сценария. Плейбук - это зафиксированное знание: что ломать, как это выглядит в инфраструктуре и почему именно эта конфигурация делает атаку возможной.

Часть пентестеров, с которыми я общаюсь, до сих пор собирают лаборатории вручную. Аргумент - «руками быстрее». Верно ровно до второй пересборки: ручная настройка AD быстрее первый раз, потому что не нужно разбираться с Ansible. На третий раз IaC отбивается полностью. Через месяц вы не вспомните, какой параметр реестра меняли для отключения LDAP Signing, а плейбук помнит. У меня в git лежат конфигурации стендов двухлетней давности - любую поднимаю за 15 минут. Попробуйте провернуть то же со снапшотами, которые удалили при очистке диска.

IaC-подход к лабораторной инфраструктуре - такой же навык пентестера, как владение Burp или Impacket, просто пока это мало кто признаёт. Если IaC-часть уже знакома и хочется не строить, а ломать готовые стенды - на HackerLab.pro задачи развёрнуты на контролируемой инфраструктуре без возни с провижинингом.
Полезно

Комментарии

0

Ещё по теме