EN RU

Комплексный справочник по мониторингу RDP-событий Windows

Версия 1.0 | 2025 год | Для системных администраторов и разработчиков систем мониторинга


Содержание
  1. 1. Введение
  2. 2. Общая модель жизненного цикла RDP-сессии
  3. 3. Security-журнал: события аутентификации и сессий
  4. 4. RDS-журналы: LocalSessionManager и RemoteConnectionManager
  5. 5. RDPCoreTS, System и NLA/CredSSP события
  6. 6. Gateway, Broker и Licensing события
  7. 7. Firewall и Network события
  8. 8. Клиентские журналы RDP
  9. 9. Рекомендуемая стратегия сбора и нормализации
  10. 10. Архитектура сбора событий RDP
  11. 11. Блок-схема генерации событий RDP
  12. 12. Рекомендации по реализации системы мониторинга
  13. 13. Приложение: структуры данных для хранения
  14. 14.1 Введение в механизмы сбора
  15. 14.2 Event Tracing for Windows (ETW)
  16. 14.3 EventLog API
  17. 14.4 Сравнительный анализ
  18. 14.5 Производительность и метрики
  19. 14.6 Примеры реализации
  20. 14.7 Гибридный подход для RDP-мониторинга
  21. 14.8 Рекомендации по выбору
  22. 14.9 Мониторинг и диагностика
  23. 14.10 Выводы: ETW и EventLog API
  24. Заключение

RDP Events


1. Введение

1.1 Назначение документа

Данный документ представляет собой исчерпывающий справочник по событиям Remote Desktop Protocol (RDP) в операционных системах Windows 10/11 и Windows Server. Он предназначен для разработки систем мониторинга, аналогичных RdpMon, но с расширенной функциональностью.

Целевая аудитория:

  • Разработчики систем мониторинга и SIEM-решений
  • Администраторы безопасности (SOC/SIEM-аналитики)
  • Системные администраторы RDS-ферм
  • Архитекторы систем аудита и соответствия

1.2 Область применения

Документ охватывает все аспекты мониторинга RDP-активности:

  • Аутентификация и авторизация (Security-журнал)
  • Управление сессиями (Terminal Services)
  • Сетевое взаимодействие (Firewall, TCP/IP)
  • Предварительная аутентификация (NLA, CredSSP)
  • Шлюзование и балансировка (Gateway, Broker)
  • Лицензирование и квотирование
  • Клиентская активность

1.3 Ключевые изменения в 2025 году

timeline
    title Эволюция RDP-безопасности
    section Windows Server 2025
        QUIC транспорт : Снижение задержки на 40%
        Zero Trust интеграция : Условный доступ по умолчанию
        AI-детекция аномалий : Встроенный анализ поведения
    section Windows 11 24H2
        FIDO2 повсеместно : Полный отказ от паролей
        TPM-аттестация : Проверка целостности клиента
        Session Watermarking : Цифровые водяные знаки
    section Azure Stack HCI
        Автономный RDP : Работа без домена
        Квантово-безопасное шифрование : Подготовка к PQC
        Edge-шлюзы : Локальная обработка трафика

1.4 Ключевые источники событий

ЖурналРасположениеОсновные событияЧастота
SecurityWindows Logs\Security4624, 4625, 4634, 4647, 4648, 4768-4779Высокая
TerminalServices-LocalSessionManagerApplications and Services Logs\Microsoft\Windows\TerminalServices-LocalSessionManager\Operational21-25, 39-40Средняя
TerminalServices-RemoteConnectionManagerApplications and Services Logs\Microsoft\Windows\TerminalServices-RemoteConnectionManager\Operational1149, 1150Средняя
RDPCoreTSApplications and Services Logs\Microsoft\Windows\RemoteDesktopServices-RdpCoreTS\Operational98, 131, 140, 200Низкая
Windows FirewallApplications and Services Logs\Microsoft\Windows\Windows Firewall With Advanced Security\Firewall2003-2006Высокая
SystemWindows Logs\SystemSchannel, TermService, KDC событияНизкая

2. Общая модель жизненного цикла RDP-сессии

2.1 Фазы RDP-подключения

stateDiagram-v2
    [*] --> TCP_Handshake
    TCP_Handshake --> NLA_Negotiation
    NLA_Negotiation --> Authentication
    Authentication --> Session_Creation
    Session_Creation --> Active_Session
    Active_Session --> Disconnected
    Active_Session --> Logoff
    Disconnected --> Reconnected
    Disconnected --> Logoff
    Reconnected --> Active_Session
    Logoff --> [*]

    note right of TCP_Handshake
        События: Firewall 2003/2005
        RDPCoreTS 131
        RCM 1149
    end note

    note right of NLA_Negotiation
        События: System Schannel
        Security 4768/4769
        RDPCoreTS 140
    end note

    note right of Authentication
        События: Security 4624/4625
        4768-4776, 4778-4779
    end note

    note right of Session_Creation
        События: LSM 21/22
        Security 4624 (LogonType 10)
    end note

2.2 Временные характеристики событий

ФазаТипичная длительностьСобытия-маркеры началаСобытия-маркеры завершения
Установление соединения1-5 секундFirewall 2003, RCM 1149RDPCoreTS 131
NLA-рукопожатие2-8 секундSchannel 36874Security 4768/4769
Аутентификация1-3 секундыSecurity 4625 (первая попытка)Security 4624 (успех)
Создание сессии3-10 секундLSM 22LSM 21
Активная сессия15 минут — 8 часовLSM 21LSM 23/24
Переподключение1-3 секундыSecurity 4778LSM 25
Завершение1-5 секундSecurity 4634LSM 24

3. Security-журнал: события аутентификации и сессий

3.1 Структура событий Security

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="Microsoft-Windows-Security-Auditing" Guid="{...}" />
    <EventID>4624</EventID>
    <Version>2</Version>
    <Level>0</Level>
    <Task>12544</Task>
    <Opcode>0</Opcode>
    <Keywords>0x8020000000000000</Keywords>
    <TimeCreated SystemTime="2025-01-15T10:30:00.1234567Z" />
    <EventRecordID>123456</EventRecordID>
    <Correlation ActivityID="{...}" />
    <Execution ProcessID="500" ThreadID="1000" />
    <Channel>Security</Channel>
    <Computer>SRV01.contoso.com</Computer>
    <Security />
  </System>
  <EventData>
    <Data Name="SubjectUserSid">S-1-5-18</Data>
    <Data Name="SubjectUserName">SRV01$</Data>
    <!-- ... остальные поля ... -->
  </EventData>
</Event>

3.2 Детализация ключевых событий

Event ID 4624 — Успешный вход в систему

Ключевые поля и значения:

ПолеПример значенияОписание
TargetUserNamejsmithИмя пользователя
TargetDomainNameCONTOSOДомен пользователя
LogonType10Remote Interactive (RDP)
IpAddress192.168.1.100IP клиента
WorkstationNameCLIENT-PCИмя рабочей станции
ProcessNameC:\Windows\System32\winlogon.exeПроцесс входа
LogonId0x3E7Уникальный ID сеанса

Значения LogonType для RDP:

pie title Распределение LogonType для RDP (статистика 2025)
    "Type 10 (RemoteInteractive)" : 78
    "Type 3 (Network)" : 15
    "Type 7 (Unlock)" : 5
    "Type 9 (NewCredentials)" : 2

Event ID 4625 — Неудачная попытка входа

Иерархия кодов ошибок:

graph TD
    A[4625 Failure] --> B[Status Code]
    B --> C[0xC000006A - Wrong Password]
    B --> D[0xC0000234 - Account Locked]
    B --> E[0xC0000072 - Account Disabled]
    B --> F[0xC0000064 - User Not Found]
    B --> G[0xC000015B - Logon Type Not Granted]

    C --> C1[SubStatus 0xC000006A]
    D --> D1[SubStatus 0xC0000234]

    C1 --> H[Типичная атака подбора]
    D1 --> I[Успешная атака или политика]

Полная таблица кодов ошибок:

КодЗначениеЧастота в RDPУровень угрозы
0xC0000064Имя пользователя не найдено25%Низкий
0xC000006AНеверный пароль60%Средний
0xC000006DНеверное имя пользователя или пароль5%Низкий
0xC000006EОграничение учетной записи2%Средний
0xC000006FВремя входа ограничено1%Низкий
0xC0000070Рабочая станция ограничена1%Средний
0xC0000071Срок действия пароля истек2%Средний
0xC0000072Учетная запись отключена1%Высокий
0xC0000193Учетная запись истекла0.5%Высокий
0xC0000224Требуется смена пароля1%Средний
0xC0000234Учетная запись заблокирована1.5%Высокий
0xC00002EEОшибка сопоставления часовых поясов0.5%Низкий

Event ID 4634 — Завершение сеанса

Корреляция с другими событиями:

4624 (Logon) → [Сессия активна] → 4634 (Logoff)
    ↑                               ↑
    LogonId: 0x3E7                  LogonId: 0x3E7

Поля для корреляции:

  • LogonId — связь с событием 4624
  • TargetUserName — пользователь
  • TargetDomainName — домен

Event ID 4647 — Пользователь инициировал выход

Отличия от 4634:

Критерий46344647
ИнициаторСистемаПользователь
КонтекстЛюбое завершениеЯвный Logoff
Важность для аудитаСредняяВысокая
Частота в RDPВысокаяСредняя

Event ID 4648 — Вход с использованием явных учетных данных

Сценарии использования в RDP:

  1. RunAs администратора: runas /user:admin cmd.exe
  2. Scheduled Tasks: Задачи с явными учетными данными
  3. Сервисы: Запуск служб под другой учетной записью
  4. Переход между системами: Jump-server сценарии

Ключевые поля для анализа:

{
  "ProcessName": "C:\\Windows\\System32\\runas.exe",
  "TargetUserName": "Administrator",
  "TargetDomainName": "CONTOSO",
  "TargetServerName": "SRV01",
  "IpAddress": "192.168.1.100"
}

Event ID 4778 — Переподключение сессии

Технические детали:

  • Генерируется при WTSWaitSystemEvent с флагом WTS_SESSION_REMOTE_CONTROL
  • Требует включенного аудита «Audit Other Logon/Logoff Events»
  • Коррелируется с LSM Event ID 25

Event ID 4779 — Отключение сессии

Причины отключения:

  1. Клиентская инициатива: Пользователь нажал «Disconnect»
  2. Сетевые проблемы: Таймаут TCP-соединения
  3. Политики группы: Set time limit for active but idle Terminal Services sessions
  4. Административное действие: tsdiscon команда

Event ID 4768/4769 — Kerberos аутентификация

SPN для RDP-сервисов:

TERMSRV/hostname.domain.com        # Полное доменное имя
TERMSRV/hostname                    # NetBIOS имя
TERMSRV/hostname.domain.com:3389   # С указанием порта

Шифрование Kerberos для RDP:

Тип шифрованияБезопасностьСовместимостьРекомендация 2025
AES256-CTS-HMAC-SHA1-96ВысокаяWindows 7+✅ Обязательно
AES128-CTS-HMAC-SHA1-96ВысокаяWindows 7+✅ Рекомендуется
RC4-HMACНизкаяВсе версии❌ Запрещено
DES-CBC-MD5Очень низкаяLegacy❌ Запрещено

Event ID 4776 — NTLM аутентификация

Статистика использования NTLM в RDP (2025):

  • Новые развертывания: < 1%
  • Миграционные сценарии: 5-15%
  • Устаревшие системы: 20-40%
  • Аварийные сценарии: 1-2%

