Перейти к содержимому

Event ID 4625 и обнаружение брутфорса RDP: от анализа логов до правила корреляции SIEM

Event ID 4625 и обнаружение брутфорса RDP: от анализа логов до правила корреляции SIEM
Время чтения: 12 мин.

Первый RDP-брутфорс, который я разбирал вручную, выглядел так: больше 200 записей Event ID 4625 за 15 минут с одного внешнего IP, LogonType 10, целевая учётка — Administrator. Увидел это на AD-машине Hack The Box, а через неделю — ровно ту же картину на реальной смене в SOC. Между «красные строчки Audit Failure в Event Viewer» и «понимаю, что происходит» стоит одно умение: читать три-четыре ключевых поля события 4625 и превращать это в автоматический детект. Именно этому и посвящена статья.

Зачем атакующему вообще ломиться в RDP? Цепочка атаки укладывается в одну строку: подобрать пароль — Brute Force, техника T1110 по классификации MITRE ATT&CK (если ещё не сталкивался: это открытая база тактик и техник атак, а T-коды вроде T1110 — стандартные идентификаторы конкретных приёмов) → получить рабочие учётные данные — Valid Accounts (T1078) → зайти через Remote Desktop Protocol (T1021.001) → развернуть ransomware или закрепиться для движения по сети. По данным Huntress, операторы ransomware регулярно используют credential-атаки как начальный вектор, а всплеск событий 4625 — один из самых ранних сигналов перед деплоем шифровальщика. В терминах OWASP тут пересекаются два риска: A07:2021 — Identification and Authentication Failures (слабые пароли и отсутствие блокировки делают брутфорс возможным) и A09:2021 — Security Logging and Monitoring Failures (без мониторинга событий аутентификации атаку просто не видно).

Что фиксирует Event ID 4625 и какие поля читать первыми

Event ID 4625 — запись в журнале Windows Security (журнал «Безопасность» в русской локализации), которая создаётся при каждой неудачной попытке входа. При каждой — без исключений. Забытый пароль при RDP-подключении, ошибка сервисной учётки, задача в планировщике с устаревшими кредами — всё пишется как 4625. Одно событие — не повод для тревоги. Повод — паттерн из десятков или сотен таких событий за короткий промежуток.

Для работы с 4625 в SOC нужно знать три поля и ориентироваться по двум таблицам кодов.

LogonType, SubStatus, IpAddress — три поля для триажа

LogonType показывает, каким способом система пыталась аутентифицировать пользователя. Для фильтрации RDP-брутфорса — ключевое поле:

LogonType Что означает Когда встречается
2 Интерактивный вход (локальная консоль) Физический доступ к машине
3 Сетевой (SMB, CIFS, IIS) Подключение к шаре, принтеру, веб-сервису
7 Разблокировка экрана Пользователь разблокировал залоченную сессию
10 RemoteInteractive (RDP) Подключение через Remote Desktop — то, что ищем

Для обнаружения брутфорса RDP фильтруй по LogonType: 10. Массовые 4625 с LogonType 3 — не RDP, а чаще SMB-перебор или сервисная учётка с протухшим паролем. Путать их — типичная ошибка на старте.

SubStatus — код ошибки, объясняющий причину отказа. Поле Status обычно содержит общий код 0xC000006D («ошибка входа»), а SubStatus раскрывает конкретику:

SubStatus Значение Что это значит для аналитика
0xC000006A Неверный пароль Учётка существует, идёт перебор паролей
0xC0000064 Несуществующая учётная запись Атакующий перебирает логины — этап энумерации
0xC0000072 Учётка отключена Попытка входа под disabled-аккаунтом
0xC0000234 Учётка заблокирована Lockout policy сработала
0xC0000071 Пароль просрочен Легитимный пользователь с expired password

Серия событий с SubStatus 0xC000006A для одного TargetUserName — классический Password Guessing (T1110.001): учётка реальная, атакующий перебирает словарь. Чередование 0xC0000064 — этап энумерации, атакующий ещё не знает логинов. А если 0xC000006A приходит для разных TargetUserName с одним паролем — перед тобой Password Spraying (T1110.003), когда один популярный пароль пробуется по списку учёток. Разница между guessing и spraying — принципиальная для выбора правила корреляции, дойдём до этого ниже.

