Анализ вредоносного трафика: от стенда в VirtualBox до Suricata-правила для Cobalt Strike Beacon

По данным IBM X-Force Threat Intelligence Index 2025, infostealers — программы для кражи учётных данных — составили 32% всего обнаруженного вредоносного ПО в 2024 году. Это самый распространённый тип малвари, обогнавший даже ransomware. Каждый из них генерирует C2-трафик (Command and Control — канал связи между заражённой машиной и управляющим сервером атакующего). Cobalt Strike Beacon, коммерческий инструмент для пентеста, давно стал стандартом де-факто у реальных атакующих, и его C2-сессии маскируются под обычные HTTP-запросы к веб-серверу. Распознать их можно — но нужна контролируемая среда, где каждый байт трафика под наблюдением. Дальше — пошаговая сборка такого стенда на VirtualBox, разбор конкретных паттернов Beacon в Wireshark и написание первого Suricata-правила для их обнаружения.
Место C2-трафика в цепочке атаки
Перед настройкой стенда стоит разобраться, что именно мы собираемся ловить и почему это стоит усилий. MITRE ATT&CK — открытая база тактик и техник атак. T-коды вроде T1071.001 — её идентификаторы, по которым аналитики ссылаются на конкретные приёмы атакующих. Command and Control (управление заражённой машиной) описывается как отдельная тактика с десятками техник. Для нашей задачи ключевые:
| Техника MITRE ATT&CK | T-код | Что делает атакующий |
|---|---|---|
| Web Protocols | T1071.001 | Использует HTTP/HTTPS для управления заражённой машиной |
| Symmetric Cryptography | T1573.001 | Шифрует данные внутри C2-канала |
| Protocol Impersonation | T1001.003 | Маскирует C2 под легитимный веб-сервис |
| Ingress Tool Transfer | T1105 | Загружает дополнительные инструменты через C2-канал |
| Network Sniffing | T1040 | Перехват трафика в сети — наша задача, но с позиции защитника |
Бизнес-логика атаки проста: после первоначального проникновения (initial access) атакующий закрепляется в системе и поднимает C2-канал. Через него проходит всё — команды, загрузка дополнительных инструментов, выкачивание данных (exfiltration). C2-канал — артерия операции. Обнаружить и заблокировать его — значит оставить атакующего без контроля. Поэтому написание правил для IDS (Intrusion Detection System — система обнаружения вторжений) — повседневная задача SOC-аналитика (Security Operations Center — центр мониторинга безопасности). А чтобы такие правила тестировать и отлаживать, нужна изолированная среда.
Изолированная сеть VirtualBox для анализа малвари
Требования к окружению
Прежде чем что-то ставить — конкретные цифры по железу:
| Параметр | Минимум | Рекомендуется |
|---|---|---|
| RAM хоста | 8 ГБ (по 2 ГБ на каждую VM + хост) | 16 ГБ |
| CPU | 4 ядра с поддержкой VT-x / AMD-V | 6+ ядер |
| Свободное место на диске | 60 ГБ | 100+ ГБ на SSD |
| ОС хоста | Windows 10/11, Ubuntu 22.04+, macOS | Linux предпочтительнее для Suricata |
| VirtualBox | 7.0+ (активно поддерживается, Oracle) | Последняя стабильная версия |
| Интернет | Только для скачивания ISO-образов | После сборки стенда не нужен |
Для стенда нужны две виртуальные машины:
- Monitoring VM — Ubuntu Server 22.04 или Kali Linux. Здесь работают Wireshark (анализатор пакетов), Suricata (IDS-движок) и INetSim (симулятор интернет-сервисов — имитирует HTTP/DNS/SMTP-ответы для малвари).
- Target VM — Windows 10. Машина, на которой запускается семпл вредоноса или генератор тестового трафика.
Собираем сеть: пошаговая настройка
Ключевой принцип — полная изоляция. Ни один пакет вредоносного трафика не должен выйти в реальную сеть. VirtualBox для этого даёт режим Internal Network — виртуальный коммутатор, который существует только между VM и не имеет физического выхода наружу.
Делай раз. Откройте настройки каждой VM в VirtualBox → раздел «Сеть» → Адаптер 1. Тип подключения — «Внутренняя сеть» (Internal Network). В поле «Имя» введите malnet — имя произвольное, главное чтобы совпадало на обеих VM. VirtualBox создаст виртуальный коммутатор, связывающий только эти две машины. Никакого NAT (трансляции адресов), никакого моста в физическую сеть хоста. Как проверить: после запуска VM увидите сетевой интерфейс (обычно enp0s3 в Linux, Ethernet-адаптер в Windows), но IP-адрес по DHCP не получите — DHCP-сервера во Internal Network по умолчанию нет.
Делай два. Для удобства управления добавьте Адаптер 2 → тип «Виртуальный адаптер хоста» (Host-Only Adapter). Через него можно подключаться к VM по SSH с хост-машины, не нарушая изоляцию сети malnet. VM получают IP в диапазоне 192.168.56.0/24 на втором адаптере автоматически (Host-Only сеть имеет встроенный DHCP). Host-Only адаптер тоже не даёт выход в интернет — он связывает только хост и VM.
Делай три. Назначьте статические IP-адреса на интерфейсе malnet. На Ubuntu создайте файл /etc/netplan/01-malnet.yaml, укажите адрес 10.0.0.1/24 для интерфейса enp0s3, затем примените конфигурацию командой sudo netplan apply. На Windows Target VM откройте «Параметры адаптера» → Свойства → IPv4: IP — 10.0.0.2, маска — 255.255.255.0, шлюз — 10.0.0.1, DNS-сервер — 10.0.0.1. Проверка: ping 10.0.0.1 с Target VM должен проходить. Не проходит — проверьте, что обе VM в сети с одинаковым именем malnet и что файрвол на Ubuntu не блокирует ICMP.
Зачем шлюз и DNS указывают на Monitoring VM? Если на Monitoring VM поднять INetSim (sudo apt install inetsim), малварь на Target VM будет «думать», что у неё есть интернет. INetSim отвечает на DNS-запросы любыми IP из заданного диапазона, эмулирует HTTP/HTTPS-серверы и даже SMTP. Весь этот трафик проходит через сетевой интерфейс Monitoring VM — Wireshark и Suricata его видят и анализируют.
Что сделать до запуска семплов
Три вещи, без которых стенд бесполезен:
- Снимок (snapshot) обеих VM. Меню VirtualBox → Снимки → «Сделать снимок» после полной настройки сети, до запуска любого вредоноса. Откат к чистому состоянию — секунды. Без снимка после каждого запуска малвари придётся переустанавливать Windows.
- Отключите общие папки и буфер обмена между хостом и VM. Настройки VM → Общие → Дополнительно → Общий буфер обмена: «Выключено», Drag’n’Drop: «Выключено». Это не паранойя — некоторые семплы умеют использовать shared folders как вектор выхода за пределы VM.
- Убедитесь, что VirtualBox Guest Additions НЕ установлены на Target VM. Часть вредоносов проверяет наличие Guest Additions, VMware Tools и других артефактов виртуализации как признак песочницы — и меняет поведение или вообще не запускается. MITRE ATT&CK классифицирует это как System Checks (T1497.001, тактики Defense Evasion / Discovery).
Cobalt Strike Beacon: паттерны C2-трафика
Cobalt Strike — коммерческий фреймворк для red team (команд имитации атак), но его утёкшие версии активно используются в реальных атаках: от массовых ransomware-кампаний до целевых APT-операций. По данным CrowdStrike Global Threat Report 2025, 86% зафиксированных атак имеют финансовую мотивацию (eCrime), и значительная часть из них использует именно Cobalt Strike или его производные для C2.
Beacon — агент, который ставится на скомпрометированную машину и периодически «отзванивается» на TeamServer (управляющий сервер атакующего). Вот что характерно для трафика в HTTP-режиме по умолчанию — без кастомного malleable C2 profile (конфигурационного файла, меняющего внешний вид трафика):
GET-запросы на check-in. Beacon периодически шлёт GET-запросы за новыми командами. URI по умолчанию — пути вроде /pixel, /__utm.gif, /activity. В параметрах или cookie — зашифрованные метаданные о заражённой машине.
POST-запросы на /submit.php. Результаты выполненных команд (скриншоты, содержимое файлов, вывод консоли) уходят POST-запросом на /submit.php с типом содержимого application/octet-stream. Один из самых узнаваемых паттернов дефолтного профиля — и главная цель нашего Suricata-правила.
Интервалы (sleep + jitter). Beacon «спит» между запросами. По умолчанию — 60 секунд с добавлением случайного отклонения (jitter). Если в трафике видны HTTP-запросы к одному хосту с интервалом ~55-65 секунд — это сильный индикатор beacon-активности. Обычный пользователь так не ходит.
Cookie-based метаданные. Идентификатор сессии и зашифрованные данные часто передаются в заголовке Cookie, что делает запрос внешне похожим на обычное посещение веб-сайта.
Согласно патенту Palo Alto Networks (WO2024025705A1) по эвристическому обнаружению Cobalt Strike Beacon HTTP C2, детекция строится на мониторинге HTTP-трафика и анализе комбинации атрибутов: URI, HTTP-заголовков, размеров ответов и периодичности запросов. Вывод: дефолтные паттерны достаточно стабильны и специфичны для сигнатурных правил.
Malleable C2 profile позволяет оператору Cobalt Strike полностью переписать внешний вид трафика: сменить URI, заголовки, User-Agent, формат данных. Опытные атакующие маскируют C2-трафик под обращения к Google Analytics, Microsoft CDN или любому другому легитимному сервису — техника Protocol or Service Impersonation (T1001.003). Правило, которое ловит дефолтный /submit.php, бесполезно против кастомного профиля. Но дефолтные паттерны встречаются чаще, чем хотелось бы атакующим: далеко не все тратят время на кастомизацию, особенно в массовых кампаниях.
Перехват C2-трафика в Wireshark: анализ Cobalt Strike
Где взять трафик для практики
Для первых экспериментов запускать настоящую малварь не нужно. Три варианта, от простого к сложному:
- Публичные PCAP-файлы (файлы с записанным сетевым трафиком в формате pcap/pcapng). Ресурс malware-traffic-analysis.net публикует разобранные кейсы с реальным C2-трафиком, включая Cobalt Strike. Скачиваете PCAP, открываете в Wireshark — анализируете без риска.
- Имитация трафика утилитой
curlс Target VM. Не полноценный Beacon, но для проверки правил Suricata хватит. Командаcurl -X POST http://10.0.0.1/submit.php -H "Content-Type: application/octet-stream" -d "testdata"сгенерирует запрос с нужными характеристиками. - Запуск Cobalt Strike на стенде (только при наличии легальной лицензии или в учебной среде) — даёт полностью реалистичный трафик со всеми характерными паттернами.
Фильтры и индикаторы в Wireshark
Запустите Wireshark на Monitoring VM: sudo wireshark (или sudo tshark -i enp0s3 -w capture.pcap для консольного режима без GUI). Захватывайте трафик на интерфейсе enp0s3 — том, который подключён к сети malnet.
Для фильтрации характерных паттернов Cobalt Strike Beacon используйте display filters — фильтры отображения, которые применяются к уже захваченному трафику:
http.request.uri contains "/submit.php"
http.request.uri contains "/__utm.gif"
http.request.method == "POST" && http.content_type contains "octet-stream"
http.cookie && http.request.uri contains "/pixel"
Первый фильтр покажет POST-запросы на /submit.php — отправку результатов команд. Второй — GET-запросы на /__utm.gif, характерные для check-in. Третий ловит любые POST с бинарным содержимым. Четвёртый — запросы с cookie к URI, типичному для beacon check-in.
Выбрав подозрительный пакет, смотрите на три вещи:
- HTTP-заголовки (средняя панель, раздел Hypertext Transfer Protocol): User-Agent (дефолтный Beacon часто отдаёт строки Internet Explorer, даже если реальный IE давно не стоит на машине), Cookie (может содержать зашифрованные метаданные сессии длиной 60-100 символов).
- Размер тела ответа: GET-ответы от TeamServer с командами — обычно несколько сотен байт. Пустой ответ (0 байт или короткий) — оператор не отправил новых команд.
- Периодичность: Statistics → I/O Graphs, график запросов к подозрительному IP. Регулярные «всплески» с интервалом ~60 секунд — индикатор beacon-активности, который нельзя объяснить обычным пользовательским поведением.
Написание правил Suricata для обнаружения C2
Настройка IDS Suricata на Monitoring VM
Suricata — open-source IDS/IPS (активно поддерживается OISF, текущая стабильная ветка 7.x). Анализирует трафик в реальном времени и срабатывает на правила-сигнатуры. Синтаксис правил совместим со Snort — если работали с одним, со вторым разберётесь быстро.
Установка на Ubuntu: sudo apt install suricata. Конфигурационный файл — /etc/suricata/suricata.yaml. Минимальные изменения перед стартом:
- В секции
varsзадайтеHOME_NET: "[10.0.0.0/24]"— диапазон нашей лабораторной сети. EXTERNAL_NET: "any"— всё, что не HOME_NET, считаем внешним.- В секции
rule-filesпроверьте, что подключён файлlocal.rules— туда пойдут наши правила.
Пользовательские правила живут в файле /etc/suricata/rules/local.rules. Если файла нет — создайте: sudo touch /etc/suricata/rules/local.rules.
Правило для Cobalt Strike Beacon: разбор по элементам
Каждое правило Suricata состоит из заголовка (действие, протокол, адреса, порты) и набора опций в скобках (конкретные паттерны для проверки). Вот правило, которое детектирует POST-запрос на /submit.php с типом содержимого application/octet-stream — характерный паттерн дефолтного Beacon:
alert http $HOME_NET any -> $EXTERNAL_NET any ( \
msg:"POSSIBLE CS Beacon POST /submit.php"; \
flow:established,to_server; \
http.method; content:"POST"; \
http.uri; content:"/submit.php"; \
http.content_type; content:"application/octet-stream"; \
classtype:trojan-activity; sid:1000001; rev:1; )
Разберём каждый элемент — без этого писать собственные правила не получится:
alert http— действиеalert(записать в лог, не блокировать) для HTTP-трафика. Для IPS-режима можно заменить наdrop.$HOME_NET any -> $EXTERNAL_NET any— от машин нашей сети (любой порт) к внешним адресам (любой порт). Направление стрелки важно: мы ищем исходящий C2-трафик.flow:established,to_server— проверять только пакеты в рамках установленного TCP-соединения, направленные к серверу. Отсекает SYN-сканирование и ответы сервера.http.method; content:"POST"— HTTP-метод запроса должен быть POST. Ключевое словоhttp.methodговорит Suricata, чтоcontentнужно искать именно в поле метода, а не во всём пакете.http.uri; content:"/submit.php"— URI запроса содержит/submit.php.http.uriограничивает область поиска.http.content_type; content:"application/octet-stream"— заголовок Content-Type указывает на бинарные данные. Отсекает обычные POST-формы сtext/htmlилиapplication/json.sid:1000001— уникальный идентификатор правила. Для пользовательских правил — диапазон от 1 000 000.classtype:trojan-activity— классификация угрозы для приоритизации алертов.
Тестируем правило: делай раз, делай два, делай три
Делай раз. Сохраните правило в /etc/suricata/rules/local.rules. Проверьте синтаксис: sudo suricata -T -c /etc/suricata/suricata.yaml. Ожидаемый вывод — строка Configuration provided was successfully loaded. Exiting. Если ошибки — Suricata укажет номер строки и тип проблемы. Частая ошибка: забытая точка с запятой между опциями.
Делай два. Запустите Suricata на интерфейсе malnet: sudo suricata -c /etc/suricata/suricata.yaml -i enp0s3. Suricata начнёт слушать трафик и проверять его против загруженных правил. В терминале появятся строки инициализации — дождитесь сообщения о загрузке правил (должно быть «1 rule loaded» или аналогичное).
Делай три. С Target VM отправьте тестовый запрос: curl -X POST http://10.0.0.1/submit.php -H "Content-Type: application/octet-stream" -d "testdata". Проверяем: tail -f /var/log/suricata/fast.log. Должна появиться строка с текстом POSSIBLE CS Beacon POST /submit.php, меткой времени и IP-адресами. Если строки нет — убедитесь, что Suricata слушает правильный интерфейс (enp0s3, а не lo), что правило прошло проверку синтаксиса и что local.rules подключён в suricata.yaml.
Ограничения техники: сигнатуры vs поведенческий анализ
Написанное правило — точечный детект для дефолтного профиля Cobalt Strike. Понимание его границ не менее важно, чем само правило:
| Сценарий | Почему правило не сработает | Альтернативный подход |
|---|---|---|
| Malleable C2 profile изменён | URI, заголовки, Content-Type — другие | JA3/JA3S-хеши TLS-рукопожатия (уникальны для конкретных C2-клиентов) |
| HTTPS без TLS-инспекции | Suricata не видит содержимое шифрованного канала (T1573.001) | Анализ метаданных: размеры пакетов, интервалы, JA3 |
| DNS-based C2 | Трафик идёт через DNS-запросы, а не HTTP | Отдельные правила для dns-протокола в Suricata, анализ длины DNS-запросов |
| Domain Fronting (T1090.004) | C2-трафик прячется за легитимным CDN | Мониторинг несоответствий SNI и Host-заголовка |
| Нестандартные порты | Beacon работает на порту 8443 или 8080 | Расширить порты в правиле или использовать any с дополнительными фильтрами |
В реальной корпоративной сети правило с паттерном /submit.php + octet-stream будет давать ложные срабатывания (false positives). Легитимные приложения тоже используют POST с бинарными данными. В проде такое правило работает в связке с другими индикаторами: репутация IP-адреса назначения, частота запросов, JA3-хеш TLS-клиента. Одиночная сигнатура — не приговор, а точка входа в расследование.
Против кастомных профилей лучше работает поведенческий анализ: выявление периодичности запросов, корреляция размеров ответов, анализ энтропии данных в cookie. Это задача для Zeek (бывший Bro — фреймворк анализа сетевого трафика) или ML-моделей, и она выходит за рамки сигнатурного подхода Suricata. Но начинать разумно с сигнатур — они дают конкретный, проверяемый результат и формируют понимание того, что именно искать.
| Подход | Преимущества | Ограничения | Когда использовать | Когда не использовать |
|---|---|---|---|---|
| Сигнатуры (Suricata/Snort) | Низкий false positive при точной сигнатуре, работа в реальном времени | Не ловит кастомные профили, требует обновления правил | Дефолтные C2, массовые кампании, известные IoC | APT с кастомным C2, zero-day малварь |
| JA3/JA3S-хеши | Работает с HTTPS без расшифровки, специфичны для C2-клиентов | Меняются при обновлении C2-фреймворка | HTTPS C2-каналы, где сигнатуры слепы | Среды с большим разнообразием TLS-клиентов |
| Поведенческий анализ (Zeek, ML) | Ловит неизвестные C2-паттерны по поведению | Высокий false positive, требует тюнинга | APT, кастомные RAT, продвинутые атакующие | Простые случаи с известными сигнатурами |
Чеклист: от чистой системы до рабочего детекта
- Установить VirtualBox 7.0+, создать две VM: Ubuntu Server 22.04 + Windows 10
- Адаптер 1 обеих VM — Internal Network, имя
malnet - Адаптер 2 (опционально) — Host-Only для SSH-управления
- Статические IP: Monitoring VM
10.0.0.1/24, Target VM10.0.0.2/24 - На Target VM: шлюз
10.0.0.1, DNS10.0.0.1 - Установить INetSim на Monitoring VM:
sudo apt install inetsim - Сделать snapshot обеих VM
- Отключить Guest Additions, shared folders, clipboard на Target VM
- Установить Wireshark:
sudo apt install wireshark - Установить Suricata:
sudo apt install suricata - В
/etc/suricata/suricata.yaml:HOME_NET: "[10.0.0.0/24]" - Написать правило в
/etc/suricata/rules/local.rules - Проверить синтаксис:
sudo suricata -T -c /etc/suricata/suricata.yaml - Запустить Suricata:
sudo suricata -c /etc/suricata/suricata.yaml -i enp0s3 - Сгенерировать тестовый трафик с Target VM через
curl - Проверить
/var/log/suricata/fast.log— алерт должен появиться
Этот чеклист можно передать коллеге — каждый шаг самодостаточен и проверяем.
Сигнатурный подход к обнаружению Command and Control трафика часто критикуют за негибкость — и критика справедлива, когда речь идёт о продвинутых атакующих с кастомными malleable-профилями. Но на практике бОльшая часть инцидентов, которые проходили через мои руки, ловились именно на дефолтах. Не потому что атакующие глупые — просто в массовых кампаниях никто не тратит время на кастомизацию каждого импланта. Одно правило в Suricata не заменит полноценный стек детекции, но даёт конкретную точку входа: алерт, от которого начинается расследование. А без алерта нет расследования — есть 12 ГБ трафика и надежда что-то найти вручную. Начинать стоит с малого: один стенд, один PCAP с malware-traffic-analysis.net, одно правило. Через десяток таких разборов начинаешь видеть паттерны без подсказок, по структуре трафика. Этот навык не вырабатывается чтением — только практикой. На IB Basics учат не «что такое CIA-triad», а как делать первые задачи в SOC и blue team — ту самую базу, от которой потом строится всё остальное.
Эту тему и смежные навыки разбирают на практике в курсе «Аналитик SOC» Codeby Academy.