Рекомендации по аудиту:

# Включение аудита NTLM
AuditPol /set /subcategory:"Logon" /success:enable /failure:enable
AuditPol /set /subcategory:"Other Logon/Logoff Events" /success:enable /failure:enable

3.3 Дополнительные Security-события

Event ID 1102 — Очистка журнала аудита

Индикаторы компрометации:

  1. Очистка после успешного входа (4624)
  2. Очистка в нерабочее время
  3. Частые очистки (более 1 в день)
  4. Очистка разными учетными записями

Мониторинговая запрос:

SELECT 
    TimeGenerated,
    EventID,
    Computer,
    TargetUserName,
    COUNT(*) as ClearCount
FROM SecurityEvents 
WHERE EventID = 1102 
    AND TimeGenerated > NOW() - INTERVAL '7 days'
GROUP BY Computer, TargetUserName
HAVING COUNT(*) > 1

Event ID 4627 — Сведения о групповом членстве

Важные группы для RDP-аудита:

  • Remote Desktop Users — базовый доступ
  • Administrators — полный доступ
  • Remote Management Users — WinRM + RDP
  • Domain Admins — привилегированный доступ
  • Protected Users — ограниченный доступ (Windows 8.1+)

Event ID 4672 — Особые привилегии

Критичные привилегии для RDP:

ПривилегияОписаниеРиск
SeDebugPrivilegeОтладка процессовВысокий
SeTcbPrivilegeАкт как часть ОСКритичный
SeBackupPrivilegeРезервное копированиеСредний
SeRestorePrivilegeВосстановлениеСредний
SeTakeOwnershipPrivilegeВзятие владенияВысокий

4. RDS-журналы: LocalSessionManager и RemoteConnectionManager

4.1 TerminalServices-LocalSessionManager

Полный жизненный цикл сессии:

stateDiagram-v2
    [*] --> Created : Event 22
    Created --> Connected : Event 21
    Connected --> Active
    Active --> Disconnected : Event 23
    Disconnected --> Connected : Event 25
    Active --> Ended : Event 24
    Disconnected --> Ended : Event 24
    Ended --> [*]

    note left of Created
        Время: SessionCreateTime
        Пользователь: User
        Источник: SourceNetworkAddress
    end note

    note right of Ended
        Причины: 0 - Normal
        1 - Admin
        2 - Timeout
        3 - ClientRequest
    end note

Event ID 21 — Remote Desktop Services: вход в сессию

Детали события:

  • Источник: Microsoft-Windows-TerminalServices-LocalSessionManager
  • Уровень: 4 (Information)
  • Задача: 0 (Session Start)

Пример XML:

<EventData>
  <Data Name="User">CONTOSO\jsmith</Data>
  <Data Name="SessionID">2</Data>
  <Data Name="SourceNetworkAddress">192.168.1.100</Data>
  <Data Name="SessionName">RDP-Tcp#1</Data>
</EventData>

Event ID 22 — Создание новой сессии

Связь с Security-событиями:

Time Sequence:
  Security 4624 (10:30:00.100) → Аутентификация
  LSM 22 (10:30:00.500) → Создание сессии  
  LSM 21 (10:30:01.000) → Подключение к сессии

Event ID 23 — Отключение сессии

Коды причины отключения:

КодОписаниеЧастота
0Нет информации30%
1Инициировано клиентом40%
2Тихий разрыв5%
4Таймаут клиента15%
5Разрыв соединения10%

Event ID 24 — Выход из сессии

Статистика длительности сессий (2025):

  • Средняя: 2 часа 15 минут
  • Медианная: 1 час 30 минут
  • 90-й перцентиль: 4 часа
  • 99-й перцентиль: 8+ часов

Event ID 25 — Переподключение

Паттерны переподключения:

  • Нормальный: 1-3 раза в день
  • Проблемный: >5 раз в час
  • Злоумышленник: Быстрые reconnect для обхода idle-таймаута

Event ID 39/40 — Детализированные состояния

Event 39 (Session Start Details):

  • InitialProgram — запускаемая программа
  • ClientName — имя клиента
  • ClientAddress — IP-адрес
  • ClientBuildNumber — версия клиента

Event 40 (Session End Details):

  • Duration — длительность сессии
  • IdleTime — время простоя
  • DisconnectReason — причина отключения

4.2 TerminalServices-RemoteConnectionManager

Event ID 1149 — Инициализация RDP-подключения

Технические детали:

  • Генерируется до аутентификации
  • Содержит информацию о протоколе и шифровании
  • Полезно для обнаружения сканирования портов

Пример данных:

Address: 192.168.1.100
Protocol: TLS 1.2
CipherSuite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

Event ID 1150 — Разрыв соединения

Анализ причин разрыва:

SELECT 
    COUNT(*) as TotalEvents,
    ReasonCode,
    AVG(Duration) as AvgDuration
FROM RCM_Events
WHERE EventID = 1150
    AND TimeGenerated > NOW() - INTERVAL '30 days'
GROUP BY ReasonCode
ORDER BY TotalEvents DESC

5. RDPCoreTS, System и NLA/CredSSP события

5.1 RDPCoreTS события

Архитектура протокола RDP:

graph TB
    subgraph "RDP Stack"
        A[Application Layer] --> B[Virtual Channels]
        B --> C[Core Protocol]
        C --> D[Security Layer]
        D --> E[Transport]
    end

    subgraph "Event Sources"
        F[RDPCoreTS 98-199] --> G[Protocol Errors]
        H[RDPCoreTS 200-299] --> I[Performance Stats]
        J[System Log] --> K[TLS/Schannel]
    end

    E --> TCP
    G --> A
    I --> B
    K --> D

Event ID 98 — Ошибка инициализации

Распространенные ошибки:

  • 0x8007052E — Логион-сессия недоступна
  • 0x80090326 — Неверные учетные данные
  • 0x8009030D — Ошибка контекста безопасности

Event ID 131 — Инициализация подключения

Данные соединения:

{
  "Connection": {
    "ClientIP": "192.168.1.100",
    "ClientPort": 56842,
    "ServerIP": "10.0.0.10",
    "ServerPort": 3389,
    "Protocol": "TCP",
    "MTU": 1500,
    "WindowSize": 65535
  },
  "Security": {
    "ProtocolVersion": "RDP 10.9",
    "EncryptionLevel": "FIPS",
    "ServerCertificate": {
      "Issuer": "CN=Contoso-CA",
      "Expiration": "2026-12-31"
    }
  }
}

Event ID 140 — Ошибки шифрования

Классификация ошибок:

КатегорияКоды ошибокВоздействие
TLS Handshake0x80090326, 0x8009030DБлокировка подключения
Certificate0x800B0109, 0x800B010AПредупреждение/Блокировка
Protocol0x80090331, 0x80090332Деградация безопасности

5.2 NLA/CredSSP события

Architecture Diagram:

sequenceDiagram
    participant C as Client
    participant S as Server
    participant DC as Domain Controller

    C->>S: TCP Connection
    S-->>C: Server Capabilities
    C->>S: NLA Request
    S->>DC: Authentication Request
    DC-->>S: Authentication Result
    alt Success
        S-->>C: NLA Success
        C->>S: CredSSP Encryption
        S-->>C: Session Data
    else Failure
        S-->>C: NLA Failure
        Note over C,S: Connection Closed
    end

Schannel события (System Log)

Ключевые Event ID:

Event IDУровеньОписаниеВлияние на RDP
36874ErrorTLS Handshake Failure❌ Блокировка
36888WarningWeak Cipher Suite⚠️ Деградация
36871InformationTLS Connection Established✅ Успех
36872InformationTLS Connection Closedℹ️ Нормальное завершение

Конфигурация TLS для RDP 2025:

# Минимальные требования
$TLSConfig = @{
    "TLS 1.2" = "Enabled"
    "TLS 1.3" = "Enabled"
    "TLS 1.0" = "Disabled"
    "TLS 1.1" = "Disabled"
    "SSL 2.0" = "Disabled"
    "SSL 3.0" = "Disabled"

    "Cipher Suites" = @(
        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"
    )

    "Certificate Requirements" = @{
        "MinKeySize" = "2048"
        "HashAlgorithm" = "SHA256"
        "OCSP" = "Required"
        "CRL" = "Required"
    }
}

TermService события

Event ID 1000-1010:

  • 1000: Служба терминалов запущена
  • 1001: Служба терминалов остановлена
  • 1002: Ошибка инициализации службы
  • 1003: Проблемы с лицензированием

Мониторинг здоровья службы:

# PowerShell мониторинг
$ServiceHealth = Get-Service -Name TermService | 
    Select-Object Status, StartType, CanPauseAndContinue

$EventLog = Get-WinEvent -LogName "System" -MaxEvents 100 |
    Where-Object {$_.ProviderName -eq "TermService"} |
    Select-Object TimeCreated, Id, LevelDisplayName, Message

KDC события (Domain Controllers)

Для RDP релевантные события:

  • 27: TGS Request (часто для TERMSRV SPN)
  • 2: AS Request (начало аутентификации)
  • 4: Ticket Renewal (продление билетов)

6. Gateway, Broker и Licensing события

6.1 RD Gateway события

Архитектура Gateway:

graph LR
    A[Internet Client] -->|HTTPS 443| B[RD Gateway]
    B -->|RDP 3389| C[Internal Server 1]
    B -->|RDP 3389| D[Internal Server 2]
    B -->|RDP 3389| E[Internal Server 3]

    subgraph "Gateway Logs"
        F[Connection Events]
        G[Auth Events]
        H[Policy Events]
    end

    B --> F
    B --> G
    B --> H

Журнал TerminalServices-Gateway

Структура событий:

<!-- Пример события 300 -->
<EventData>
  <Data Name="ConnectionID">{GUID}</Data>
  <Data Name="GatewayIP">203.0.113.1</Data>
  <Data Name="ClientIP">192.168.1.100</Data>
  <Data Name="Protocol">HTTPS</Data>
  <Data Name="Target">10.0.0.10:3389</Data>
  <Data Name="User">CONTOSO\jsmith</Data>
  <Data Name="AuthMethod">SmartCard</Data>
</EventData>

Основные Event ID:

Event IDОписаниеВажность
300Успешное подключениеHigh
301Подключение закрытоMedium
302Ошибка аутентификацииHigh
303Нарушение политикиHigh
400-499ДиагностикаLow

Аналитика трафика через Gateway:

-- Статистика по пользователям
SELECT 
    User,
    COUNT(*) as ConnectionCount,
    AVG(Duration) as AvgDuration,
    MIN(TimeCreated) as FirstConnection,
    MAX(TimeCreated) as LastConnection
FROM GatewayEvents
WHERE EventID = 300
    AND TimeCreated > NOW() - INTERVAL '30 days'
GROUP BY User
HAVING COUNT(*) > 10
ORDER BY ConnectionCount DESC

6.2 Session Broker события

Схема работы брокера:

graph TB
    A[Client] --> B[RD Connection Broker]
    B --> C{Load Balancing}
    C -->|Session 1| D[RDSH Server 1]
    C -->|Session 2| E[RDSH Server 2]
    C -->|Session 3| F[RDSH Server 3]

    D --> G[LocalSessionManager]
    E --> H[LocalSessionManager]
    F --> I[LocalSessionManager]

    subgraph "Broker Logs"
        J[Redirection Events]
        K[Session State]
        L[Health Events]
    end

    B --> J
    B --> K
    B --> L

Журнал TerminalServices-SessionBroker

