Строю таймлайн инцидента в Wireshark и Zeek за 20 минут: разбор дампа с бьюконом C2

На последнем дежурстве SIEM поднял алерт: рабочая станция из бухгалтерского VLAN каждые 62 секунды отправляла HTTPS-запросы на IP в голландском датацентре. Выгрузили PCAP за четыре часа — 1.2 ГБ сырого трафика. Задача: собрать таймлайн инцидента, понять — C2-бьюкон или нет, и передать L3-аналитику хронологию с артефактами. Двадцать минут на триаж — стандартное окно, пока incident manager решает, изолировать ли хост. Ниже — ровно тот процесс, который я прогоняю каждый раз, когда на стол падает подозрительный дамп.
Зачем строить таймлайн инцидента по сетевому трафику
Бьюкон (beacon) — периодические обращения вредоноса к серверу управления. Сервер называют C2 (Command and Control). Через этот канал атакующий отдаёт команды импланту: скачать дополнительный модуль, переместиться на соседний хост, собрать и выгрузить данные. Пока бьюкон жив — злоумышленник контролирует сеть. По данным CrowdStrike Global Threat Report 2025, среднее время lateral movement после первичного доступа — 62 минуты, рекорд — 51 секунда. Каждая минута без ответа работает на атакующего.
Таймлайн — хронологическая карта инцидента: «в 14:23 хост разрезолвил домен, в 14:24 установил TLS-соединение, в 14:25 начал периодические POST-запросы каждые 60 секунд». Без таймлайна расследование превращается в хаотичный поиск по пакетам. С ним — точная последовательность событий, которая отвечает на три вопроса: когда началась компрометация, какой протокол использован для C2, было ли перемещение внутри сети.
Wireshark (GUI-анализатор пакетов) и Zeek (бывший Bro — фреймворк сетевого мониторинга) закрывают разные задачи. Wireshark позволяет руками разобрать конкретную сессию до байта: вскрыть содержимое HTTP-запроса, проследить TCP-поток, извлечь файл из трафика. Zeek превращает сырые пакеты в структурированные логи: conn.log (каждое соединение с метаданными), dns.log (DNS-запросы), ssl.log (TLS-хендшейки), http.log (HTTP-транзакции), files.log (файлы, обнаруженные в трафике). Как описывает Basilisk Security в руководстве по network forensics, «Zeek records behaviour, so even when payloads are encrypted you still see the connection metadata, the DNS lookups, the TLS certificate details and the timing — which together reveal a great deal about intent». Zeek отвечает на вопрос «кто с кем, когда и сколько», Wireshark — «что конкретно передавали». Вместе они дают полную картину для построения таймлайна атаки.
Предпосылки: на машине аналитика установлены Wireshark 4.x и Zeek 7+ (ставится через apt install zeek на Debian/Ubuntu или через Homebrew на macOS). Все команды ниже — в терминале Linux или macOS. Дамп лежит в файле incident.pcap в текущей директории.
Минута 0–5: первичный осмотр дампа трафика C2
Первые пять минут — ориентировка. Прежде чем нырять в пакеты, нужно понять объём и структуру трафика. Три команды дают картину целиком.
Статистика и иерархия протоколов
Запускаем capinfos incident.pcap — команда выводит длительность захвата, количество пакетов, средний размер пакета и скорость трафика. Если дамп охватывает 4 часа и содержит 500 тысяч пакетов — средняя нагрузка, Wireshark справится. Если 4 часа и 50 миллионов — Wireshark начнёт задыхаться, работаем через tshark и Zeek.
Дальше — иерархия протоколов: tshark -r incident.pcap -q -z io,phs (tshark — консольная версия Wireshark) выводит дерево протоколов с процентами от общего трафика. Ожидаемый результат: TCP занимает 80–90%, внутри — HTTP, TLS, DNS. Аномалия — если DNS занимает непропорционально много (возможно DNS-туннелирование) или присутствует нестандартный порт с большим количеством пакетов.
Top talkers — определяем жертву и подозрительные IP
Команда tshark -r incident.pcap -q -z endpoints,ip покажет IP-адреса, отсортированные по объёму трафика. Цель — выделить внутренний IP жертвы и внешние адреса с наибольшим обменом данными.
В Wireshark тот же результат даёт меню Statistics → Conversations → вкладка IPv4, сортировка по столбцу Bytes. Визуально удобнее, но для автоматизации tshark лучше.
На что смотрим: IP-адреса, которых не должно быть в трафике рабочей станции бухгалтера. Проверяем ASN (автономную систему — по сути, «кому принадлежит этот блок адресов») подозрительного IP: whois 185.220.101.34 | grep -i origin. Крупные CDN-провайдеры (Cloudflare AS13335, Akamai, Fastly) — скорее ложное срабатывание. Малоизвестные хостинги, особенно в юрисдикциях с bulletproof-хостингом, — красный флаг.
К пятой минуте есть: длительность дампа, доминирующие протоколы, IP жертвы (допустим, 10.7.11.101) и подозрительный внешний адрес (допустим, 185.220.101.34).
Минута 5–10: Zeek conn.log — скелет таймлайна инцидента
Генерируем структурированные логи: zeek -C -r incident.pcap local. Флаг -C игнорирует ошибки контрольных сумм (в реальных дампах они встречаются часто — не пугайтесь), а local загружает detection-скрипты, без которых notice.log будет пустым. Zeek создаст набор файлов в текущей директории: conn.log, dns.log, ssl.log, http.log, files.log, notice.log. Если файлы с расширением .log появились — Zeek отработал.
conn.log — главный лог для анализа инцидента. Каждая строка — одно сетевое соединение. Ключевые поля: временная метка (ts), IP источника (id.orig_h) и назначения (id.resp_h), порт назначения (id.resp_p), протокол (proto), длительность (duration), отправленные и полученные байты (orig_bytes, resp_bytes), состояние соединения (conn_state), уникальный идентификатор (uid). uid — ключ, по которому Zeek связывает записи между разными логами: одно и то же соединение можно проследить из conn.log в ssl.log и http.log.
Фильтрация conn.log и dns.log
Фильтруем conn.log по подозрительному IP и смотрим, какой домен за ним стоит:
# Все соединения с подозрительным IP, отсортированные по времени
cat conn.log | zeek-cut ts id.orig_h id.resp_h id.resp_p duration orig_bytes resp_bytes | grep "185.220.101.34" | sort
# DNS-запросы, которые резолвились в этот IP
cat dns.log | zeek-cut ts query answers | grep "185.220.101.34"
# notice.log — находки самого Zeek (self-signed certs, подозрительные протоколы)
cat notice.log | zeek-cut ts note msg
zeek-cut (в старых версиях — bro-cut) извлекает нужные столбцы из Zeek-логов. Работает как Unix-утилита cut, но понимает формат Zeek-заголовков.
Ожидаемый вывод первой команды: десятки строк с одинаковым IP назначения, похожими значениями длительности (1–3 секунды) и байт (200–400 отправлено, 100–200 получено). Видите такую картину — паттерн бьюкона уже проступает.
Вторая команда покажет домен вроде update-service-cdn.top или xk3j9f2.example.com — высокоэнтропийное (случайно выглядящее) имя с нестандартным TLD. Легитимные сервисы используют узнаваемые домены. Вредоносная инфраструктура часто генерирует имена алгоритмически — техника DGA (Domain Generation Algorithm).
Третья команда проверяет notice.log — Zeek самостоятельно фиксирует аномалии: self-signed сертификаты, необычные SSL-версии, подозрительные HTTP-методы. Иногда одна строка в notice.log экономит десять минут ручного разбора.
К десятой минуте есть: список всех соединений жертвы с подозрительным IP (с временными метками и объёмами), домен, резолвящийся в этот IP, замечания Zeek из notice.log.
Минута 10–15: выявление beaconing в трафике
Ключевой этап. Здесь мы доказываем, что трафик — именно C2-бьюкон, а не легитимный heartbeat (периодический сигнал «я жив» от нормального приложения: антивируса, мессенджера, NTP-клиента).
Считаем периодичность запросов beacon и jitter
Главный признак бьюкона — стабильная периодичность с низким jitter (разброс интервалов между соединениями). C2-фреймворки позволяют задать интервал обращения (скажем, 60 секунд) и jitter (скажем, 10%). Имплант будет стучаться каждые 54–66 секунд. Легитимные приложения тоже делают heartbeat, но их интервалы менее стабильны, объём данных предсказуем по назначению, а домены — общеизвестны.
Практический критерий: стандартное отклонение интервалов меньше 30% от среднего при количестве соединений больше пяти — стоит копать глубже.
Берём временные метки из отфильтрованного conn.log и считаем:
import statistics
timestamps = [1689091263.5, 1689091323.8, 1689091384.1, 1689091444.3,
1689091504.9, 1689091565.2, 1689091625.7] # из conn.log
intervals = [timestamps[i+1] - timestamps[i] for i in range(len(timestamps)-1)]
avg = statistics.mean(intervals)
stdev = statistics.stdev(intervals)
jitter_pct = (stdev / avg) * 100
print(f"Средний интервал: {avg:.1f}s, jitter: {jitter_pct:.1f}%")
# Вывод: Средний интервал: 60.4s, jitter: 1.7% — LIKELY BEACONING
Средний интервал 60.4 секунды при jitter 1.7% — классический бьюкон. Для сравнения: NTP-клиент опрашивает сервер раз в 1024 секунды с jitter менее 1% (стабильно, но масштаб другой), браузерное расширение проверяет обновления с jitter 50–80% (хаотично), мессенджер поддерживает keep-alive с jitter 15–25%.
Тот же анализ можно провести через RITA (Real Intelligence Threat Analytics) — инструмент автоматически выявляет beaconing в Zeek-логах, рассчитывая score периодичности. Но для двадцатиминутного триажа Python-скрипт или даже ручной подсчёт по пяти временным меткам — хватит.
JA3-отпечатки TLS и анализ сетевых артефактов C2
JA3 — хеш-отпечаток TLS-клиента. Вычисляется из параметров TLS-хендшейка: версия TLS, поддерживаемые шифронаборы, расширения. У каждого приложения свой JA3: у Chrome один, у Firefox другой, у Cobalt Strike Beacon — третий. Если C2 идёт по HTTPS, JA3 помогает идентифицировать клиент без расшифровки трафика.
Смотрим ssl.log: cat ssl.log | zeek-cut ts id.orig_h id.resp_h ja3 server_name issuer subject. На что обращать внимание:
Редкий JA3-хеш, повторяющийся десятки раз. Если на машине нет приложения с таким отпечатком — вероятен C2. Публичные базы JA3 (ja3er.com, sslbl.abuse.ch) позволяют проверить хеш.
Self-signed сертификат. Поле issuer совпадает с subject — типично для C2, нетипично для продакшн-сервисов.
Свежий сертификат Let’s Encrypt на подозрительном домене. Атакующие получают бесплатные сертификаты для C2-серверов, чтобы трафик выглядел легитимно.
Server Name Indication (SNI), не совпадающий с доменом в DNS. Имплант может указывать один SNI в TLS Client Hello, а резолвить другой домен — техника domain fronting.
Дополнительно проверяем dns.log на признаки DNS-туннелирования. В терминах MITRE ATT&CK (открытая база тактик и техник атак — по сути, единый язык для описания действий злоумышленника; T-коды вроде T1071.004 — её идентификаторы) это техника T1071.004 (DNS, тактика Command and Control): использование DNS-протокола как канала управления. Команда cat dns.log | zeek-cut ts query qtype_name | awk 'length($2) > 40' покажет запросы с аномально длинными доменными именами. Здесь $2 — поле query, потому что порядок вывода zeek-cut соответствует порядку аргументов: ts=$1, query=$2, qtype_name=$3. Длинные имена — признак данных, закодированных в поддомене. Массовые TXT-запросы к одному домену — ещё один индикатор.
К пятнадцатой минуте есть: численное доказательство периодичности (средний интервал + jitter), JA3-отпечаток TLS-клиента, характеристики сертификата и DNS-артефакты.
Минута 15–20: собираем таймлайн атаки и маппим на MITRE ATT&CK
Детали из Wireshark
Подозрительные соединения идентифицированы — открываем дамп в Wireshark для точечного анализа. Display filter ip.addr == 185.220.101.34 && tls.handshake.type == 1 покажет только Client Hello пакеты к подозрительному IP. Каждый такой пакет — начало нового бьюкон-цикла. Правой кнопкой по пакету → Follow → TCP Stream — весь обмен данными в рамках одного соединения.
Для HTTP-трафика (если C2 не использует TLS): display filter ip.addr == 185.220.101.34 && http.request покажет все запросы. Обращаем внимание на URI-паттерн: одинаковые POST на /api/update?id=A3F2 с фиксированным User-Agent — кастомный протокол C2, замаскированный под легитимный API. Это техника T1071.001 (Web Protocols).
Если в трафике были загрузки файлов, извлекаем их через Wireshark: File → Export Objects → HTTP. Хеши извлечённых файлов проверяем sha256sum и сверяем с VirusTotal. Загрузка дополнительных инструментов на скомпрометированный хост — техника T1105 (Ingress Tool Transfer).
Для контекста: в реальном разборе дампа с трояном Formbook (по материалам SecurityVision на Habr) аналогичный процесс вскрыл цепочку компрометации через эксплуатацию CVE-2017-11882 — уязвимость повреждения памяти в Microsoft Office. CVSS 7.8 HIGH; вектор AV:L (атака локальная), AC:L (низкая сложность), PR:N (привилегии не нужны), UI:R (требуется действие пользователя — открыть RTF-файл); CWE-119 (ошибка работы с памятью). CVE находится в каталоге CISA KEV — это список уязвимостей, которые УЖЕ эксплуатируются в реальных атаках, включая ransomware-кампании. EPSS 0.9994 — оценка вероятности (от 0 до 1), что уязвимость начнут эксплуатировать в ближайшие 30 дней; значение в топ-0.03% всех CVE. Патч вышел в 2017 году, но эксплуатация подтверждена inthewild.io с 2021 года и продолжается. CISA Vulnrichment присваивает SSVC-решение Act (exploitation: active, technical impact: total) — наивысший приоритет патчинга. Оригинальный PoC от embedi опубликован в Exploit-DB (EDB-43163), на его основе на GitHub есть несколько реализаций, включая Metasploit-модуль от 0x09AL (★98).
Формат таймлайна
Собираем находки в таблицу. Формат — тот, который L3-аналитик или менеджер инцидентов прочтёт без дополнительных вопросов:
| Время (UTC) | Источник | Назначение | Событие | MITRE ATT&CK | Артефакт |
|---|---|---|---|---|---|
| 14:21:03 | 10.7.11.101 | DNS-сервер | DNS-запрос к update-service-cdn.top | T1071.004 (DNS) | dns.log, query ID |
| 14:21:04 | 10.7.11.101 | 185.220.101.34:443 | TLS Client Hello, JA3: abc123 | T1573 (Encrypted Channel) | ssl.log, uid |
| 14:21:05 | 10.7.11.101 | 185.220.101.34:443 | POST 312 байт, ответ 148 байт | T1071.001 (Web Protocols) | conn.log uid |
| 14:22:05 | 10.7.11.101 | 185.220.101.34:443 | Бьюкон, интервал 60.1s | T1071.001 | conn.log uid |
| … | … | … | Повторяется 237 раз за 4 часа | T1071.001 | conn.log uid |
| 14:35:12 | 185.220.101.34 | 10.7.11.101 | Загрузка payload 48 KB | T1105 (Ingress Tool Transfer) | files.log, SHA256 |
| 14:36:00 | 10.7.11.101 | 10.7.11.50:445 | SMB-соединение | lateral movement | conn.log uid |
Конкретные значения (IP, домены, хеши) меняются от инцидента к инциденту, структура таблицы — одна и та же. Столбец MITRE ATT&CK классифицирует каждое событие по общепринятой таксономии. T1573 (Encrypted Channel) — использование шифрования для маскировки C2-трафика. T1105 (Ingress Tool Transfer) — загрузка дополнительных инструментов на скомпрометированный хост.
Для каждой строки сохраняем артефакт: uid соединения из conn.log, JA3-хеш, хеши извлечённых файлов, скриншот TCP-стрима из Wireshark. Экспортируем подозрительные пакеты через Wireshark: File → Export Specified Packets с активным display filter — это сохраняет оригинальные временные метки и порядок пакетов, что критично для цепочки хранения доказательств.
Ошибки при расследовании инцидента по PCAP, которые стоят времени
Несколько граблей из практики.
Путают CDN с C2. Хост стучится на IP Cloudflare каждые 30 секунд — а это браузерное расширение проверяет обновления, а не бьюкон. Прежде чем эскалировать, проверьте ASN адреса через whois. Крупные CDN — обычно ложное срабатывание. Малоизвестные хостинги — нет.
Анализируют только первые пакеты. Некоторые C2-протоколы меняют поведение после первоначального хендшейка: первые пять соединений выглядят как обычный HTTPS, затем переключаются на кастомный бинарный протокол на нестандартном порту (техника T1571, Non-Standard Port). Всегда анализируйте дамп целиком, а не только первые минуты.
Не сопоставляют Zeek с Wireshark. Одного conn.log недостаточно. Zeek покажет метаданные соединений, но содержимое POST-запроса (закодированные команды C2) видно только в Wireshark через Follow TCP Stream. Один инструмент не заменяет другой — для network forensics нужна связка.
Игнорируют files.log. Zeek фиксирует все файлы, прошедшие через трафик, с MIME-типами и хешами. Команда cat files.log | zeek-cut ts tx_hosts rx_hosts mime_type md5 за секунду покажет, передавался ли исполняемый файл (mime_type application/x-dosexec). Быстрее, чем искать тот же файл вручную через Wireshark Export Objects.
Не фиксируют артефакты. Двадцать минут пролетели, хост изолировали — а таймлайн остался в голове аналитика. Таблица с временными метками, uid из Zeek и MITRE-маппингом — обязательный deliverable. Без неё L3-аналитик начинает расследование с нуля.
Что делать после двадцати минут
Двадцать минут дают черновой таймлайн для принятия решения: изолировать хост, эскалировать инцидент, запросить расширенный дамп. Полное расследование занимает часы и дни — к нему подключаются EDR-телеметрия, журналы Windows, дампы памяти.
По данным Mandiant M-Trends 2025, медианное время нахождения злоумышленника в сети до обнаружения — 11 дней. Exploits составляют 38% initial access. Если ваш таймлайн показывает, что бьюкон активен четвёртый час — вы отреагировали на порядок быстрее среднего по индустрии.
Для автоматизации разбора дампа трафика C2 стоит посмотреть на:
- ZUI (Brim) — GUI-обёртка над Zeek и Suricata. Позволяет выполнять агрегированные запросы и переключаться между метаданными и Wireshark-пакетами из одного интерфейса
- RITA — специализированный инструмент для автоматического обнаружения beaconing в Zeek-логах, рассчитывает score периодичности
- Suricata — IDS с сигнатурным движком; прогон дампа через
suricata -r incident.pcapс ruleset ET Open даёт алерты по известным сигнатурам C2 в fast.log
Два года работы L2 в SOC дали одно наблюдение, которое стоит проговорить. Большинство начинающих аналитиков тратят 80% времени на Wireshark, разглядывая пакеты по одному. Пропорция перевёрнута. Wireshark — отличный инструмент, но он плохо масштабируется. Дамп на 500 тысяч пакетов превращается в бесконечный скроллинг, если не знаешь, куда смотреть. Zeek решает именно эту проблему: сжимает полмиллиона пакетов в несколько тысяч строк conn.log. Один grep — и перед вами все обращения к подозрительному IP за четыре часа.
Проблема в том, что Zeek почти не встречается в начальных курсах. Люди узнают о нём через коллег или writeups и начинают пользоваться через год-два после прихода в SOC. Это потерянное время. Если бы я начинал путь в ИБ заново, первое действие после установки Wireshark — поставить Zeek и прогнать через него свой первый PCAP. Разница в скорости триажа — не проценты, а разы. Двадцать минут — не потолок качества, а порог реагирования. За 20 минут строится черновой таймлайн, достаточный для решения: изолировать, эскалировать, запросить больше данных. Полное расследование занимает часы. Но без быстрого первичного триажа эти часы начинаются слишком поздно — пока аналитик разглядывает пакеты по одному, атакующий перемещается на следующий хост. На IB Basics учат не «что такое CIA-triad», а как делать первые задачи в SOC и blue team.
Эту тему и смежные навыки разбирают на практике в курсе «Реагирование на компьютерные инциденты» Codeby Academy.
