Как отличить brute-force от сканера уязвимостей по логам: разбор паттернов для SOC-аналитика

Утро понедельника, 07:15. В SIEM (Security Information and Event Management — система, которая собирает логи со всей инфраструктуры и ищет в них подозрительное) за ночь накопилось 14 000 событий Event ID 4625 с одного IP-адреса. Дежурный аналитик L1 (первая линия SOC — обрабатывает алерты по инструкции) ставит статус «brute-force» и отправляет на блокировку. Через час прибегает команда аудита: заблокирован корпоративный Nessus, который в 03:00 начал плановое сканирование.
Обратная ситуация бьёт не слабее — реальный перебор паролей классифицируется как «сканер» и остаётся незамеченным.
Я разберу конкретные поля в логах Windows и Linux, по которым SOC-аналитик за несколько минут определяет: перед ним атака или легитимный инструмент.
Зачем SOC-аналитику разделять brute-force и сканирование уязвимостей
Brute-force (перебор паролей) — техника из матрицы MITRE ATT&CK (открытая база тактик и техник атак; каждой технике присвоен T-код — уникальный идентификатор). Техника T1110 объединяет четыре подвида: Password Guessing (T1110.001), Password Cracking (T1110.002), Password Spraying (T1110.003) и Credential Stuffing (T1110.004). Все относятся к тактике Credential Access — получение учётных данных для проникновения в систему.
Сканер уязвимостей (Nessus, OpenVAS, Qualys) — легитимный инструмент, который проверяет систему на известные слабости. При этом он пробует дефолтные учётные записи и генерирует те же Event ID 4625, что и атакующий. Вот тут и начинается путаница.
В цепочке атаки (kill chain — модель последовательных этапов кибератаки) brute-force — это начальный доступ (initial access). Подобранный пароль открывает путь к горизонтальному перемещению по сети (lateral movement), повышению привилегий (privilege escalation) и выводу данных (exfiltration). Сканер никогда не переходит к следующим этапам — он собирает отчёт и прекращает работу.
Число brute-force кампаний против сервисов удалённого доступа за последние годы выросло кратно, а совокупные потери от компрометации учётных данных оцениваются в миллиарды долларов ежегодно. Задача SOC-аналитика уровня L2 (вторая линия — углублённый анализ) — отличить одно от другого до того, как станет поздно.
Windows Security Event ID 4625: анализ ключевых полей
Event ID 4625 — запись в журнале Windows Security, которая создаётся при каждой неудачной попытке аутентификации. Для разбора атак и сканирования нужны пять полей:
- SubStatus — код причины отказа.
0xC000006Aозначает «неверный пароль» (учётная запись существует, пароль не подошёл).0xC0000064— «пользователь не найден в системе». Разница принципиальная. - Logon Type — тип входа.
3— сетевой (SMB, WMI).10— RDP (Remote Desktop Protocol — протокол удалённого рабочего стола).8— NetworkCleartext (например, HTTP Basic Auth). - Source Network Address — IP-адрес источника.
- Target User Name — учётная запись, к которой пытались войти.
- Workstation Name — имя машины-источника.
SubStatus и Logon Type — два поля, которые решают задачу
Brute-force атака генерирует поток событий с SubStatus 0xC000006A против существующих пользователей. Атакующий знает или предварительно собрал логины и перебирает пароли. Logon Type обычно один: если бьют RDP — весь поток имеет Logon Type 10, если SMB — Logon Type 3.
Сканер уязвимостей создаёт смесь: 0xC000006A и 0xC0000064. Он пробует предопределённый набор дефолтных учёток — admin, administrator, test, guest, sa — многих из которых в системе нет, отсюда код 0xC0000064. По Logon Type картина ещё интереснее: сканер проверяет несколько протоколов одновременно (SMB, RDP, HTTP) и генерирует Logon Type 3, 8 и 10 в одной серии. Это характерный признак автоматизированной проверки разных сервисов — живой атакующий так почти никогда не работает.
auth.log на Linux: анализ атак аутентификации
На Linux аутентификационные события записываются в /var/log/auth.log (Debian/Ubuntu) или /var/log/secure (CentOS/RHEL). Формат текстовый, разбирать удобно через grep и awk.
Типичная серия при неудачном SSH-входе:
Jun 15 03:14:22 srv01 sshd[18432]: Failed password for invalid user admin from 10.0.5.47 port 49812 ssh2
Jun 15 03:14:23 srv01 sshd[18433]: Failed password for root from 10.0.5.47 port 49814 ssh2
Jun 15 03:14:23 srv01 sshd[18434]: Failed password for invalid user test from 10.0.5.47 port 49816 ssh2
Два паттерна в одном фрагменте: Failed password for invalid user (пользователь не существует) и Failed password for root (пользователь существует, пароль неверный). Это аналог SubStatus в Windows. Сканер генерирует обе записи, brute-force чаще бьёт в существующие учётки.
Маркер, на который мало кто обращает внимание — поле port (source port клиента). Сканер уязвимостей открывает и закрывает соединения последовательно, source port инкрементируется на 1-2 (49812 → 49814 → 49816 в примере выше). Brute-force инструменты вроде Hydra открывают несколько параллельных потоков, и source port прыгает хаотично (49812 → 51340 → 50017). Мелочь — но в реальном разборе именно она часто ставит точку.
Паттерны brute-force атак в SIEM: что именно искать
Brute-force в логах аутентификации оставляет характерные следы в зависимости от подвида техники.
Classic brute-force (T1110.001)
Атакующий бьёт в одну учётную запись, перебирая пароли. Картина в логах: один Target User Name (например, administrator), один Source IP, SubStatus = 0xC000006A, интервалы между попытками от 0,1 до 2 секунд (автоматизация) или ровно 0 (параллельные потоки). Такой паттерн ловится элементарно — поток Event 4625 против одного аккаунта с одного IP виден невооружённым глазом. Именно поэтому атакующие давно перешли к spraying.
Password spraying (T1110.003)
Инвертированный подход: один пароль (например, Company@2025) пробуется на множестве учётных записей. Каждый аккаунт получает 1-2 отказа, и ни один не достигает порога блокировки. В CTI-отчётах (Cyber Threat Intelligence — аналитика угроз) password spraying часто описывается как техника state-sponsored групп: 1-2 попытки на аккаунт в час на протяжении рабочего дня. Медленно, аккуратно, ниже радаров.
В логах: много разных Target User Name, один Source IP (или небольшая группа), устойчивый временной интервал между попытками (30-60 секунд), SubStatus = 0xC000006A (все пользователи существуют, пароли неверные).
Нюанс, который ломает стандартные детекты: инструмент Kerbrute выполняет spraying через Kerberos-запросы (Kerberos — протокол аутентификации в Windows-доменах) и генерирует Event 4771 (Kerberos Pre-authentication Failed) с Result Code 0x18, а не Event 4625. Стандартные SIEM-правила для brute-force его не ловят — нужен отдельный детект по Kerberos-событиям.
Credential stuffing (T1110.004)
Атакующий использует реальные пары «логин-пароль» из утечек. Масштаб: база Exploit.In (2016) содержала данные 593 миллионов уникальных email-адресов с паролями, по данным Have I Been Pwned. Credential stuffing отличается от brute-force тем, что каждая пара уникальна — нет повторных попыток с одним паролем.
Картина в логах: формат username совпадает с реальными аккаунтами (не admin/test, а john.smith@company.com), каждый username пробуется 1-2 раза, Source IP меняется (прокси-ротация), временное окно сжатое — тысячи попыток за 10-15 минут. Группировка Scattered Spider (UNC3944) предположительно комбинировала credential stuffing с социальной инженерией helpdesk для обхода MFA (многофакторной аутентификации — когда помимо пароля нужен второй фактор: код из SMS, аппаратный ключ и т.д.).
Обнаружение сканирования уязвимостей по логам: паттерны сканера
Сканер уязвимостей создаёт принципиально другую картину в аутентификационных логах.
Разнообразие протоколов. Nessus или OpenVAS в рамках одного скана проверяют SMB (Logon Type 3), RDP (Logon Type 10), HTTP Basic Auth (Logon Type 8), WMI и другие сервисы. Brute-force инструмент работает с одним протоколом — ему не нужно проверять, какие сервисы доступны. Он уже знает, куда бьёт.
Дефолтные учётные записи. Сканер пробует фиксированный набор: admin, administrator, root, sa, guest, test, oracle, postgres. Этот список идентичен от скана к скану. Brute-force использует собранные разведкой данные или словарь с тысячами вариаций.
Стабильный source IP из корпоративной подсети. Адрес сканера один, из внутренней сети (10.x.x.x, 172.16.x.x). Не ротируется.
Сопутствующий port scan. Перед серией Event 4625 сканер генерирует трафик по множеству портов: 445, 3389, 80, 443, 22, 1433, 5432 — за один проход. IDS/IPS (система обнаружения/предотвращения вторжений) фиксирует port scan до начала аутентификационных проверок. AbuseIPDB — база репутации IP-адресов — относит port scan к категории #14, отделяя от категории #18 (Brute-Force); для SSH-перебора есть отдельная категория #22.
Нерегулярные интервалы. Сканер работает рывками: проверяет один сервис, переходит к следующему, возвращается. Паузы 5-30 секунд между группами. Brute-force идёт непрерывным потоком с фиксированным интервалом.
Таблица-чеклист: brute-force vs сканер уязвимостей по логам
| Признак | Brute-force | Сканер уязвимостей |
|---|---|---|
| Target User Name | 1-3 конкретных аккаунта (spraying — все) | Дефолтные: admin, test, guest, sa |
| SubStatus | Преимущественно 0xC000006A | Смесь 0xC000006A и 0xC0000064 |
| Logon Type | Один тип (3 или 10) | Несколько типов в одной серии |
| Source IP | Один IP или ротация через прокси | Один IP из корпоративной подсети |
| Интервалы | Равные, 0,1-2 сек или параллельные | Нерегулярные, паузы 5-30 сек |
| Port scan перед попытками | Нет | Да |
| Успешный вход после серии fail | Возможен (цель атаки) | Нет |
| Протоколы | Один (SSH, RDP или SMB) | Несколько одновременно |
Практика для SOC-аналитика: делай раз, делай два, делай три
Требования к окружению:
— Windows: доступ к Security Event Log (PowerShell 5.1+, членство в группе Event Log Readers или локальный администратор)
— Linux: чтение /var/log/auth.log (пользователь в группе adm или root)
— Инструменты: grep, awk (предустановлены в Linux-дистрибутивах)
Шаг 1 — фильтруем Event ID 4625 и группируем по source IP
Зачем: определить, какие IP генерируют основной объём отказов, и выделить подозрительные источники.
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4625} -MaxEvents 5000 |
Group-Object {$_.Properties[19].Value} |
Sort-Object Count -Descending |
Select-Object Count, Name -First 10
Properties[19] — поле Source Network Address в структуре Event 4625 (нумерация с нуля). Индекс может отличаться между версиями и локализациями Windows. Надёжнее — XPath-запрос по именованному полю IpAddress: Get-WinEvent -FilterXPath "*[System[EventID=4625]]" -LogName Security -MaxEvents 1 | ForEach-Object { $_.ToXml() } и найти нужное поле. Для проверки числового индекса: (Get-WinEvent -FilterHashtable @{LogName='Security';Id=4625} -MaxEvents 1).Properties | ForEach-Object {$_.Value}.
Результат — таблица, где Name — IP-адрес, Count — число отказов. Если один IP из подсети 10.0.0.0/8 сгенерировал 90% событий — вероятнее всего сканер. Внешний IP, ранее не встречавшийся — подозрение на brute-force.
Шаг 2 — строим таймлайн и анализируем интервалы
Зачем: временной паттерн — главный дифференциатор между brute-force (постоянная частота) и сканером (рывки с паузами).
На Linux для auth.log:
grep "Failed password" /var/log/auth.log | grep "10.0.5.47" |
awk '{print $1, $2, $3}' | uniq -c | sort -rn | head -20
Замените 10.0.5.47 на IP из шага 1. Результат — строки вида 143 Jun 15 03:14 — 143 неудачные попытки за одну минуту. Попытки распределены равномерно по минутам — автоматизированный перебор. Сконцентрированы в 2-3 минуты с паузами по 10-20 минут — сканер переключался между сервисами.
Шаг 3 — проверяем, был ли успешный вход после серии fail
Зачем: если после серии отказов появляется Event ID 4624 (успешный вход) или Accepted password в auth.log с того же IP — это признак успешного brute-force. Сканер не совершает успешный вход.
В PowerShell запросите Event 4624 за тот же период и отфильтруйте по Source Network Address — индекс поля зависит от версии ОС. Проверьте: (Get-WinEvent -FilterHashtable @{LogName='Security';Id=4624} -MaxEvents 1).Properties | ForEach-Object {$_.Value} и найдите IP-адрес, либо используйте XPath по имени поля IpAddress. На Linux: grep "Accepted password" /var/log/auth.log | grep "10.0.5.47". Пустой вывод — входа не было. Строка с Accepted password — это инцидент: смена пароля скомпрометированной учётки, блокировка IP, проверка последующих действий (lateral movement, создание новых учёток). Немедленная эскалация.
Корреляционные правила SIEM и Sigma для детекта brute-force
Sigma — универсальный формат описания правил обнаружения. Написал правило один раз — конвертировал в запросы для Splunk, Elastic Security, QRadar или другой SIEM. В репозитории SigmaHQ (github.com/SigmaHQ/sigma) по технике T1110 есть готовые правила:
proc_creation_win_hktl_hydra.yml— обнаруживает запуск Hydra на Windows по сигнатуре командной строки. Полезно, если атакующий запускает brute-force с уже скомпрометированной машины внутри сети.win_security_susp_failed_logons_single_source_ntlm.yml— детектит серию неудачных NTLM-входов (NTLM — протокол аутентификации Windows, старше Kerberos и слабее его) с одного source IP. Базовое правило для classic brute-force.win_security_susp_failed_logons_single_process.yml— срабатывает при массовых отказах от одного процесса, помогает обнаружить spraying от внутреннего инструмента.
Примечание: оба правила находятся в директории unsupported/ репозитория SigmaHQ и могут быть устаревшими. Для продакшена проверьте актуальные альтернативы в rules/windows/builtin/security/.
Конвертация: sigma-cli convert -t es-qs rule.yml (для Elastic) или с таргетом splunk-spl (для Splunk).
Ключевое ограничение: ни одно из этих Sigma-правил не фильтрует сканеры уязвимостей автоматически. Это задача вайтлиста — IP-адреса корпоративных сканеров добавляются в исключения правила. Без вайтлиста правило будет кричать на каждый плановый скан.
False positive brute-force: типичные ошибки и как их избежать
Ложные срабатывания — главная боль SOC при детекте brute-force. Три сценария, которые я вижу регулярно.
Сценарий 1: сканер без вайтлиста. IP-адрес Nessus/OpenVAS не добавлен в исключения SIEM-правил — каждое плановое сканирование генерирует алерт High. Решение: вести актуальный реестр IP всех корпоративных сканеров и пересматривать его при каждом изменении инфраструктуры.
Сценарий 2: пользователь забыл пароль. 3-5 неудачных попыток утром понедельника — не brute-force. Отличие: количество (3-5 vs 100+), диапазон (2-3 минуты vs непрерывный поток), наличие успешного входа после звонка в helpdesk. Решение: порог SIEM-правила «минимум 20 событий 4625 за 5 минут» отсекает таких пользователей.
Сценарий 3: сервисная учётная запись с истёкшим паролем. Служба генерирует Event 4625 каждые 30 секунд, потому что пароль протух. Отличие от brute-force: один Source Workstation Name (имя сервера), один Target User Name (сервисная учётка), неизменный паттерн 24/7. Решение: добавить в правило условие «минимум N разных Target User Name за период».
Когда метод НЕ работает
Описанные паттерны разделяют классический brute-force и стандартный корпоративный сканер. Но есть сценарии, где анализа логов аутентификации недостаточно:
- Credentialed scan — если сканер использует валидные учётные данные, он генерирует Event 4624 (успешный вход), а не 4625. В логах неотличим от легитимного пользователя.
- Slow brute-force через Tor/прокси — одна попытка в час с разных IP. Ни одно пороговое правило не сработает. Здесь нужен поведенческий анализ (UEBA — User and Entity Behavior Analytics, система, которая строит профиль «нормального» поведения и ловит отклонения) или ручной threat hunting.
- Kerbrute spraying — как разобрано выше, генерирует Event 4771 вместо Event 4625. Стандартные правила по 4625 бесполезны.
Каждый из этих сценариев требует отдельных детектов, выходящих за рамки базового анализа логов аутентификации.
За несколько лет на L2 я наблюдаю одну и ту же проблему: команды SOC ставят правило «больше 10 Event 4625 за 5 минут = brute-force» и считают задачу закрытой. Правило срабатывает 40 раз в неделю. 38 из 40 — false positive от сканеров, сервисных учёток и людей после отпуска. Аналитики устают, закрывают алерты не глядя. И в этот момент password spraying с одной попыткой на аккаунт в час проходит незамеченным — потому что ниже любого порога.
Проблема не в SIEM и не в Sigma-правилах. Проблема — в отсутствии baseline (базовой линии «нормального» поведения инфраструктуры). Пока SOC не знает, какой объём Event 4625 генерирует инфраструктура в штатном режиме — сколько отказов создают сервисные учётки, сканеры и пользователи каждый понедельник — любое пороговое правило остаётся угадайкой. Baseline строится за 2-4 недели чистых логов с правильной разметкой источников. Без этого шага SOC работает вслепую: ловит шум и пропускает сигнал. Если хочешь понять, как устроена эта работа от фундамента — на IB Basics разбирают именно такие задачи, от первых действий в реальном SOC до построения нормального baseline.
Эту тему и смежные навыки разбирают на практике в курсе «Аналитик SOC» Codeby Academy.