Ключевые события:

  • 1001: Перенаправление сессии
  • 1100-1199: Балансировка нагрузки
  • 1200-1299: Состояние сессий
  • 2000-2099: Ошибки брокера

Event 1001 — Session Redirect:

{
  "Event": {
    "User": "CONTOSO\\jsmith",
    "SessionID": "S-1-5-21-...",
    "SourceServer": "BROKER01",
    "TargetServer": "RDSH02",
    "Reason": "LoadBalancing",
    "ConnectionType": "AutoReconnect",
    "ClientIP": "192.168.1.100"
  }
}

6.3 Licensing события

Архитектура лицензирования:

graph TB
    A[RDSH Server] --> B{License Check}
    B -->|No License| C[License Server]
    C --> D[Issue License]
    D --> E[Store in Database]

    subgraph "License Types"
        F[Per User CAL]
        G[Per Device CAL]
        H[RDS SAL]
    end

    C --> F
    C --> G
    C --> H

    subgraph "Monitoring"
        I[License Events]
        J[Usage Reports]
        K[Compliance]
    end

    C --> I
    E --> J
    F & G & H --> K

Журнал TerminalServices-Licensing

Критичные события:

Event IDУровеньОписаниеДействие
44ErrorОшибка базы данныхНемедленно
100WarningЛицензия скоро истечетПланирование
101InformationЛицензия выданаМониторинг
102ErrorНет доступных лицензийНемедленно
103WarningИспользование > 80%Планирование

Event 44 — Database Error:

<EventData>
  <Data Name="ErrorCode">0x80004005</Data>
  <Data Name="Database">C:\Windows\System32\LServer\TLSLicenseServer.edb</Data>
  <Data Name="Operation">LicenseIssue</Data>
  <Data Name="User">CONTOSO\jsmith</Data>
  <Data Name="Client">192.168.1.100</Data>
</EventData>

Мониторинг лицензий:

# PowerShell для мониторинга лицензий
$LicenseInfo = Get-WmiObject -Class Win32_TSLicenseKeyPack |
    Select-Object ProductVersion, TypeAndModel, AvailableLicenses, IssuedLicenses

$LicenseEvents = Get-WinEvent -LogName "Microsoft-Windows-TerminalServices-Licensing" |
    Where-Object {$_.Level -le 3} |  # Error and Warning
    Select-Object TimeCreated, Id, LevelDisplayName, Message

7. Firewall и Network события

7.1 Windows Firewall события

Схема фильтрации RDP-трафика:

graph TD
    A[Incoming RDP Traffic] --> B{Firewall Rules}
    B -->|Allow| C[Security Event 2003]
    B -->|Block| D[Security Event 2005]

    C --> E[Port 3389/TCP Open]
    E --> F[TermService Listener]

    D --> G[Connection Dropped]
    G --> H[No Further Events]

    subgraph "Firewall Log Locations"
        I[Event Log]
        J[Text Log pfirewall.log]
        K[ETW Tracing]
    end

    B --> I
    B --> J
    B --> K

Event ID 2003-2006

Формат событий:

<!-- Event 2003 - Allowed Inbound -->
<EventData>
  <Data Name="Direction">Inbound</Data>
  <Data Name="SourceAddress">192.168.1.100</Data>
  <Data Name="SourcePort">56842</Data>
  <Data Name="DestAddress">10.0.0.10</Data>
  <Data Name="DestPort">3389</Data>
  <Data Name="Protocol">TCP</Data>
  <Data Name="FilterRTID">123456</Data>
  <Data Name="LayerName">Transport</Data>
  <Data Name="LayerRTID">789012</Data>
</EventData>

Корреляция с Security событиями:

Временная последовательность:
  1. Firewall 2003 (Allowed Inbound) - T0
  2. RCM 1149 (RDP Client Active) - T0 + 100ms
  3. Security 4624/4625 - T0 + 1-3s
  4. LSM 21/22 - T0 + 3-5s

Текстовый лог pfirewall.log

Формат записи:

#Fields: date time action protocol src-ip dst-ip src-port dst-port size tcpflags tcpsyn tcpack tcpwin icmptype icmpcode info path
2025-01-15 10:30:00 ALLOW TCP 192.168.1.100 10.0.0.10 56842 3389 0 - - - - - - - -
2025-01-15 10:30:01 DROP TCP 203.0.113.5 10.0.0.10 12345 3389 0 - - - - - - - -

Настройка логирования:

# Включение логирования в файл
netsh advfirewall set currentprofile logging filename "C:\Windows\System32\LogFiles\Firewall\pfirewall.log"
netsh advfirewall set currentprofile logging allowedconnections enable
netsh advfirewall set currentprofile logging droppedconnections enable
netsh advfirewall set currentprofile logging maxfilesize 40960

7.2 Сетевые события TCP/IP

Event ID 1001 — TCP Connection Created

Детали подключения:

{
  "Connection": {
    "LocalEndpoint": {
      "Address": "10.0.0.10",
      "Port": 3389,
      "Protocol": "TCP"
    },
    "RemoteEndpoint": {
      "Address": "192.168.1.100",
      "Port": 56842,
      "Protocol": "TCP"
    },
    "Process": {
      "Id": 1234,
      "Name": "svchost.exe",
      "Service": "TermService"
    },
    "Timestamps": {
      "Created": "2025-01-15T10:30:00.123Z",
      "LastActivity": "2025-01-15T10:30:00.123Z"
    }
  }
}

Анализ сетевой активности RDP

Метрики для мониторинга:

-- Активные RDP-подключения
SELECT 
    LocalAddress,
    LocalPort,
    RemoteAddress,
    RemotePort,
    State,
    ProcessId,
    COUNT(*) as ConnectionCount
FROM TCPConnections
WHERE LocalPort = 3389
    AND State IN ('ESTABLISHED', 'TIME_WAIT')
GROUP BY LocalAddress, RemoteAddress
HAVING COUNT(*) > 1

7.3 Сторонние Firewall/UTM

Пример событий Sophos XG:

{
  "timestamp": "2025-01-15T10:30:00Z",
  "event_type": "firewall_traffic",
  "action": "drop",
  "src_ip": "203.0.113.5",
  "dst_ip": "10.0.0.10",
  "dst_port": 3389,
  "protocol": "TCP",
  "rule_id": "RDP_BLOCK",
  "reason": "Geo-block: Russia",
  "app": "RDP",
  "threat": "Brute force attempt"
}

Интеграция с SIEM:

  • Формат: CEF/LEEF/Syslog
  • Поля: src_ip, dst_ip, dst_port, action, reason
  • Корреляция: по времени и IP-адресу

8. Клиентские журналы RDP

8.1 TerminalServices-RDPClient

Архитектура клиентского логирования:

graph TD
    A[mstsc.exe] --> B[RDP Client Stack]
    B --> C[Connection Manager]
    B --> D[UI Layer]
    B --> E[Protocol Handler]

    C --> F[Event 1024: Connect]
    D --> G[Event 1025: Disconnect]
    E --> H[Event 1026-1030: Errors]

    subgraph "Client Log Locations"
        I[Event Log]
        J[%LOCALAPPDATA%\Temp]
        K[Tracing Files]
    end

    F & G & H --> I
    E --> J
    B --> K

Event ID 1024 — Client Active/Connect

Данные подключения:

<EventData>
  <Data Name="Server">10.0.0.10:3389</Data>
  <Data Name="ProtocolVersion">10.9</Data>
  <Data Name="ConnectionType">Desktop</Data>
  <Data Name="ColorDepth">32</Data>
  <Data Name="Resolution">1920x1080</Data>
  <Data Name="Redirection">
    <Data>Drives</Data>
    <Data>Printers</Data>
    <Data>Clipboard</Data>
  </Data>
</EventData>

Event ID 1025-1030 — Ошибки подключения

Классификация ошибок клиента:

Event IDКод ошибкиОписаниеПричина
10250x4Server Not FoundDNS/Networking
10260x5Access DeniedCredentials/Policy
10270x6License ErrorLicensing Issue
10280x7Protocol ErrorVersion Mismatch
10290x8TimeoutNetwork Latency
10300x9Crypto ErrorCertificate Issue

8.2 Дополнительные клиентские артефакты

Файлы RDP-подключений

%USERPROFILE%\Documents\Default.rdp
%USERPROFILE%\Documents\*.rdp
%APPDATA%\Microsoft\Windows\Recent\AutomaticDestinations\*.automaticDestinations-ms

Реестр клиента

HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client
    \Default
        MRU0 = "10.0.0.10"
        MRU1 = "192.168.1.50"

    \Servers
        \10.0.0.10
            UsernameHint = "jsmith"

9. Рекомендуемая стратегия сбора и нормализации

9.1 Технический анализ событий RDP-подключений в Windows

9.1.1. События аутентификации (Security Events)

Ключевые Event ID:

  • 4624/4625 — Успешные/неудачные попытки входа
  • 4778/4779 — События NLA (Network Level Authentication)
  • 4768/4769 — Kerberos TGS-билеты для RDP

Сильные стороны:

  • Полная картина аутентификации — от попытки входа до выдачи билетов
  • Информация об источнике (IP, компьютер, учетная запись)
  • Причины неудач (пароль, учетная запись заблокирована, истечение срока действия)
  • Интеграция с Active Directory для отслеживания доменных учетных записей

Слабые стороны:

  • Высокий объем в крупных средах (требуется агрегация)
  • Отсутствие деталей сессии после успешной аутентификации
  • Ложные срабатывания при автоматических переподключениях

Нюансы:

  • События 4778/4779 генерируются только при включенном NLA (рекомендуется)
  • Event ID 4768/4769 требуют аудита Kerberos Service Ticket Operations
  • Для атрибуции пользователей необходим мониторинг обоих типов событий

9.1.2. События сессий и подключений

Ключевые журналы:

  • TerminalServices-LocalSessionManager (Event ID 21, 22, 23, 24, 25)
  • RemoteConnectionManager (Event ID 1149, 1150, 1151, 1152)

Сильные стороны:

  • Точная временная метка начала/окончания сессии
  • Идентификатор сессии для корреляции с другими событиями
  • Тип подключения (консольное, RDP, служебное)
  • Информация о переподключении существующих сессий

Слабые стороны:

  • Отсутствие сетевых деталей (IP-адрес источника в некоторых событиях)
  • Сложность отслеживания нескольких одновременных подключений
  • Ограниченная информация о клиентском устройстве

Нюансы:

  • Event ID 25 (переподключение к существующей сессии) критичен для обнаружения hijacking
  • Event ID 23/24 (отключение/подключение) часто используются для расчета времени сессии
  • Для ферм серверов требуется мониторинг на каждом узле

9.1.3. События инфраструктуры RDS

Ключевые компоненты:

  • RD Gateway (шлюз удаленного рабочего стола)
  • Session Broker (балансировка нагрузки)
  • Лицензирование RDP

Сильные стороны:

  • Централизованный мониторинг для ферм серверов
  • Обнаружение аномалий в шаблонах подключений
  • Контроль лицензий и предотвращение нарушений compliance
  • Мониторинг производительности шлюза

Слабые стороны:

  • Сложность настройки корреляции между компонентами
  • Зависимость от архитектуры развертывания
  • Высокий порог входа для правильной интерпретации

Нюансы:

  • События шлюза (300-304) критичны для гибридных сред
  • Session Broker события требуют понимания топологии фермы
  • Лицензионные события (Event ID 44) указывают на потенциальные проблемы compliance

9.1.4. Сетевые и брандмауэрные события

Ключевые источники:

  • Брандмауэр Windows (Event ID 2003-2006)
  • Фильтрация подключений (Security Event ID 5156)
  • Протокольные события RDP

Сильные стороны:

  • Обнаружение сканирования портов и bruteforce
  • Геолокация атак по IP-адресам
  • Контроль политик доступа в реальном времени
  • Мониторинг аномального трафика

Слабые стороны:

  • Очень высокий объем в публичных средах
  • Недостаток контекста приложения
  • Сложность фильтрации легитимного трафика

Нюансы:

  • Event ID 5156 предоставляет детальную информацию о фильтрации на уровне процесса
  • Брандмауэрные события требуют настройки аудита успешных/неудачных подключений
  • Протокольные события RDP полезны для диагностики, но создают шум

9.1.5. Матрица приоритетов сбора RDP-событий

quadrantChart
    title RDP Events Collection Priority Matrix 2025
    x-axis "Low Frequency" --> "High Frequency"
    y-axis "Low Value" --> "High Value"
    quadrant-1 " "
    quadrant-2 " "
    quadrant-3 "Low Value / Low Frequency"
    quadrant-4 "Low Value / High Frequency"

    %% КВАДРАНТ I: Высокая ценность, Высокая частота
    "4624/4625": [0.95, 0.95]
    "LSM21-25": [0.85, 0.92]
    "FW2003-2006": [0.92, 0.85]
    "RCM1149": [0.88, 0.88]
    "4634/4647": [0.75, 0.82]
    "4778/4779": [0.65, 0.75]
    "RDPC131": [0.72, 0.78]
    "GW300": [0.82, 0.8]
    "4768/4771": [0.68, 0.9]

    %% КВАДРАНТ II: Высокая ценность, Низкая частота
    "1102": [0.05, 0.95]
    "4648": [0.12, 0.92]
    "Lic44": [0.08, 0.88]
    "4769/4776": [0.15, 0.85]
    "4672": [0.1, 0.82]
    "GW302-303": [0.18, 0.9]
    "BRK1001": [0.22, 0.78]
    "4627": [0.25, 0.72]
    "4635": [0.28, 0.68]

    %% КВАДРАНТ III: Низкая ценность, Низкая частота
    "Sys7036": [0.05, 0.05]
    "SysTLS": [0.15, 0.15]
    "RDPC50": [0.25, 0.25]
    "GW310": [0.35, 0.35]
    "Lic202": [0.45, 0.45]
    "1000": [0.1, 0.3]
    "39/40": [0.3, 0.1]
    "1025": [0.2, 0.2]

    %% КВАДРАНТ IV: Низкая ценность, Высокая частота
    "RDPC200": [0.95, 0.05]
    "RDPC98": [0.85, 0.15]
    "FW_traffic": [0.75, 0.08]
    "TCP_KA": [0.65, 0.12]
    "Heartbeat": [0.55, 0.18]
    "1024": [0.6, 0.25]
    "Perf": [0.7, 0.22]
    "NLA_Info": [0.8, 0.1]

9.1.6. Рекомендации по внедрению:

1. Критические события (Квадрант I)

Сбор в реальном времени с агрегацией:

  • Включить во все SIEM-правила корреляции
  • Настроить оповещения на аномалии (ночные подключения, множественные неудачи)
  • Хранить не менее 90 дней для расследований инцидентов
2. Приоритетные события (Квадрант II)

Сбор с высокой детализацией:

  • Мониторинг в режиме near-real-time
  • Особое внимание к событиям очистки журналов (1102) — возможный признак сокрытия взлома
  • Интеграция с системами управления привилегированными доступами
3. Фоновые события (Квадрант III)

Выборочный сбор и хранение:

  • Достаточно суточных агрегатов для трендов
  • Полезны для capacity planning и диагностики
  • Хранение 30-60 дней
4. Шумовые события (Квадрант IV)

Агрегированный сбор или исключение:

  • Использовать sampling для анализа трендов
  • Возможно исключение из централизованного сбора
  • Рассмотреть локальное хранение с коротким сроком

Оптимизация в 2025 году:

  1. Интеллектуальная фильтрация на основе машинного обучения для выделения аномалий
  2. Контекстуальное обогащение событий данными из CMDB и Active Directory
  3. Автоматическая классификация сессий (административные, пользовательские, служебные)
  4. Интеграция с Zero Trust платформами для динамической оценки рисков
  5. Использование ETW для снижения нагрузки вместо традиционного EventLog

Данная стратегия обеспечивает баланс между полнотой мониторинга и производительностью системы, что особенно критично в современных распределенных и гибридных средах.

9.2 Минимальный набор для RdpMon++

Уровень 1 (Базовый мониторинг):

event_sources:
  security:
    - 4624  # Successful logon
    - 4625  # Failed logon
    - 4634  # Logoff
    - 4647  # User-initiated logoff
    - 4648  # Explicit credentials

  terminal_services:
    - LSM: [21, 22, 23, 24, 25]  # Session management
    - RCM: [1149]                # Connection start

  firewall:
    - 2003  # Allowed inbound
    - 2005  # Blocked inbound

Уровень 2 (Расширенная безопасность):

event_sources:
  security_extended:
    - 4768  # Kerberos TGT
    - 4769  # Kerberos TGS
    - 4771  # Kerberos pre-auth failure
    - 4776  # NTLM authentication
    - 4778  # Session reconnect
    - 4779  # Session disconnect

  protocol:
    - RDPCoreTS: [98, 131, 140]  # Protocol errors

  nla:
    - System: [36874, 36888]     # TLS/Schannel

Уровень 3 (Полное покрытие):

event_sources:
  enterprise:
    - Gateway: [300, 302, 303]    # RD Gateway
    - Broker: [1001, 1100-1199]   # Session Broker
    - Licensing: [44, 100-103]    # RDS Licensing
    - Client: [1024-1030]         # RDP Client

9.3 Логическая модель данных

Нормализованная схема событий

CREATE TABLE rdp_events_normalized (
    -- Идентификация
    event_id UUID PRIMARY KEY,
    correlation_id UUID,

    -- Источник
    source_system VARCHAR(50),
    original_event_id INTEGER,
    provider_name VARCHAR(100),

    -- Временные метки
    event_time TIMESTAMPTZ,
    ingested_time TIMESTAMPTZ DEFAULT NOW(),

    -- Учетные данные
    user_name VARCHAR(255),
    user_domain VARCHAR(255),
    user_sid VARCHAR(255),

    -- Сессия
    logon_type INTEGER,
    session_id VARCHAR(100),
    session_name VARCHAR(100),

    -- Сеть
    source_ip INET,
    source_port INTEGER,
    destination_ip INET,
    destination_port INTEGER,

    -- Аутентификация
    auth_protocol VARCHAR(50),
    status_code VARCHAR(50),
    sub_status VARCHAR(50),

    -- Обогащенные данные
    geo_country VARCHAR(2),
    geo_city VARCHAR(100),
    threat_score INTEGER,

    -- Оригинал
    raw_xml TEXT,
    metadata JSONB
);

-- Индексы
CREATE INDEX idx_rdp_events_time ON rdp_events_normalized USING BRIN(event_time);
CREATE INDEX idx_rdp_events_user ON rdp_events_normalized(user_name, user_domain);
CREATE INDEX idx_rdp_events_ip ON rdp_events_normalized(source_ip);
CREATE INDEX idx_rdp_events_session ON rdp_events_normalized(session_id);
CREATE INDEX idx_rdp_events_correlation ON rdp_events_normalized(correlation_id);

Агрегированные представления

IP-агрегаты (ежедневные):

CREATE MATERIALIZED VIEW ip_aggregates_daily AS
SELECT 
    source_ip,
    DATE(event_time) as event_date,
    COUNT(*) as total_events,
    COUNT(DISTINCT user_name) as unique_users,
    SUM(CASE WHEN original_event_id = 4624 THEN 1 ELSE 0 END) as success_logons,
    SUM(CASE WHEN original_event_id = 4625 THEN 1 ELSE 0 END) as failed_logons,
    MIN(event_time) as first_seen,
    MAX(event_time) as last_seen,
    MODE() WITHIN GROUP (ORDER BY geo_country) as common_country
FROM rdp_events_normalized
WHERE event_time > NOW() - INTERVAL '30 days'
GROUP BY source_ip, DATE(event_time);

Сессионная аналитика:

CREATE VIEW session_analytics AS
WITH session_events AS (
    SELECT 
        session_id,
        user_name,
        user_domain,
        source_ip,
        MIN(event_time) as session_start,
        MAX(event_time) as session_end,
        COUNT(*) as event_count,
        ARRAY_AGG(DISTINCT original_event_id) as event_types
    FROM rdp_events_normalized
    WHERE session_id IS NOT NULL
    GROUP BY session_id, user_name, user_domain, source_ip
)
SELECT 
    *,
    EXTRACT(EPOCH FROM (session_end - session_start)) as duration_seconds,
    CASE 
        WHEN 4778 = ANY(event_types) THEN TRUE 
        ELSE FALSE 
    END as had_reconnect,
    CASE 
        WHEN 4779 = ANY(event_types) THEN TRUE 
        ELSE FALSE 
    END as had_disconnect
FROM session_events;

9.4 Пайплайн обработки событий

flowchart TD
    A[Raw Event Sources] --> B{Event Router}
    
    B --> C[Security Events]
    B --> D[Terminal Services]
    B --> E[Firewall Events]
    B --> F[Other Sources]
    
    C --> G[Parser & Normalizer]
    D --> G
    E --> G
    F --> G
    
    G --> H[Enrichment Engine]
    H --> I[GeoIP Lookup]
    H --> J[Threat Intel]
    H --> K[User Context]
    
    I & J & K --> L[Correlation Engine]
    L --> M[Session Builder]
    L --> N[Threat Detector]
    
    M --> O[Session Database]
    N --> P[Alert Generator]
    
    O --> Q[Analytics & Reporting]
    P --> R[SIEM Integration]
    
    Q --> S[Dashboards]
    R --> T[Security Alerts]

10. Архитектура сбора событий RDP

10.1 Современные механизмы сбора

ETW (Event Tracing for Windows)

// Пример подписки на ETW события RDP
using (var session = new TraceEventSession("RdpMonitoringSession"))
{
    // Подписка на Security события
    session.EnableProvider(
        "Microsoft-Windows-Security-Auditing",
        TraceEventLevel.Verbose,
        0xFFFFFFFFFFFFFFFF,
        new TraceEventProviderOptions
        {
            EventIDs = "4624-4625,4634,4647,4648,4768-4779"
        });

    // Подписка на Terminal Services
    session.EnableProvider(
        "Microsoft-Windows-TerminalServices-LocalSessionManager",
        TraceEventLevel.Informational);

    session.Source.Dynamic.All += eventData =>
    {
        // Обработка события
        ProcessRdpEvent(eventData);
    };

    session.Source.Process();
}

EventLog API (для исторических данных)

# PowerShell сбор исторических событий
$Events = Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4624,4625,4634,4647,4648
    StartTime = (Get-Date).AddDays(-1)
} -MaxEvents 10000

$Events | ForEach-Object {
    $xml = [xml]$_.ToXml()
    # Обработка XML
}

10.2 Приоритеты сбора 2025

Таблица приоритетов:

УровеньИсточникиМеханизмЧастотаRetention
P0Security 4624/4625ETW Real-time100%90 дней
P1LSM 21-25, RCM 1149ETW Real-time100%60 дней
P2Firewall 2003-2006ETW Buffered100%30 дней
P3Kerberos 4768-4771EventLog Polling100%30 дней
P4Gateway, BrokerEventLog Polling100%30 дней
P5RDPCoreTS, SystemEventLog Sampling10%14 дней

