Поиск источника блокировки пользователя в Active Ditectory

от автора

В работе администратора домена Active Directory довольно часто возникает необходимость найти причину блокировки пользователя. Иногда причиной блокировки пользователя является заражённый вирусом ПК — в таких случаях особо важна скорость обнаружения источника проблемы. В PowerShell 2 на Windows 2008 R2 есть прекрасный командлет Get-WinEvent который позволяет решать данную задачу за 1-2 минуты даже в очень большом домене.
Примечание: всё далее описанное касается только PowerShell >= 2.0

Необходимые исходные условия.

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

Категория аудита Подкатегория аудита Тип аудита Интересующий нас eventID
Audit Account Logon Events (Вход учётной записи) Kerberos Authentication Service (Аудит службы проверки подлинности Kerberos) Отказ 4771 Kerberos pre-authentication failed.
Audit Logon Events (Вход/Выход) Logon (Аудит входа в систему) Отказ 4625 An account failed to log on.
Audit Logon Events (Вход/Выход) Account Lockout (Аудит блокировки учётных записей) Успех 4740 Account locked
Алгоритм поиска источника блокировки

  1. Определить какой контроллер является владельцем роли PDC-эмулятора
  2. Найти в журнале безопасности PDC-эмулятора событие с кодом 4740 в поле «TargetUserName», которого указано имя интересующего нас пользователя
  3. В поле «TargetDomainName» того же события найти имя контроллера домена, обслужившего авторизацию
  4. Найти в журнале безопасности контроллера, обслужившего авторизацию, событие с кодом 4625 (неуспешная NTLM авторизация) или 4771 (неуспешная kerberos авторизация)
  5. Из найденного события получить значения полей «IpAddress» — адрес ПК с которого была попытка авторизации

Этих действий будет достаточно для быстрого поиска ПК с вредоносным ПО, подбирающим пароли пользователей. Как правило достаточно быстро вычислить источник проблемы и изолировать его для дальнейшего расследования. Алгоритм поиска процесса непосредственно вызывающего блокировку пользователя сильно зависит от ПО, установленного на конечном ПК.

Используемые командлеты PowerShell

  • Get-ADDomainController — для определения владельца роли PDC-эмулятора
  • Get-WinEvent — «волшебный» командлет, благодаря которому и стал возможным быстрый поиск

В чём «магия» Get-WinEvent?
Во-первых он ищет события с конца и имеет параметр -MaxEvents, позволяющий найти только самое последнее событие или неколько самых последних событий.
Во-вторых он имеет прекрасный параметр -FilterHashtable, который позволяет очень гибко задать условия поиска события.

Скрипт поиска

Для себя я подготовил небольшой PowerShell скрипт.
На входе скрипт принимает либо имя пользователя, для которого необходимо найти источник блокировки, либо количество (по умолчанию — 1) последних заблокированных пользователей.

 param (     $User,     $Count = 1  )      $result = New-Object system.Data.DataTable "Locks"     $col1 = New-Object system.Data.DataColumn Username,([string])     $col2 = New-Object system.Data.DataColumn DCFrom,([string])     $col3 = New-Object system.Data.DataColumn LockTime,([string])     $col4 = New-Object system.Data.DataColumn eventID,([string])     $col5 = New-Object system.Data.DataColumn SourceHost,([string])     $col6 = New-Object system.Data.DataColumn LogonType,([string])     $col7 = New-Object system.Data.DataColumn LogonProcessName,([string])     $col8 = New-Object system.Data.DataColumn FalureTime,([string])     $result.columns.add($col1)     $result.columns.add($col2)     $result.columns.add($col3)     $result.columns.add($col4)     $result.columns.add($col5)     $result.columns.add($col6)     $result.columns.add($col7)     $result.columns.add($col8)          $PDC = [string](Get-ADDomainController -Discover -Service PrimaryDC).Hostname     $FilterHash = @{}     $FilterHash.LogName = "Security"     $FilterHash.ID = "4740"     if ($User) {         $FilterHash.data =$User         $Count = 1     }     $FilterHash2 = @{}     $FilterHash2.LogName = "Security"     $FilterHash2.ID = @("4625", "4771")     Get-WinEvent -Computername $PDC -FilterHashtable $FilterHash -MaxEvents $Count |  foreach {         $Row = $result.NewRow()         $Username = ([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”} | %{$_."#text"}         $DCFrom = ([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetDomainName”} | %{$_."#text"}         $LockTime = $_.TimeCreated         $FilterHash2.data = $username         Get-WinEvent -Computername $dcfrom -FilterHashtable $FilterHash2 -MaxEvents 3 | foreach {             $Row = $result.NewRow()             $Row.Username = $Username             $Row.DCFrom = $DCFrom             $Row.LockTime = $LockTime             $Row.eventID = $_.ID             $Row.SourceHost = ([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “IpAddress”} | %{$_."#text"}             $Row.LogonType = ([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “LogonType”} | %{$_."#text"}              switch ($Row.LogonType)             {               "2" {$Row.LogonType = "Interactive"}              "3" {$Row.LogonType = "Network"}              "4" {$Row.LogonType = "Batch"}              "5" {$Row.LogonType = "Service"}              "7" {$Row.LogonType = "Unlock"}              "8" {$Row.LogonType = "NetworkCleartext"}              "9" {$Row.LogonType = "NewCredentials"}              "10" {$Row.LogonType = "RemoteInteractive"}              "11" {$Row.LogonType = "CachedInteractive"}             }             $Row.LogonProcessName = ([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “LogonProcessName”} | %{$_."#text"}             $Row.FalureTime = $_.TimeCreated                         $result.Rows.Add($Row)                     }     }   $result | Format-Table -AutoSize 

Пример использования:

PS> Find-Locker.ps1 -User i.i.inanov PS> Find-Locker.ps1 -Count 10 
Вместо P.S.

Да, есть Account Lockout and Management Tools с прекрасной утилитой LockoutStatus.exe, но она долго опрашивает все контроллеры домена (а некоторый из них могут быть и недоступны).
Предложенный скрипт никак не претендует на замену LockoutStatus.exe (у них совершенно разный принцип работы). Обычно я использую их вместе.

Готовый скрипт можно скачать с Google Drive: Find-Locker.ps1

ссылка на оригинал статьи http://habrahabr.ru/post/171701/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *