В этой статье мы рассмотрим, особенности аудита / анализа логов RDP подключений в Windows. Как правило, описанные методы могут пригодиться при расследовании различных инцидентов на терминальных / RDS серверах Windows, когда от системного администратора требуется предоставить информацию: какие пользователи входили на RDS сервер, когда авторизовался и завершил сеанс конкретный пользователь, откуда / с какого устройства (имя или IP адрес) подключался RDP-пользователь. Я думаю, эта информация будет полезна как для администраторов корпоративных RDS ферм, так и владельцам RDP серверов в интернете (Windows VPS как оказалось довольно популярны).
Как и другие события, логи RDP подключения в Windows хранятся в журналах событий. Откройте консоль журнала событий (Event Viewer). Есть несколько различных журналов, в которых можно найти информацию, касающуюся RDP подключения.
В журналах Windows содержится большое количество информации, но быстро найти нужное событие бывает довольно сложно. Когда пользователь удаленно подключается к RDS серверу или удаленному столу (RDP) в журналах Windows генерируется много событий. Мы рассмотрим журналы и события на основных этапах RDP подключения, которые могут быть интересны администратору:
- Network Connection
- Authentication
- Logon
- Session Disconnect/Reconnect
- Logoff
Network Connection: – установление сетевого подключение к серверу от RDP клиента пользователя. Событие с EventID – 1149 (Remote Desktop Services: User authentication succeeded). Наличие этого события не свидетельствует об успешной аутентификации пользователя. Этот журнал находится в разделе Applications and Services Logs -> Microsoft -> Windows -> Terminal-Services-RemoteConnectionManager -> Operational. Включите фильтр по данному событию (ПКМ по журналу-> Filter Current Log -> EventId 1149).
В результате у вас получится список с историей всех сетевых RDP подключений к данному серверу. Как вы видите, в логах указывается имя пользователя, домен (используется NLA аутентификация, при отключенном NLA текст события выглядит иначе) и IP адрес компьютера, с которого осуществляется RDP подключение.
Authentication: – успешная или неуспешная аутентификация пользователя на сервере. Журнал Windows -> Security. Соответственно нас могут интересовать события с EventID – 4624 (успешная аутентификация — An account was successfully logged on) или 4625 (ошибка аутентификации — An account failed to log on). Обратите внимание на значение LogonType в событии. При входе через терминальную службу RDP — LogonType = 10 или 3. Если LogonType = 7, значит выполнено переподключение к уже имеющейся RDP сессии.
При этом имя пользователя содержится в описании события в поле Account Name, имя компьютера в Workstation Name, а имя пользователя в Source Network Address.
Вы можете получить список событий успешных авторизаций по RDP (событие 4624) с помощью такой команды PowerShell.
Get-EventLog security -after (Get-date -hour 0 -minute 0 -second 0) | ?{$_.eventid -eq 4624 -and $_.Message -match 'logon type:\s+(10)\s'} | Out-GridView
Logon: – RDP вход в систему, событие появляющееся после успешной аутентификации пользователя. Событие с EventID – 21 (Remote Desktop Services: Session logon succeeded). Этот журнал находится в разделе Applications and Services Logs -> Microsoft -> Windows -> TerminalServices-LocalSessionManager -> Operational. Как вы видите здесь можно узнать идентификатор RDP сессии для пользователя — Session ID.
Событие с EventID – 21 (Remote Desktop Services: Shell start notification received) означает успешный запуск оболочки Explorer (появление окна рабочего стола в RDP сессии).
Session Disconnect/Reconnect – события отключения / переподключения к сессии имеют разные коды в зависимости от того, что вызвало отключение пользователя (отключение по неактивности, выбор пункта Disconnect в сессии, завершение RDP сессии другим пользователем или администратором и т.д.). Эти события находятся в разделе журналов Applications and Services Logs -> Microsoft -> Windows -> TerminalServices-LocalSessionManager -> Operational. Рассмотрим RDP события, которые могут быть интересными:
- EventID – 24 (Remote Desktop Services: Session has been disconnected) – пользователь отключился от RDP сессии.
- EventID – 25 (Remote Desktop Services: Session reconnection succeeded) – пользователь переподключился к своей имеющейся RDP сессии на сервере.
- EventID – 39 (Session <A> has been disconnected by session <B>) – пользователь сам отключился от своей RDP сессии, выбрав соответствующий пункт меню (а не просто закрыл окно RDP клиента). Если идентификаторы сессий разные, значит пользователя отключил другой пользователь (или администратор).
- EventID – 40 (Session <A> has been disconnected, reason code <B>). Здесь нужно смотреть на код причины отключения в событии. Например:
- reason code 0 (No additional information is available)– обычно говорит о том, что пользователь просто закрыл окно RDP клиента.
- reason code 5 (The client’s connection was replaced by another connection) – пользователь переподключился к своей старой сессии.
- reason code 11 (User activity has initiated the disconnect) – пользователь сам нажал на кнопку Disconnect в меню.
Событие с EventID – 4778 в журнале Windows -> Security (A session was reconnected to a Window Station). Пользователь переподключился к RDP сессии (пользователю выдается новый LogonID).
Событие с EventID 4799 в журнале Windows -> Security (A session was disconnected from a Window Station). Отключение от RDP сеанса.
Logoff: – выход пользователя из системы. При этом в журнале Applications and Services Logs -> Microsoft -> Windows -> TerminalServices-LocalSessionManager -> Operational фиксируется событие с EventID 23 (Remote Desktop Services: Session logoff succeeded).
При этом в журнале Security нужно смотреть событие EventID 4634 (An account was logged off).
Событие Event 9009 (The Desktop Window Manager has exited with code (<X>) в журнале System говорит о том, что пользователь инициировал завершение RDP сессии, и окно и графический shell пользователя был завершен.
Ниже представлен небольшой PowerShell, который выгружает из журналов терминального RDS сервера историю всех RDP подключений за текущий день. В полученной таблице указано время подключения, IP адрес клиента и имя RDP пользователя (при необходимости вы можете включить в отчет другие типы входов).
Get-EventLog -LogName Security -after (Get-date -hour 0 -minute 0 -second 0)| ?{(4624,4778) -contains $_.EventID -and $_.Message -match 'logon type:\s+(10)\s'}| %{
(new-object -Type PSObject -Property @{
TimeGenerated = $_.TimeGenerated
ClientIP = $_.Message -replace '(?smi).*Source Network Address:\s+([^\s]+)\s+.*','$1'
UserName = $_.Message -replace '(?smi).*Account Name:\s+([^\s]+)\s+.*','$1'
UserDomain = $_.Message -replace '(?smi).*Account Domain:\s+([^\s]+)\s+.*','$1'
LogonType = $_.Message -replace '(?smi).*Logon Type:\s+([^\s]+)\s+.*','$1'
})
} | sort TimeGenerated -Descending | Select TimeGenerated, ClientIP `
, @{N='Username';E={'{0}\{1}' -f $_.UserDomain,$_.UserName}} `
, @{N='LogType';E={
switch ($_.LogonType) {
2 {'Interactive - local logon'}
3 {'Network conection to shared folder)'}
4 {'Batch'}
5 {'Service'}
7 {'Unlock (after screensaver)'}
8 {'NetworkCleartext'}
9 {'NewCredentials (local impersonation process under existing connection)'}
10 {'RDP'}
11 {'CachedInteractive'}
default {"LogType Not Recognised: $($_.LogonType)"}
}
}}
Иногда бывает удобно с логами в таблице Excel, в этом случае вы можете выгрузить любой журнал Windows в текстовый файл и импортировать в Excel. Экспорт журнала можно выполнить из консоли Event Viewer (конечно, при условии что логи не очищены) или через командную строку:
WEVTUtil query-events Security > c:\ps\security_log.txt
Или так:
get-winevent -logname "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" | Export-Csv c:\ps\rdp-log.txt -Encoding UTF8
Список текущих RDP сессий на сервере можно вывести командой:
Qwinsta
Команда возвращает как идентификатор сессии (ID), имя пользователя (USERNAME)и состояние (Active/Disconnect). Эту команду удобна использовать, когда нужно определить ID RDP сессии пользователя при теневом подключении.
Список запущенных процессов в конкретной RDP сессии (указывается ID сессии):
qprocess /id:157
На RDP-клиенте логи не такие информационные, основное чем часто пользуются информация об истории RDP подключений в реестре.
Вот, что называется — вовремя! Только я тут озаботился плотным изучением логов именно RDP и …. р-раз, а вот и стетеечка 🙂 Спасибо.
Уже не первый раз твои мысли читаю! Пользуйся 🙂
Если — получится накопать еще что-то полезное или какие-то полезные скрипты для анализа RDP логов напишешь — не стесняйся, делись.
Да. леХХко 🙂 Я же сказал — копаю 🙂 Вот софтина, например, полезная не только для RDP — Intrusion Detection for Windows Systems. Free и Платная версии.
Живет тут — https://cyberarms.net/
Что делает, в двух словах. Касаемо RDP — ловит неправльные пары логин/пароль и добавляет IP в свое собственное правило блокировки в Windows Firewall. Удобно. Но еще удобнее, если эти IP оттуда доставать и блокировать сразу на уровне входного Router/Firewall.
Что и делаю. По расписанию с помощью PowerShell вынимаю из правил Firewall IP адреса «стукачей» и отправляю в BLACKLIST на Firewall.
А вот и скриптик. Урезан, до «универсального». Кому интересно, допилят сами
$LogFile = "C:\BlockedIPs\blokip.txt"
$ip = "0.0.0.0"
$NetFirewallRule = Get-NetFirewallRule -DisplayName "Blocked by Cyberarms Intrusion Detection_BlockAttacker_AllPorts"
$tab = $NetFirewallRule | Get-NetFirewallAddressFilter
foreach($str in $tab){
$str.RemoteAddress.split("`n") | where { $_ -ne $ip } | Out-File -FilePath $LogFile -Encoding ASCII
}
$NetFirewallRule | Set-NetFirewallRule -LocalAddress Any -RemoteAddress $ip
Согласен, полезно.
В принципе если есть список ip+пользователь, можно сделать, чтобы при несоотвествии подключающийся ip блокировался в файерволе. Достаточно повесить на событие RDP логина задание планировщика с проверкой IP и учетки по текстовому файлу и блокировкой в случае отсуствия данных в файле.
Немного параноидально, но иногда заказчик хочет чего-то такого 🙂
Короче — возможны варианты. 🙂
А меня «пионеры» достали со своими брутфорсерами. Поэтому drop’аю их на внешнем firewall’e. Тоже скриптом и тоже через планировщик, дописываю новые IP в blacklist. А собирает их мне теперь софтина, которую я обозначил.
До этого делал тоже через ps. Выдергивал по Event’ам 140 и 4625 с чем лезут и кто лезет. Складывал в текстовые файлы и оттуда уже извлекал IP брутфорсеров. Делалось это по утрам, по состоянию «на вчера».
Теперь стало существенно проще. Да и софтина их IP «заранее» банит через Firewall, счетчик попыток на 50 выставлен.
а если ip не светится — идёт какое-то уведомление на почту или в события? Есть такой функционал в бесплатной версии?
кстать, сайт с софтиной не открывается… Ни с прокси, ни с тора, ни откуда 🙁
что-то не работает софтина… проинсталил её на десктоп свой, сервис её работает. Пробую ломиться по рдп на свой комп с виртуалки с неправильными логином и паролем — в логах софтины пусто….
в тему, как раз на прошлой недели понадобилось собрать логи по RDP соединениям, копаться в журналах винды не самое удобное, а ps скрипт вполне удобно. Спасибо)
При выполнения скрипта, выдается данная ошибка. 2012R2 Win.
Не удается вызвать эту команду с точкой, так как она была определена для другого языкового режима. Чтобы вызвать команду, не импортируя ее содержимое, опустите оператор ".".
+ CategoryInfo : InvalidOperation: (:) [RDPConnectionParser.ps1], NotSupportedException
+ FullyQualifiedErrorId : DotSourceNotSupported,RDPConnectionParser.ps1
Странно. Я как раз тестировал скрипт на 2012 R2 Eng. Проверяйте код своего скрипта.
У вас случаем не русская версия Windows?
А как «разгребать» все єто если РДС-ферма на 10+ хостов ?
Тут есть несколько вариантов:
1) Собрать все логи в одну кучу на один сервер через подписку: http://winitpro.ru/index.php/2011/01/17/centralizovannyj-event-log-v-windows-2008-server/
2) Если журналы RDP входов — критическая информация — можно писать их сразу в базу (например MySql — http://winitpro.ru/index.php/2016/04/19/vypolnenie-mysql-zaprosov-iz-powershell/)
3) Либо можно просто в скрипте перебирать все RDSH серверы по текстовому файлу. Что-то вроде
$list = gc C:\ps\complist.txt
Foreach ($server in $list) {
Get-EventLog -ComputerName $server -LogName Security -after (Get-date -hour 0 -minute 0 -second 0)| ?{(4624,4778) -contains $_.EventID -and $_.Message -match 'logon type:\s+(10)\s'}| %{
........
Скрипты не срабатывают. просто ничего не выводят
windows 2012r2 rus проверил на трёх системах.
видимо для русских версий надо заменить «logon type:» на «Тип входа:»
Все верно. В русских версиях текст в событиях на русском. Спасибо за дополненеи.
У меня и в Журнале событий совершенно пусто, и в PowerShell при запуске всё выполняется, но ничего не выдаёт. Не могу понять в чём причина. Возможно из-за пиратской Винды?..
Запустите консоль services.ms и проверьте, что запущена служба EventLog (Журнал событий Windowss \ Event Log Service). Служба должна быть настроена на автозапуск.
Если служба запущена, попробуйте сбросить настройки локальных политик http://winitpro.ru/index.php/2013/10/03/sbros-lokalnyx-gruppovyx-politik-v-windows/
Было бы очень интересно узнать как это можно сделать
У меня в модеме проброс портов. Как узнать с какого Ай-пи стучатся в Сервак? Кто-то стучиться, кто не знаю. Перебирают имена — пароли пользователей. Server 2008 R2. Событие с кодом 1149: это — Службы удаленных рабочих столов: Успешная проверка подлинности пользователя:
Информация об IP адреса, с которого выполняется подключение фиксируется в журнале событий. Посмотрите например EventID – 1149 — там указан IP source.
Совершенно верно. Событие с кодом 1149: это — Успешная проверка подлинности пользователя.
А если подключение не было успешным, то нет никакой информации откуда шло подключение. Или, как вариант, я просто этого не знаю. Не знаю где посмотреть.
По умолчанию в винде отключено логирование события типо «Fail» или «Неудачная попытка входа».
Включить можно или через «Локальные политики безопасности» -> локальные политики -> политики аудита -> Аудит входа в систему (там указываешь что логировать, успех или отказ, или все вместе).
Ну или gpedit.msc =)
На русской версии Server 2008 не работает. Уже все поля переиминовал на русский, все равно выводит пустоту скрипт. Автор, пожалуйста, прошу, сделай скрипт для русского сервера(
К сожалению у меня нет русской версии Windows Server.
Попробуйте руками собрать и перепроверить все поля и сообщения в событии авторизации.
Get-EventLog -LogName Security -after (Get-date -hour 0 -minute 0 -second 0)| ?{(4624,4778) -contains $_.EventID -and $_.Message -match ‘Тип входа:\s+(10)\s’}| %{
(new-object -Type PSObject -Property @{
TimeGenerated = $_.TimeGenerated
ClientIP = $_.Message -replace ‘(?smi).*Сетевой адрес источника:\s+([^\s]+)\s+.*’,’$1′
UserName = $_.Message -replace ‘(?smi).*Имя учетной записи:\s+([^\s]+)\s+.*’,’$1′
UserDomain = $_.Message -replace ‘(?smi).*Домен учетной записи:\s+([^\s]+)\s+.*’,’$1′
LogonType = $_.Message -replace ‘(?smi).*Тип входа:\s+([^\s]+)\s+.*’,’$1′
})
} | sort TimeGenerated | Select TimeGenerated, ClientIP `
, @{N=’Username’;E={‘{0}\{1}’ -f $_.UserDomain,$_.UserName}} `
, @{N=’LogType’;E={
switch ($_.LogonType) {
2 {‘Interactive — local logon’}
3 {‘Network conection to shared folder)’}
4 {‘Batch’}
5 {‘Service’}
7 {‘Unlock (after screensaver)’}
8 {‘NetworkCleartext’}
9 {‘NewCredentials (local impersonation process under existing connection)’}
10 {‘RDP’}
11 {‘CachedInteractive’}
default {«LogType Not Recognised: $($_.LogonType)»}
}
}}
такой вариант работает на русском сервере