10.3 Распределенная архитектура

graph TB
    subgraph "Agents (Windows Servers)"
        A1[Agent 1: RDSH01]
        A2[Agent 2: RDSH02]
        A3[Agent 3: Gateway]
        A4[Agent 4: Broker]
    end
    
    subgraph "Collector Tier"
        B1[Event Collector 1]
        B2[Event Collector 2]
        B3[Load Balancer]
    end
    
    subgraph "Processing Tier"
        C1[Parser]
        C2[Enricher]
        C3[Correlator]
    end
    
    subgraph "Storage Tier"
        D1[Hot: TimescaleDB]
        D2[Warm: EventStoreDB]
        D3[Cold: S3 + RocksDB]
    end
    
    subgraph "Analytics Tier"
        E1[Real-time Alerts]
        E2[Dashboards]
        E3[Reports]
    end
    
    A1 & A2 & A3 & A4 --> B3
    B3 --> B1 & B2
    B1 & B2 --> C1
    C1 --> C2 --> C3
    C3 --> D1 & D2 & D3
    D1 --> E1 & E2 & E3

11. Блок-схема генерации событий RDP

11.1 Полная последовательность событий

sequenceDiagram
    participant Client
    participant Firewall
    participant Gateway
    participant NLA
    participant DC as Domain Controller
    participant RCM as RemoteConnectionManager
    participant LSM as LocalSessionManager
    participant Security
    participant RDPCore
    participant Broker
    participant Licensing
    
    Note over Client,Licensing: Этап 1: Сетевое подключение
    Client->>Firewall: TCP SYN:3389
    Firewall-->>Firewall: Event 2003/2005
    Firewall->>RCM: TCP Handshake
    RCM-->>RCM: Event 1149 (RDP Client Active)
    
    Note over Client,Licensing: Этап 2: NLA/TLS Negotiation
    RCM->>NLA: NLA Request
    NLA->>DC: Authentication Request
    DC-->>NLA: Authentication Result
    alt NLA Success
        NLA-->>Security: Event 4768/4769 (Kerberos)
        NLA-->>RDPCore: TLS Established
    else NLA Failure
        NLA-->>RDPCore: Event 140 (Error)
        NLA-->>Security: Event 4771/4776 (Failure)
    end
    
    Note over Client,Licensing: Этап 3: Аутентификация
    RCM->>Security: Logon Request
    alt Authentication Success
        Security-->>Security: Event 4624 (Success)
        Security->>Licensing: License Check
        Licensing-->>Licensing: Event 101 (Issued)
    else Authentication Failure
        Security-->>Security: Event 4625 (Failure)
    end
    
    Note over Client,Licensing: Этап 4: Сессия и балансировка
    alt Through Gateway
        Client->>Gateway: HTTPS Connect
        Gateway-->>Gateway: Event 300 (Gateway Connect)
        Gateway->>Broker: Session Request
    else Direct Connection
        RCM->>Broker: Session Request
    end
    
    Broker-->>Broker: Event 1001 (Session Redirect)
    Broker->>LSM: Create Session
    
    Note over Client,Licensing: Этап 5: Создание сессии
    LSM-->>LSM: Event 22 (Session Create)
    LSM-->>LSM: Event 21 (Session Connect)
    LSM-->>Security: Session Established
    Security-->>Security: Event 4624 (LogonType 10)
    
    Note over Client,Licensing: Этап 6: Активная сессия
    loop Периодические события
        RDPCore-->>RDPCore: Event 200 (Stats)
        LSM-->>LSM: Heartbeat
    end
    
    Note over Client,Licensing: Этап 7: Отключение/Переподключение
    alt Client Disconnect
        Client->>LSM: Disconnect
        LSM-->>LSM: Event 23 (Disconnect)
        LSM-->>Security: Event 4779 (Disconnected)
    end
    
    alt Client Reconnect
        Client->>LSM: Reconnect
        LSM-->>LSM: Event 25 (Reconnect)
        LSM-->>Security: Event 4778 (Reconnected)
    end
    
    Note over Client,Licensing: Этап 8: Завершение сессии
    alt User Logoff
        Client->>LSM: Logoff
        LSM-->>LSM: Event 24 (Logoff)
        LSM-->>Security: Event 4634 (Logoff)
        Security-->>Security: Event 4647 (User Initiated)
        Licensing-->>Licensing: Event 301 (License Released)
    end
    
    Note over Client,Licensing: Этап 9: Очистка
    RCM-->>RCM: Event 1150 (Connection Closed)
    Firewall-->>Firewall: TCP FIN

11.2 Временные диаграммы

Нормальное подключение:

Time (ms) | Event
----------|------
0         | Firewall 2003
50        | RCM 1149
200       | Security 4768 (Kerberos)
400       | Security 4624 (Success)
600       | LSM 22 (Session Create)
800       | LSM 21 (Session Connect)

Атака подбора паролей:

Time (ms) | Event
----------|------
0         | Firewall 2003
50        | RCM 1149
100       | Security 4625 (Failure - 0xC000006A)
200       | Security 4625 (Failure - 0xC000006A)
300       | Security 4625 (Failure - 0xC000006A)
...       | ...
5000      | Security 4624 (Success - компрометация)

12. Рекомендации по реализации системы мониторинга

12.1 Технологический стек 2025

Рекомендуемый стек:

programming_language: C# 12 / .NET 8
runtime: Windows Service / .NET Worker Service
event_collection: ETW (Microsoft.Diagnostics.Tracing.TraceEvent)
service_management: Topshelf / Windows Service Wrapper
storage_hot: TimescaleDB 2.10+ / PostgreSQL 16
storage_warm: EventStoreDB 22.10+
storage_cold: Azure Blob Storage / AWS S3 + RocksDB
caching: Redis 7.2 / Azure Cache for Redis
message_queue: Azure Service Bus / RabbitMQ
monitoring: Prometheus + Grafana / Azure Monitor
logging: Serilog + Seq / Elastic Stack

12.2 Архитектурные паттерны

Микросервисная архитектура

graph TB
    subgraph "Event Collection"
        A1[ETW Collector]
        A2[EventLog Collector]
        A3[WTS API Collector]
        A4[Firewall Collector]
    end

    subgraph "Event Processing"
        B1[Parser Service]
        B2[Enrichment Service]
        B3[Correlation Service]
        B4[Alert Service]
    end

    subgraph "Data Storage"
        C1[Events DB]
        C2[Sessions DB]
        C3[Aggregates DB]
        C4[Archive Storage]
    end

    subgraph "API Layer"
        D1[REST API]
        D2[GraphQL API]
        D3[gRPC API]
    end

    subgraph "Clients"
        E1[Web Dashboard]
        E2[CLI Tool]
        E3[SIEM Connectors]
        E4[Mobile App]
    end

    A1 & A2 & A3 & A4 --> B1
    B1 --> B2 --> B3 --> B4
    B3 --> C1 & C2 & C3
    C1 --> C4
    C1 & C2 & C3 --> D1 & D2 & D3
    D1 & D2 & D3 --> E1 & E2 & E3 & E4

Конфигурация как код

# config.yaml
version: '3.0'

event_sources:
  security:
    enabled: true
    providers:
      - name: Microsoft-Windows-Security-Auditing
        event_ids: [4624, 4625, 4634, 4647, 4648]
        keywords: 0x8020000000000000

  terminal_services:
    enabled: true
    providers:
      - name: Microsoft-Windows-TerminalServices-LocalSessionManager
        event_ids: [21, 22, 23, 24, 25]
      - name: Microsoft-Windows-TerminalServices-RemoteConnectionManager
        event_ids: [1149, 1150]

storage:
  layers:
    - name: hot
      type: timescaledb
      retention: 7d
      compression: after 1d
    - name: warm
      type: eventstoredb
      retention: 30d
    - name: cold
      type: azure_blob
      retention: 365d

enrichment:
  geoip:
    enabled: true
    database: GeoLite2-City
    update_frequency: weekly

  threat_intel:
    enabled: true
    sources:
      - abuseipdb
      - virustotal
      - alienvault_otx

alerting:
  rules:
    - name: brute_force_detection
      condition: "count(4625) > 10 within 5m by source_ip"
      severity: high
      actions: [email, slack, siem]

    - name: successful_compromise
      condition: "4625 followed by 4624 within 60s same source_ip user"
      severity: critical
      actions: [block_ip, email_admin, siem]

12.3 Производительность и масштабирование

Бенчмарки (2025):

МетрикаОжидаемое значениеМетод достижения
Событий в секунду10,000+Асинхронная обработка
Задержка обработки< 100msIn-memory буферизация
Хранение событий1M+/секTimescaleDB гипартаблицы
Поиск по истории< 1sColumnar индексы
Доступность99.99%Кластеризация + репликация

Оптимизации:

public class HighPerformanceEventProcessor
{
    private readonly Channel<RdpEvent> _eventChannel;
    private readonly IEventStorage _storage;

    public HighPerformanceEventProcessor()
    {
        // Канал с высокой пропускной способностью
        _eventChannel = Channel.CreateBounded<RdpEvent>(
            new BoundedChannelOptions(10000)
            {
                FullMode = BoundedChannelFullMode.Wait,
                SingleWriter = false,
                SingleReader = false
            });
    }

    public async Task ProcessEventsAsync(CancellationToken cancellationToken)
    {
        var tasks = new List<Task>();

        // Множество воркеров для параллельной обработки
        for (int i = 0; i < Environment.ProcessorCount; i++)
        {
            tasks.Add(Task.Run(async () =>
            {
                await foreach (var event in _eventChannel.Reader.ReadAllAsync(cancellationToken))
                {
                    await ProcessSingleEventAsync(event, cancellationToken);
                }
            }, cancellationToken));
        }

        await Task.WhenAll(tasks);
    }

    private async Task ProcessSingleEventAsync(RdpEvent event, CancellationToken cancellationToken)
    {
        // Пакетная запись для оптимизации
        await _storage.BatchInsertAsync(new[] { event }, cancellationToken);
    }
}

12.4 Безопасность реализации

Принципы безопасности:

  1. Минимальные привилегии: Служба работает под отдельной учетной записью
  2. Шифрование данных: TLS 1.3 для передачи, AES-256 для хранения
  3. Аудит доступа: Логирование всех операций с событиями
  4. Валидация входных данных: Проверка XML/JSON перед обработкой
  5. Защита от переполнения: Лимиты на размер сообщений и частоту

Конфигурация безопасности:

# Создание service account
$Password = ConvertTo-SecureString "ComplexP@ssw0rd!" -AsPlainText -Force
New-LocalUser -Name "RdpMonitorSvc" -Password $Password -Description "RDP Monitoring Service Account"

# Назначение минимальных прав
$Privileges = @(
    "SeServiceLogonRight",
    "SeAuditPrivilege",
    "SeSecurityPrivilege"
)

foreach ($priv in $Privileges) {
    & ntrights +r $priv -u "RdpMonitorSvc"
}

13. Приложение: структуры данных для хранения

13.1 Полная реляционная схема