IpAddress — сетевой адрес источника подключения. В RDP-брутфорсе это внешний IP. Проверить можно через AbuseIPDB — сервис с базой IP-адресов, замеченных в злонамеренной активности; бесплатный tier даёт 1000 запросов в день; confidence score выше 75 означает подтверждённый источник атак, категория #18 Brute-Force. Внутренний IP (192.168.x.x, 10.x.x.x) при LogonType 10 — обычно легитимное подключение с ошибкой, а не атака.

TargetUserName — имя учётной записи, под которой пытаются войти. В типичном брутфорсе это Administrator, Admin, а также конкретные имена, полученные через OSINT или утечки. При прохождении AD-машин на HTB (включая Blackfield, где работа начинается с энумерации учёток Active Directory) видно тот же принцип: сначала атакующий узнаёт логины, затем перебирает пароли. Если открыть событие 4625 в XML View в Event Viewer, все эти поля лежат в секции <EventData> — именно по ним SIEM парсит события, и именно их мы используем в правиле корреляции.

Как отличить брутфорс RDP от нормального шума в логах

Одиночное событие 4625 — норма. По данным Huntress, 1–5 неудачных попыток входа в день на одного пользователя — типичный фон. Тревога начинается, когда события выстраиваются в паттерн.

Признаки реального RDP-брутфорса

  1. Высокая частота за короткий интервал. Десятки или сотни событий 4625 за 5–15 минут. Автоматизированный инструмент (hydra, crowbar, patator) генерирует попытки непрерывно — человек так быстро не опечатывается.

  2. Один IP — много попыток. Поле IpAddress одинаковое у серии событий. Исключение — распределённый брутфорс с ротацией IP, но об этом отдельно.

  3. LogonType 10. Подтверждает, что попытки идут через RDP, а не через SMB или другой протокол.

  4. Целевые учётки. TargetUserName = Administrator, Admin, конкретные имена из утечек. Перебор случайных строк с SubStatus 0xC0000064 — энумерация, тоже подозрительно.

  5. Нерабочие часы. Попытки в 03:00 по местному времени — мало кто из легитимных пользователей работает в это время.

  6. Event ID 4740 после серии 4625. 4740 — блокировка учётной записи. Когда lockout policy срабатывает после потока неудачных входов — сильный сигнал автоматизированной атаки. Корреляция пары 4625 + 4740 — базовый use case в SOC.

Типичные ложные срабатывания

Сервисная учётка с протухшим паролем. LogonType 3 (не 10), IP внутренний, частота — раз в 5–15 минут (по расписанию задачи или пула IIS). Фильтрация по LogonType 10 и внешним IP отсекает большинство таких случаев. Я на первой неделе в SOC потратил час на «атаку», которая оказалась IIS Application Pool с просроченным паролем сервисной учётки. С тех пор первым делом смотрю LogonType.

NLA меняет LogonType — и это ловушка. При включённой NLA (Network Level Authentication — аутентификация на уровне сети, когда креды проверяются ДО создания RDP-сессии) неудачные подключения могут записываться с LogonType 3 вместо 10. Почему? NLA проверяет креды до установки полноценной RDP-сессии, и Windows классифицирует это как сетевой вход. На системах с NLA правило, фильтрующее только LogonType 10, пропустит часть брутфорса. Запомни этот нюанс — он всплывёт при настройке детекта.

Пошаговый анализ Event ID 4625 через PowerShell

Требования к окружению

  • ОС: Windows 10/11 Pro или Windows Server 2016/2019/2022 (Home-редакции имеют ограниченный Security-лог)
  • Права: PowerShell от имени администратора (журнал Security требует elevated-привилегий)
  • Политика аудита: Audit Logon Events включена — путь: Security Settings → Advanced Audit Policy Configuration → Logon/Logoff → Audit Logon. Без этой политики события 4625 не записываются (подтверждено документацией Microsoft)
  • RAM: стандартные для ОС, дополнительных ресурсов не нужно

Шаг 1: проверь, что аудит включён

Перед поиском событий убедись, что система их записывает. Выполни auditpol /get /subcategory:"Logon" — если в столбце Setting видишь Success and Failure или хотя бы Failure, аудит работает. Если No Auditing — события не пишутся, и искать нечего. Сначала включи аудит через Group Policy.

Шаг 2: вытяни и сгруппируй события по IP