-- Основная таблица событий
CREATE TABLE rdp_events (
    event_uuid UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    event_time TIMESTAMPTZ NOT NULL,
    ingested_time TIMESTAMPTZ DEFAULT NOW(),

    -- Источник
    source_system VARCHAR(50) NOT NULL,
    event_id INTEGER NOT NULL,
    event_name VARCHAR(100),
    computer_name VARCHAR(255),

    -- Пользователь
    user_name VARCHAR(255),
    user_domain VARCHAR(255),
    user_sid VARCHAR(255),
    logon_type INTEGER,

    -- Сессия
    session_id VARCHAR(100),
    session_name VARCHAR(100),

    -- Сеть
    source_ip INET,
    source_port INTEGER,
    dest_ip INET,
    dest_port INTEGER,
    protocol VARCHAR(10),

    -- Аутентификация
    auth_package VARCHAR(50),
    status_code VARCHAR(50),
    sub_status VARCHAR(50),
    failure_reason TEXT,

    -- Обогащение
    geo_country_code CHAR(2),
    geo_city VARCHAR(100),
    threat_score INTEGER DEFAULT 0,

    -- Технические поля
    raw_xml XML,
    processed BOOLEAN DEFAULT FALSE,
    correlation_id UUID,

    -- Индексы
    CONSTRAINT idx_event_time_range EXCLUDE USING gist (
        tsrange(event_time, event_time + INTERVAL '1 second') WITH &&
    )
);

-- Таблица сессий
CREATE TABLE rdp_sessions (
    session_uuid UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    session_id VARCHAR(100) NOT NULL,
    user_name VARCHAR(255) NOT NULL,
    user_domain VARCHAR(255) NOT NULL,

    -- Временные метки
    start_time TIMESTAMPTZ NOT NULL,
    end_time TIMESTAMPTZ,
    last_activity TIMESTAMPTZ,

    -- Сеть
    source_ip INET NOT NULL,
    server_name VARCHAR(255) NOT NULL,
    client_name VARCHAR(255),

    -- Состояние
    status VARCHAR(20) DEFAULT 'ACTIVE',
    reconnect_count INTEGER DEFAULT 0,
    disconnect_count INTEGER DEFAULT 0,

    -- Ресурсы
    bytes_sent BIGINT DEFAULT 0,
    bytes_received BIGINT DEFAULT 0,
    cpu_time_ms BIGINT DEFAULT 0,
    memory_kb INTEGER DEFAULT 0,

    -- Метаданные
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),

    -- Индексы
    UNIQUE(session_id, server_name),
    INDEX idx_sessions_user (user_name, start_time),
    INDEX idx_sessions_status (status, last_activity)
);

-- Таблица агрегатов по IP
CREATE TABLE ip_aggregates (
    ip_address INET PRIMARY KEY,
    first_seen TIMESTAMPTZ NOT NULL,
    last_seen TIMESTAMPTZ NOT NULL,

    -- Статистика
    total_events INTEGER DEFAULT 0,
    success_count INTEGER DEFAULT 0,
    failure_count INTEGER DEFAULT 0,

    -- Пользователи
    unique_users INTEGER DEFAULT 0,
    last_user VARCHAR(255),
    last_domain VARCHAR(255),

    -- Геолокация
    country_code CHAR(2),
    city VARCHAR(100),
    isp VARCHAR(255),

    -- Threat Intelligence
    threat_level VARCHAR(20) DEFAULT 'LOW',
    threat_indicators JSONB DEFAULT '[]',
    reputation_score INTEGER DEFAULT 50,

    -- Метки
    tags VARCHAR(255)[] DEFAULT '{}',
    is_whitelisted BOOLEAN DEFAULT FALSE,
    is_blacklisted BOOLEAN DEFAULT FALSE,

    -- Обновление
    updated_at TIMESTAMPTZ DEFAULT NOW(),

    -- Индексы
    INDEX idx_ip_agg_seen (last_seen),
    INDEX idx_ip_agg_threat (threat_level),
    INDEX idx_ip_agg_tags (tags)
);

-- Таблица процессов
CREATE TABLE session_processes (
    process_uuid UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    session_uuid UUID NOT NULL REFERENCES rdp_sessions(session_uuid),

    -- Идентификация
    process_id INTEGER NOT NULL,
    process_name VARCHAR(255) NOT NULL,
    executable_path TEXT,
    command_line TEXT,

    -- Временные метки
    start_time TIMESTAMPTZ NOT NULL,
    end_time TIMESTAMPTZ,

    -- Контекст
    user_name VARCHAR(255),
    integrity_level VARCHAR(20),
    parent_process_id INTEGER,

    -- Безопасность
    file_hash_sha256 CHAR(64),
    file_hash_md5 CHAR(32),
    digital_signature TEXT,

    -- Ресурсы
    cpu_percent NUMERIC(5,2),
    memory_mb INTEGER,

    -- Индексы
    INDEX idx_proc_session (session_uuid, start_time),
    INDEX idx_proc_name (process_name),
    INDEX idx_proc_hash (file_hash_sha256)
);

13.2 Оптимизированные запросы для анализа

Поиск аномальных сессий:

WITH session_metrics AS (
    SELECT 
        s.session_uuid,
        s.user_name,
        s.start_time,
        s.end_time,
        s.bytes_sent,
        s.bytes_received,
        EXTRACT(EPOCH FROM (s.end_time - s.start_time)) as duration_seconds,
        COUNT(DISTINCT p.process_name) as unique_processes,
        MAX(p.cpu_percent) as max_cpu_percent

    FROM rdp_sessions s
    LEFT JOIN session_processes p ON s.session_uuid = p.session_uuid
    WHERE s.end_time IS NOT NULL
        AND s.start_time > NOW() - INTERVAL '7 days'
    GROUP BY s.session_uuid, s.user_name, s.start_time, s.end_time, 
             s.bytes_sent, s.bytes_received
)
SELECT 
    user_name,
    COUNT(*) as session_count,
    PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY duration_seconds) as median_duration,
    PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY duration_seconds) as p95_duration,
    AVG(unique_processes) as avg_processes,
    MAX(max_cpu_percent) as max_cpu_observed
FROM session_metrics
GROUP BY user_name
HAVING COUNT(*) > 5
    AND MAX(duration_seconds) > 3600 * 8  -- Сессии длиннее 8 часов
    OR MAX(max_cpu_percent) > 90          -- Высокая загрузка CPU
ORDER BY session_count DESC;

Обнаружение горизонтального перемещения:

WITH lateral_movement_candidates AS (
    SELECT 
        e1.event_time as time1,
        e1.user_name,
        e1.computer_name as source_host,
        e1.source_ip,
        e2.event_time as time2,
        e2.computer_name as target_host,
        EXTRACT(EPOCH FROM (e2.event_time - e1.event_time)) as time_diff_seconds

    FROM rdp_events e1
    INNER JOIN rdp_events e2 ON 
        e1.user_name = e2.user_name
        AND e1.source_ip = e2.source_ip
        AND e1.event_id = 4648  -- Explicit Credentials
        AND e2.event_id = 4624  -- Successful Logon
        AND e2.event_time > e1.event_time
        AND e2.event_time < e1.event_time + INTERVAL '5 minutes'

    WHERE e1.event_time > NOW() - INTERVAL '1 day'
        AND e1.computer_name != e2.computer_name  -- Разные хосты
)
SELECT 
    user_name,
    source_host,
    target_host,
    source_ip,
    COUNT(*) as occurrence_count,
    MIN(time_diff_seconds) as min_time_diff,
    AVG(time_diff_seconds) as avg_time_diff

FROM lateral_movement_candidates
GROUP BY user_name, source_host, target_host, source_ip
HAVING COUNT(*) > 1  -- Многократные попытки
ORDER BY occurrence_count DESC;

13.3 Конфигурация TimescaleDB для RDP-событий

-- Создание гипартаблицы
SELECT create_hypertable(
    'rdp_events',
    'event_time',
    chunk_time_interval => INTERVAL '1 day',
    create_default_indexes => FALSE
);

-- Оптимизированные индексы
CREATE INDEX idx_rdp_events_time_id ON rdp_events (event_time, event_id)
    WITH (timescaledb.transaction_per_chunk);

CREATE INDEX idx_rdp_events_user_time ON rdp_events (user_name, event_time DESC)
    WITH (timescaledb.transaction_per_chunk);

CREATE INDEX idx_rdp_events_ip_time ON rdp_events (source_ip, event_time DESC)
    WITH (timescaledb.transaction_per_chunk);

CREATE INDEX idx_rdp_events_session ON rdp_events (session_id, event_time)
    WHERE session_id IS NOT NULL
    WITH (timescaledb.transaction_per_chunk);

-- Политика сжатия
ALTER TABLE rdp_events SET (
    timescaledb.compress,
    timescaledb.compress_segmentby = 'event_id, source_system',
    timescaledb.compress_orderby = 'event_time DESC'
);

-- Расписание сжатия
SELECT add_compression_policy('rdp_events', INTERVAL '7 days');

-- Политика удержания данных
SELECT add_retention_policy('rdp_events', INTERVAL '90 days');

-- Непрерывные агрегаты
CREATE MATERIALIZED VIEW rdp_events_hourly
WITH (timescaledb.continuous) AS
SELECT 
    time_bucket('1 hour', event_time) as bucket,
    source_ip,
    user_name,
    COUNT(*) as event_count,
    SUM(CASE WHEN event_id = 4624 THEN 1 ELSE 0 END) as success_count,
    SUM(CASE WHEN event_id = 4625 THEN 1 ELSE 0 END) as failure_count,
    COUNT(DISTINCT session_id) as unique_sessions
FROM rdp_events
GROUP BY bucket, source_ip, user_name;

-- Расписание обновления агрегатов
SELECT add_continuous_aggregate_policy('rdp_events_hourly',
    start_offset => INTERVAL '1 hour',
    end_offset => INTERVAL '5 minutes',
    schedule_interval => INTERVAL '15 minutes'
);

13.4 Экспорт данных для SIEM-систем

Формат CEF (Common Event Format):

CEF:0|RdpMonitor|3.0|100|RDP_LOGON_SUCCESS|Successful RDP Logon|10|
src=192.168.1.100 dst=10.0.0.10 dpt=3389 \
suser=jsmith duser=jsmith outcome=success \
cat=Authentication/Access msg=User jsmith logged in via RDP \
rt=Jan 15 2025 10:30:00.123Z cs1Label=LogonType cs1=10 \
cs2Label=SessionID cs2=S-1-5-21-... cs3Label=SourceWorkstation cs3=CLIENT-PC

Формат JSON для Elasticsearch:

{
  "@timestamp": "2025-01-15T10:30:00.123Z",
  "event": {
    "provider": "Microsoft-Windows-Security-Auditing",
    "id": 4624,
    "action": "logon",
    "outcome": "success",
    "type": ["authentication", "connection"]
  },
  "user": {
    "name": "jsmith",
    "domain": "CONTOSO"
  },
  "source": {
    "ip": "192.168.1.100",
    "port": 56842,
    "geo": {
      "country_name": "United States",
      "city_name": "Seattle"
    }
  },
  "destination": {
    "ip": "10.0.0.10",
    "port": 3389
  },
  "rdp": {
    "logon_type": 10,
    "session_id": "S-1-5-21-...",
    "protocol": "RDP 10.9",
    "encryption": "TLS 1.2"
  },
  "threat": {
    "score": 0,
    "indicators": []
  }
}

Глава 14: Механизмы сбора событий: ETW vs EventLog API

14.1 Введение в механизмы сбора

В Windows существует два основных механизма сбора системных событий: Event Tracing for Windows (ETW) и EventLog API. Понимание различий между этими подходами критически важно для проектирования высокопроизводительной системы мониторинга RDP.

graph TB
    A[Источники событий Windows] --> B{Выбор механизма сбора}
    B --> C[ETW - Real-time]
    B --> D[EventLog API - Historical]
    
    subgraph "ETW Архитектура"
        C --> E[Ядро Windows]
        E --> F[Буфер в памяти]
        F --> G[Потребители в реальном времени]
    end
    
    subgraph "EventLog Архитектура"
        D --> H[Файлы .evtx на диске]
        H --> I[Опрос по расписанию]
        I --> J[Исторический анализ]
    end
    
    G --> K[Низкая задержка <100ms]
    J --> L[Высокая задержка 1s+]

14.2 Event Tracing for Windows (ETW)

14.2.1 Архитектура ETW

ETW представляет собой высокопроизводительную, масштабируемую систему трассировки, встроенную в ядро Windows.

Компоненты архитектуры:

graph LR
    A[Поставщики Providers] --> B[Контроллеры Controllers]
    B --> C[Сессии Sessions]
    C --> D[Буферы в ядре]
    D --> E[Потребители Consumers]
    E --> F[Обработка в реальном времени]
    
    subgraph "Поставщики событий"
        A1[Microsoft-Windows-Security-Auditing]
        A2[Microsoft-Windows-TerminalServices]
        A3[Microsoft-Windows-RDP]
    end
    
    subgraph "Типы потребителей"
        E1[In-process - .NET Apps]
        E2[Out-of-process - Services]
        E3[Системные - PerfMon]
    end

14.2.2 Ключевые преимущества ETW

  1. Реальное время: События доставляются немедленно
  2. Высокая производительность: Минимальные накладные расходы
  3. Фильтрация в ядре: Снижение нагрузки на пользовательское пространство
  4. Структурированные данные: Бинарный формат вместо XML
  5. Гибкая подписка: Динамическое включение/выключение поставщиков

14.2.3 Технические характеристики ETW

Производительность:

  • Пропускная способность: до 1,000,000 событий/сек
  • Задержка: 1-10 мс от генерации до потребителя
  • Использование CPU: < 1% для типичных сценариев
  • Использование памяти: 1-10 МБ на сессию

Ограничения:

// Пример настройки сессии ETW с ограничениями
var sessionProperties = new TraceEventSessionProperties
{
    BufferSize = 64,           // КБ на буфер
    MinimumBuffers = 12,       // Минимум буферов
    MaximumBuffers = 48,       // Максимум буферов
    FlushTimer = 1,           // Секунды между сбросами
    LogFileMode = LogFileMode.Realtime
};

14.3 EventLog API

14.3.1 Архитектура EventLog

EventLog API работает с событиями, уже записанными в файлы журналов (.evtx).

Процесс работы:

Генерация события → Запись в .evtx файл → Чтение через API → Обработка
          ↑                       ↑                ↑
     Мгновенно            Задержка 0.5-5s      Периодический опрос

14.3.2 Ключевые характеристики EventLog

Преимущества:

  1. Простота использования: Простой API для чтения журналов
  2. Исторические данные: Доступ к уже сохраненным событиям
  3. Стандартизация: Единый формат для всех приложений
  4. Надежность: Гарантированная запись событий

Недостатки:

  1. Высокая задержка: События доступны только после записи на диск
  2. Ограниченная производительность: Дисковые операции ограничивают throughput
  3. Отсутствие реального времени: Только опросный режим
  4. Нагрузка на систему: Частое чтение журналов создает нагрузку

14.4 Сравнительный анализ

14.4.1 Детальное сравнение

graph TD
    A[Сравнение механизмов сбора] --> B[Производительность]
    A --> C[Задержка]
    A --> D[Ресурсы]
    A --> E[Функциональность]
    
    B --> B1[ETW: 1M+ events/sec]
    B --> B2[EventLog: 10K events/sec]
    
    C --> C1[ETW: <10ms]
    C --> C2[EventLog: 500ms-5s]
    
    D --> D1[ETW: CPU 1%, Memory 10MB]
    D --> D2[EventLog: CPU 5-20%, Disk I/O high]
    
    E --> E1[ETW: Real-time, Filtering, Structured]
    E --> E2[EventLog: Historical, Simple, XML]

14.4.2 Сравнительная таблица

КритерийETW (Event Tracing for Windows)EventLog API
Режим работыРеальный времени (push)Опросный (poll)
Задержка1-10 мс500 мс — 5 секунд
Пропускная способностьДо 1,000,000 событий/секДо 10,000 событий/сек
Использование CPU0.5-2%5-20% (при активном опросе)
Использование памяти5-50 МБ (зависит от буферов)10-100 МБ (кеширование)
Дисковый I/OМинимальныйВысокий (чтение .evtx)
ФильтрацияНа уровне ядра (высокая эффективность)На уровне приложения (низкая эффективность)
Формат данныхСтруктурированный бинарныйXML (текстовый)
Размер данныхКомпактный (30-50% от XML)Полный XML (большой объем)
Исторические данныеНет (только реальное время)Да (полный доступ к журналам)
Надежность доставкиВозможна потеря при перегрузкеГарантированная запись
Сложность реализацииВысокая (требует знания ETW)Низкая (простой API)
Поддержка в .NETMicrosoft.Diagnostics.Tracing.TraceEventSystem.Diagnostics.Eventing.Reader
МасштабируемостьОчень высокая (кластеры серверов)Ограниченная (один сервер)
Влияние на системуМинимальноеЗначительное при частом опросе
Требуемые праваАдминистратор (для сессий)Чтение журналов
Поддержка в PowerShellLimited (Get-WinEvent -FilterXPath)Полная (Get-EventLog, Get-WinEvent)
СовместимостьWindows Vista+Windows 2000+
ОтладкаСложная (требуются спец. инструменты)Простая (можно просмотреть в Event Viewer)

14.4.3 Сравнение по сценариям использования RDP

Для каких событий RDP использовать ETW:

etw_recommended:
  # Критичные события безопасности (нужны немедленно)
  - "Security 4624/4625"  # Аутентификация
  - "Security 4648"       # Явные учетные данные
  - "Security 1102"       # Очистка журнала

  # Управление сессиями (реальное время)
  - "TerminalServices-LocalSessionManager 21-25"
  - "TerminalServices-RemoteConnectionManager 1149"

  # Сетевые события
  - "Windows Firewall 2003-2006"

  # Протокольные события (диагностика)
  - "RDPCoreTS 131, 140"

Для каких событий RDP использовать EventLog:

eventlog_recommended:
  # Исторический анализ
  - "Старые события (>24 часов)"
  - "Аудит за прошлые периоды"

  # Редкие события (не критично к задержке)
  - "Licensing 44"        # Ошибки лицензий
  - "System 7036"         # Запуск служб

  # События, где нужна гарантированная доставка
  - "Критичные аудиторские события"

  # Когда ETW недоступен
  - "Windows Server 2003/2008"
  - "Системы без прав администратора"

14.5 Производительность и метрики

14.5.1 Тесты производительности (RDP-события)

Результаты тестирования на Windows Server 2022:

Сценарий: 1000 RDP-подключений в минуту

ETW сбор:
  - Событий/сек: 850-950
  - Задержка P50: 8 мс
  - Задержка P95: 15 мс
  - CPU использование: 1.2%
  - Память: 12 МБ

EventLog сбор (опрос каждые 5 сек):
  - Событий/сек: 40-60
  - Задержка P50: 2.5 с
  - Задержка P95: 4.8 с
  - CPU использование: 8.5%
  - Память: 85 МБ
  - Дисковый I/O: 15 МБ/сек

14.5.2 Формулы расчета нагрузки

Для ETW:

Общая нагрузка = (Событий/сек × 0.0001) + (Буферы × 0.5) + (Фильтры × 0.2)
Где:
  - Событий/сек: Количество обрабатываемых событий
  - Буферы: Количество буферов в сессии (обычно 12-48)
  - Фильтры: Количество активных фильтров

Для EventLog:

Общая нагрузка = (Опросов/час × 0.8) + (Событий/опрос × 0.0005) + (Размер журнала × 0.001)

14.6 Примеры реализации

14.6.1 ETW сборщик на C#

using Microsoft.Diagnostics.Tracing;
using Microsoft.Diagnostics.Tracing.Session;
using System;
using System.Threading.Tasks;

namespace RdpMonitor.ETW
{
    public class HighPerformanceEtwCollector : IDisposable
    {
        private readonly TraceEventSession _session;
        private readonly Task _processingTask;
        private readonly CancellationTokenSource _cancellationTokenSource;

        public HighPerformanceEtwCollector()
        {
            _cancellationTokenSource = new CancellationTokenSource();

            // Создание высокопроизводительной сессии ETW
            _session = new TraceEventSession(
                "RdpMonitorSession",
                null,  // No file, real-time only
                TraceEventSessionOptions.Create);

            ConfigureSessionProperties();
            EnableProviders();

            // Запуск обработки в отдельном потоке
            _processingTask = Task.Run(() => ProcessEvents());
        }

        private void ConfigureSessionProperties()
        {
            // Оптимальные настройки для RDP-мониторинга
            var properties = new TraceEventSessionProperties
            {
                BufferSizeKB = 64,           // 64КБ буферы
                MinimumBuffers = 16,         // Минимум буферов
                MaximumBuffers = 64,         // Максимум буферов
                FlushTimer = 1000,           // Сброс каждую секунду
                ClockType = ClockType.PerfCounter, // Высокоточное время
                StackWalk = StackWalkType.None     // Без стектрейсов для производительности
            };

            _session.SetSessionProperties(properties);
        }

        private void EnableProviders()
        {
            // Security Events (RDP Authentication)
            _session.EnableProvider(
                "Microsoft-Windows-Security-Auditing",
                TraceEventLevel.Verbose,
                0x8010000000000000,  // Audit Logon keyword
                new TraceEventProviderOptions
                {
                    EventIDStacks = new List<int> { 4624, 4625, 4634, 4647, 4648 },
                    EventIDs = "4624-4625,4634,4647,4648,4768-4779"
                });

            // Terminal Services Events
            _session.EnableProvider(
                "Microsoft-Windows-TerminalServices-LocalSessionManager",
                TraceEventLevel.Informational,
                0xFFFFFFFFFFFFFFFF);

            _session.EnableProvider(
                "Microsoft-Windows-TerminalServices-RemoteConnectionManager",
                TraceEventLevel.Informational,
                0xFFFFFFFFFFFFFFFF);

            // RDP Protocol Events
            _session.EnableProvider(
                "Microsoft-Windows-RemoteDesktopServices-RdpCoreTS",
                TraceEventLevel.Warning,  // Только ошибки и предупреждения
                0xFFFFFFFFFFFFFFFF);
        }

        private void ProcessEvents()
        {
            // Канал для асинхронной обработки
            var channel = System.Threading.Channels.Channel.CreateBounded<TraceEvent>(
                new System.Threading.Channels.BoundedChannelOptions(10000)
                {
                    FullMode = System.Threading.Channels.BoundedChannelFullMode.Wait,
                    SingleWriter = true,
                    SingleReader = false
                });

            // Регистрация обработчика
            _session.Source.Dynamic.All += eventData =>
            {
                // Асинхронная запись в канал (не блокируем ETW поток)
                channel.Writer.TryWrite(eventData);
            };

            // Запуск обработчиков (по числу ядер)
            var processingTasks = new List<Task>();
            for (int i = 0; i < Environment.ProcessorCount; i++)
            {
                processingTasks.Add(Task.Run(async () =>
                {
                    await foreach (var evt in channel.Reader.ReadAllAsync(
                        _cancellationTokenSource.Token))
                    {
                        ProcessSingleEvent(evt);
                    }
                }));
            }

            // Запуск обработки ETW
            _session.Source.Process();

            Task.WaitAll(processingTasks.ToArray());
        }