Цель: получить список IP-адресов с наибольшим количеством неудачных RDP-входов за сутки и сразу увидеть аномалии.

Get-WinEvent -FilterHashtable @{
  LogName='Security'; Id=4625;
  StartTime=(Get-Date).AddHours(-24)
} | Where-Object {$_.Properties[10].Value -eq 10} |
  Group-Object {$_.Properties[19].Value} |
  Sort-Object Count -Descending |
  Select-Object Count, Name -First 10

Что здесь происходит: Get-WinEvent читает журнал Security, фильтрует по Event ID 4625 за последние 24 часа. Properties[10] — LogonType (фильтруем значение 10, то есть RDP). Properties[19] — IpAddress. Нумерация свойств в массиве Properties фиксирована для Event ID 4625 и соответствует порядку нод в XML-представлении события. Group-Object группирует по IP, Sort-Object Count -Descending сортирует от большего к меньшему.

Ожидаемый результат — таблица, где верхние строки с count 100+ — кандидаты на брутфорс, а строки с 1–3 попытками от внутренних IP — обычный шум.

Шаг 3: детали по подозрительному IP

Когда нашёл аномальный IP, вытяни записи для него: Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} | Where-Object {$_.Properties[19].Value -eq 'ПОДОЗРИТЕЛЬНЫЙ_IP'} | Select-Object TimeCreated, @{N='User';E={$_.Properties[5].Value}}, @{N='SubStatus';E={$_.Properties[9].Value}} -First 20. На выходе — временные метки, имена учёток и коды SubStatus. Если SubStatus одинаковый (0xC000006A) и TargetUserName = Administrator — подтверждённый Password Guessing.

Шаг 4: проверь IP через внешние источники

Внешний IP проверяется через AbuseIPDB (бесплатный tier: GET /api/v2/check?ipAddress=X, 1000 запросов в день). Confidence score выше 75 — подтверждённый источник атак. Полезно проверить ASN: отдельные bulletproof-хостинги (подсети Datacamp, Petersburg Internet Network) имеют высокую концентрацию malicious IP — фильтрация на уровне AS добавляет ещё один слой защиты.

Правило корреляции для SIEM: Sigma и Splunk SPL

Sigma-правило для обнаружения брутфорса RDP

Sigma — открытый формат описания правил обнаружения. Его главная фишка: пишешь одно правило, конвертируешь в запросы конкретных SIEM (Splunk, Elastic, Microsoft Sentinel). Одно правило покрывает любой SIEM — в отличие от SPL или KQL, привязанных к конкретному продукту.

title: RDP Brute Force - Event 4625
logsource: {product: windows, service: security}
detection:
  selection:
    EventID: 4625
    LogonType: 10
  condition: selection | count() by IpAddress > 5
  timeframe: 5m
level: high
tags: [attack.credential_access, attack.t1110.001]

Правило отбирает события 4625 с LogonType 10, группирует по IpAddress и срабатывает, если с одного IP за 5 минут пришло больше 5 неудачных попыток. Тег attack.t1110.001 — ссылка на технику Password Guessing в MITRE ATT&CK. Порог «5 за 5 минут» — стартовая точка; на конкретной инфраструктуре его нужно подкрутить под реальный фон.

Работает если: аудит Logon Events включён, события пересылаются в SIEM (через Winlogbeat, Elastic Agent, NXLog или аналог), NLA выключена или SIEM корректно парсит события с LogonType 3 при NLA.

Не работает если: атакующий ротирует IP (каждая попытка с нового адреса — count никогда не превысит порог), лог-коллектор не доставляет события вовремя (задержка больше timeframe), или RDP-трафик идёт через шлюз (IP в логе = адрес шлюза, а не атакующего).

Трансляция в Splunk SPL

Эквивалент для Splunk: index=wineventlog EventCode=4625 LogonType=10 | bin _time span=5m | stats count by IpAddress, _time | where count > 5. Имена полей зависят от Technology Add-on (TA-windows): Event ID может маппиться в EventCode или event_id, IP — в IpAddress, src_ip или Source_Network_Address. Проверь маппинг в своём TA перед выводом в прод — иначе правило будет молчать не потому что атак нет, а потому что поля называются иначе.

Трансляция в Elastic (KQL)