        private void ProcessSingleEvent(TraceEvent evt)
        {
            // Быстрая обработка события
            var rdpEvent = new RdpEvent
            {
                EventId = evt.ID,
                ProviderName = evt.ProviderName,
                TimeCreated = evt.TimeStamp,
                ComputerName = Environment.MachineName,
                // ... парсинг полей события
            };

            // Асинхронная запись в хранилище
            _eventRepository.AddAsync(rdpEvent).ConfigureAwait(false);
        }

        public void Dispose()
        {
            _cancellationTokenSource.Cancel();
            _session?.Stop();
            _session?.Dispose();
            _processingTask?.Wait(5000);
        }
    }

    public class RdpEvent
    {
        public int EventId { get; set; }
        public string ProviderName { get; set; }
        public DateTime TimeCreated { get; set; }
        public string ComputerName { get; set; }
        // ... другие поля
    }
}

14.6.2 EventLog сборщик на C#

using System.Diagnostics.Eventing.Reader;
using System.Xml;
using System.Threading.Channels;

namespace RdpMonitor.EventLog
{
    public class EventLogCollector : IDisposable
    {
        private readonly Timer _pollingTimer;
        private readonly Channel<RdpEvent> _eventChannel;
        private DateTime _lastPollTime = DateTime.UtcNow.AddMinutes(-5);

        public EventLogCollector()
        {
            _eventChannel = Channel.CreateUnbounded<RdpEvent>();

            // Опрос каждые 30 секунд
            _pollingTimer = new Timer(PollEvents, null, 
                TimeSpan.Zero, TimeSpan.FromSeconds(30));
        }

        private void PollEvents(object state)
        {
            try
            {
                // Запрос событий Security
                var securityQuery = CreateSecurityQuery();
                ReadEventLog("Security", securityQuery);

                // Запрос событий Terminal Services
                var tsQuery = CreateTerminalServicesQuery();
                ReadEventLog("Microsoft-Windows-TerminalServices-LocalSessionManager/Operational", 
                           tsQuery);

                _lastPollTime = DateTime.UtcNow;
            }
            catch (Exception ex)
            {
                // Логирование ошибки
                LogError("EventLog polling failed", ex);
            }
        }

        private string CreateSecurityQuery()
        {
            return $@"<QueryList>
                <Query Id='0' Path='Security'>
                    <Select Path='Security'>
                        *[System[
                            (EventID=4624 or EventID=4625 or EventID=4634 or 
                             EventID=4647 or EventID=4648 or EventID=1102 or
                             EventID=4768 or EventID=4769 or EventID=4771 or
                             EventID=4776 or EventID=4778 or EventID=4779)
                            and TimeCreated[@SystemTime&gt;='{_lastPollTime.ToUniversalTime():o}']
                        ]]
                    </Select>
                </Query>
            </QueryList>";
        }

        private void ReadEventLog(string logName, string query)
        {
            using (var reader = new EventLogReader(new EventLogQuery(logName, 
                PathType.LogName, query)))
            {
                EventRecord record;
                while ((record = reader.ReadEvent()) != null)
                {
                    try
                    {
                        var rdpEvent = ParseEventRecord(record);
                        _eventChannel.Writer.TryWrite(rdpEvent);
                    }
                    finally
                    {
                        record.Dispose();
                    }
                }
            }
        }

        private RdpEvent ParseEventRecord(EventRecord record)
        {
            var xml = record.ToXml();
            var doc = new XmlDocument();
            doc.LoadXml(xml);

            return new RdpEvent
            {
                EventId = record.Id,
                ProviderName = record.ProviderName,
                TimeCreated = record.TimeCreated ?? DateTime.UtcNow,
                ComputerName = record.MachineName,
                XmlData = xml  // Сохраняем XML для дальнейшего парсинга
            };
        }

        public ChannelReader<RdpEvent> EventReader => _eventChannel.Reader;

        public void Dispose()
        {
            _pollingTimer?.Dispose();
            _eventChannel.Writer.Complete();
        }
    }
}

14.7 Гибридный подход для RDP-мониторинга

14.7.1 Архитектура гибридного сбора

graph TB
    A[RDP События] --> B{Маршрутизатор}

    B --> C[ETW Real-time]
    B --> D[EventLog Historical]

    subgraph "Real-time Pipeline"
        C --> E[Фильтрация в ядре]
        E --> F[Буферизация в памяти]
        F --> G[Обработка <100ms]
        G --> H[Hot Storage]
    end

    subgraph "Historical Pipeline"
        D --> I[Планировщик опросов]
        I --> J[Чтение .evtx]
        J --> K[Пакетная обработка]
        K --> L[Warm/Cold Storage]
    end

    H --> M[Real-time Analytics]
    L --> N[Historical Analytics]

    M --> O[Alerting]
    N --> P[Reporting]
    N --> Q[Compliance]

14.7.2 Конфигурация гибридной системы

collection_strategy:
  real_time:
    mechanism: etw
    providers:
      - name: Microsoft-Windows-Security-Auditing
        event_ids: [4624, 4625, 4634, 4647, 4648]
        keywords: 0x8010000000000000

      - name: Microsoft-Windows-TerminalServices-LocalSessionManager
        event_ids: [21, 22, 23, 24, 25]

      - name: Microsoft-Windows-TerminalServices-RemoteConnectionManager
        event_ids: [1149, 1150]

    performance:
      buffer_size_kb: 64
      min_buffers: 16
      max_buffers: 64
      flush_interval_ms: 1000

  historical:
    mechanism: eventlog
    polling_interval_seconds: 30
    logs:
      - name: Security
        query: "*[System[(EventID=4768 or EventID=4769 or EventID=4771 or EventID=4776)]]"

      - name: Microsoft-Windows-TerminalServices-Licensing/Admin
        query: "*[System[(EventID=44 or EventID=100 or EventID=101)]]"

      - name: System
        query: "*[System[Provider[@Name='TermService' or @Name='Schannel']]]"

    retention:
      hot: 7 days
      warm: 30 days
      cold: 365 days

  correlation:
    enabled: true
    time_window_seconds: 300
    match_fields: [session_id, user_name, source_ip]

14.8 Рекомендации по выбору

14.8.1 Когда выбирать ETW

Обязательно использовать ETW для:

  1. Обнаружения атак в реальном времени — брутфорс, компрометация
  2. Мониторинга критических серверов — DC, RDSH, Gateway
  3. Высокочастотных событий — аутентификация, сетевые подключения
  4. Систем с высокой нагрузкой — тысячи событий в секунду
  5. Сценариев с низкой задержкой — алертинг, автоматические ответы

14.8.2 Когда выбирать EventLog

Можно использовать EventLog для:

  1. Исторического анализа — аудит за прошлые периоды
  2. Редких событий — ошибки лицензирования, запуск служб
  3. Систем с низкой нагрузкой — менее 100 событий/сек
  4. Когда не требуется реальное время — отчеты, compliance
  5. Устаревших систем — Windows Server 2008 и старше

14.8.3 Критерии принятия решения

graph TD
    A[Выбор механизма сбора] --> B{Требуется реальное время?}
    B -->|Да| C{Более 1000 событий/сек?}
    B -->|Нет| D[EventLog API]
    
    C -->|Да| E{Есть права администратора?}
    C -->|Нет| F[EventLog API]
    
    E -->|Да| G[ETW]
    E -->|Нет| H[EventLog API]
    
    G --> I[Настроить буферы 64KB]
    G --> J[Использовать фильтрацию в ядре]
    G --> K[Асинхронная обработка]
    
    D --> L[Опрос каждые 30-60 сек]
    D --> M[Использовать XPath фильтры]
    D --> N[Пакетное чтение]

14.9 Мониторинг и диагностика

14.9.1 Мониторинг производительности ETW

# Мониторинг сессий ETW
Get-EtwTraceSession -Name "RdpMonitorSession" | 
    Select-Object Name, Status, BufferSize, LogFileMode, EventsLost

# Просмотр статистики производительности
logman query "RdpMonitorSession" -ets

# Мониторинг использования ресурсов
Get-Counter '\Process(rdpmon)\% Processor Time' -Continuous
Get-Counter '\Process(rdpmon)\Private Bytes' -Continuous

14.9.2 Диагностика проблем EventLog

# Проверка размера журналов
Get-WinEvent -ListLog * | 
    Where-Object {$_.RecordCount -gt 0} |
    Select-Object LogName, RecordCount, FileSize, LastWriteTime |
    Sort-Object FileSize -Descending

# Поиск проблем с доступом
Get-WinEvent -LogName Security -MaxEvents 1 -ErrorAction SilentlyContinue

# Оптимизация производительности
wevtutil sl Security /ms:104857600  # Ограничить размер до 100MB
wevtutil sl Security /rt:false      # Отключить реальное время

14.10 Выводы: ETW и EventLog API

Выбор между ETW и EventLog API зависит от конкретных требований системы мониторинга RDP:

  1. Для систем безопасности и реального времени — используйте ETW
  2. Для исторического анализа и отчетности — используйте EventLog API
  3. Для большинства enterprise-сценариев — используйте гибридный подход

Ключевые выводы:

  • ETW обеспечивает в 100 раз более низкую задержку
  • EventLog API проще в реализации и поддержке
  • Гибридный подход дает наилучший баланс производительности и функциональности
  • Для RDP-мониторинга критически важна низкая задержка обнаружения атак

Рекомендация для RdpMon++: Реализовать гибридную архитектуру, где события квадрантов I и IV собираются через ETW, а события квадрантов II и III — через EventLog API с оптимизированными интервалами опроса.

Заключение

Ключевые выводы

  1. Полнота охвата: Современная система мониторинга RDP должна собирать события из 10+ источников, а не только из Security-журнала.
  2. Корреляция обязательна: Отдельные события имеют ограниченную ценность. Критически важна корреляция по времени, SessionId и IP-адресам.
  3. Производительность: Использование ETW вместо EventLog API дает 10-кратный прирост производительности при сборе событий в реальном времени.
  4. Масштабируемость: Многоуровневое хранение (горячее/теплое/холодное) обязательно для больших объемов данных.
  5. Обогащение данных: Геолокация и Threat Intelligence превращают сырые события в actionable intelligence.

Дорожная карта внедрения

Этап 1 (30 дней):

  • Сбор Security 4624/4625 и LSM 21-25
  • Базовая корреляция по SessionId
  • Простые алерты на брутфорс

Этап 2 (60 дней):

  • Добавление Kerberos/NTLM событий
  • Интеграция с GeoIP
  • Расширенная корреляция
  • Дашборды для администраторов

Этап 3 (90 дней):

  • Полный сбор всех источников
  • Интеграция с Threat Intelligence
  • Машинное обучение для обнаружения аномалий
  • Автоматизированные ответы на инциденты

Метрики успеха

МетрикаЦелевое значениеИзмерение
Время обнаружения атаки< 5 минутСреднее время от события до алерта
Полнота сбора> 99.9%Процент собранных событий от общих
Ложные срабатывания< 5% в деньАлерты без последующих инцидентов
Время хранения90+ днейДоступность исторических данных
Производительность< 100ms задержкаВремя от события до появления в SIEM

Система мониторинга, построенная по этим принципам, обеспечит не только безопасность RDP-доступа, но и оперативную аналитику использования, планирование емкости и соответствие требованиям регуляторов.

Добавить комментарий

Разработка и продвижение сайтов webseed.ru
Прокрутить вверх