Для Elastic Security запрос: event.code: "4625" AND winlog.event_data.LogonType: "10" с threshold rule (порог 5 событий за 5 минут, группировка по source.ip). Настраивается через Security → Detection Rules → Create new rule → Threshold.

Усиление: корреляция с Event ID 4740

Добавь второе правило на Event ID 4740 (Account Lockout). Если 4740 появляется в течение 10 минут после серии 4625 для того же TargetUserName — confidence детекта резко возрастает. Lockout policy сработала, пороговое число неудачных попыток достигнуто, система уже среагировала. В Sigma 2.0 корреляция между правилами поддерживается нативно.

Когда детект по Event ID 4625 не работает

[Применимо: SOC мониторинг, внешний и внутренний периметр. Правило работает для standalone-серверов и AD-среды. При наличии NLB или RDP Gateway IP-адрес в логе может быть адресом шлюза — нужна дополнительная корреляция с логами шлюза.]

Распределённый брутфорс. Атакующий с ботнетом ротирует IP после каждой попытки — count по IpAddress никогда не превысит порог. Решение: параллельное правило с группировкой по TargetUserName — count() by TargetUserName > 20 | timeframe: 10m. Если одну учётку атакуют 20 раз за 10 минут с разных адресов — это аномалия, даже если каждый IP засветился один раз.

Password Spraying. Одна попытка на учётку, один пароль по всему списку — ни группировка по IP, ни по TargetUserName не покажет всплеска. Детект требует отдельного правила: count(distinct TargetUserName) by IpAddress > N, где N — порог уникальных учёток с одного адреса за интервал. Spraying — головная боль для SOC, потому что по отдельности каждая попытка выглядит легитимно.

Аудит выключен. Без политики Audit Logon Events события 4625 не записываются. Лог пуст не потому, что атак нет, а потому что нет видимости. Именно эту проблему описывает OWASP A09:2021. Проверяй auditpol до того, как начнёшь строить детекты — иначе рискуешь охранять пустую комнату.

BlueKeep — другой класс угрозы. RDP-брутфорс — не единственная угроза для порта 3389. Уязвимость BlueKeep (CVE-2019-0708, CVSS 9.8 CRITICAL; CVSS-вектор AV:N/AC:L/PR:N/UI:N — атака по сети, низкая сложность, без привилегий, без участия пользователя; CWE-416 Use After Free) позволяет выполнить код удалённо без аутентификации. Она активно эксплуатируется с 2021 года (подтверждено CISA KEV — каталогом уязвимостей, которые уже используются в реальных атаках; EPSS = 1.0, то есть максимальная вероятность эксплуатации) и затрагивает Windows Server 2008 / Windows 7. Детект по 4625 против BlueKeep бесполезен — здесь нужен патч, а не мониторинг событий аутентификации.

Большинство русскоязычных руководств по детекту RDP-брутфорса — от PowerShell-скриптов для автоблокировки IP через Windows Firewall до утилит вроде RdpGuard и Cyberarms IDDS — работают на уровне «увидел 5 событий 4625 с одного IP — заблокировал». Для одиночного VPS с открытым портом 3389 этого хватает. Но в корпоративном SOC нужен другой уровень: понимать, какой SubStatus приходит, коррелировать с 4740, отслеживать паттерн spraying против guessing, различать LogonType 10 и LogonType 3 при NLA, фиксировать результат в тикете. Разница между «скрипт заблокировал IP» и «аналитик написал правило корреляции SIEM, которое работает 24/7 без его участия» — это разница между ручной работой и системным детектом.

SOC-позиции уровня L1 всё чаще требуют не просто навык работы в интерфейсе SIEM, а умение написать базовое Sigma-правило и объяснить, почему порог в одном правиле 5 попыток за 5 минут, а в другом — 20 за 10. Sigma-правило для Event ID 4625 с LogonType 10 — буквально первый use case, с которого стоит собирать портфолио детектов. Тот, кто приходит на собеседование с пятью рабочими Sigma-правилами и внятным объяснением логики порогов, выглядит принципиально иначе, чем кандидат с сертификатом и нулём написанных правил. IB Basics для тех, кому скучно от Hack The Box без объяснений почему — там структура, которой не хватает при самостоятельном разборе логов.

Эту тему и смежные навыки разбирают на практике в курсе «Аналитик SOC» Codeby Academy.