Pull to refresh

Аудит безопасности на сервере. Поиск по жураналу безопасности. Power Powershell

Reading time23 min
Views18K
Аудит журнала безопасности помог моему коллеге контролировать практически любые действия сотрудников, которые имеют хоть какой-то доступ к серверам или ActiveDirectory.

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

Первым делом необходимо было определить список событий, которые необходимо было отслеживать. Чтобы уменьшить количество текста, я создала процедуру, которая по ID события выдает ее описание:

Function DefineReason ($Id){
    switch ($Id){
        4741{ Return "Создана учетна запись компьютера"}
        4742{ Return "Изменена учетна запись компьютера" }
        4743{ Return "Удалена учетная запись компьютера"}
        4727{ Return "Создана глобальная группа с включенной безопасностью"}
        4728{ Return "Добавлен пользователь к глобальной группе с включенной безопасностью"}
        4729{ Return "Удален пользователь из глобальной группы с включенной безопасностью"}
        4730{ Return "Удалена глобальная группа с включенной безопасностью"}
        4731{ Return "Создана локальная группа с включенной безопасностью"}
        4732{ Return "Добавлен пользователь в локальную группу с включенной безопасностью"}
        4733{ Return "Удален пользователь из локальной группы с включенной безопасностью"}
        4734{ Return "Удалена локальная группа с включенной безопасностью"}
        4735{ Return "Изменена локальная группа с включенной безопасностью"}
        4737{ Return "Изменена глобальная группа с включенной безопасностью"}
        4743{ Return "Удалена учетная запись компьютера"}
        4754{ Return "Создана универсальная группа с включенной безопасностью" }
        4755{ Return "Изменена универсальная группа с включенной безопасностью"}
        4756{ Return "Добавлен пользователь к универсальной группе с включенной безопасностью"}
        4757{ Return "Удален пользователь из универсальной группы с включенной безопасностью"}
        4758{ Return "Удалена универсальная группа с включенной безопасностью"}
        4764{ Return "Изменен тип группы"}
        4720{ Return "Создана учетна запись"}
        4722{ Return "Включена учетна запись"}
        4724{ Return "Сброс пароля пользователя"}
        4725{ Return "Учетна запись пользователя отключена"}
        4726{ Return "Учетна запись пользователя удалена"}
        4738{ Return "Изменена учетна запись"}
        4740{ Return "Учетна запись пользователя заблокирована"}
        4767{ Return "Учетна запись пользователя разблокирована"}
        4780{ Return "Список управления Доступом был установлен на учетные записи, которые являются членами группы администраторов"}
        4781{ Return "Было изменено имя учетной записи"}
        4794{ Return "Была предпринята попытка задать режим восстановления служб каталогов"}
        5376{ Return "Диспетчер учетных данных: учетные данные были сохранены"}
        5377{ Return "Диспетчер учетных данных: учетные данные были востановлены из резервной копии"}
        4825{ Return "Запрeщен доступ к удаленному рабочемо столу, не входит в группу RDP"}
        1102{ Return "Удален журнал Security"}
    }
}

Затем понадобилось описать события, которые отслеживаются по маске доступа:

# Функция определения описания события по маске доступа

Function DefineReasonByAccessMask ($AccessMask){
    switch($AccessMask){
        "0xc0000064"  { Return "Имя пользователя не существует" }
        "0xc000006A"  { Return "Верное имя, но не правильный пароль"}
        "0xc0000234"  { Return "Пользователь заблокирован" }
        "0xc0000072"  { Return "Учетка деактивирована"}
        "0xc0000006F" { Return "Вход вне рабочее время"}
        "0xc00000070" { Return "Ограничение локальной станции"}
        "0xc00000193" { Return "Срок действия учетной записи истек"}
        "0xc00000071" { Return "Срок действия пароля Истек"}
        "0xc00000224" { Return "Необходимо сменить пароль при следующем входе"}
        "0xc000015b"  { Return "Пользователю запрещен вход на этой машине"}
        "0xc000006d"  { Return "Неверный пароль"}
    }
}

Теперь мы знаем, за чем хотим следить. Следующий шаг при разработке скрипта по аудиту — это получение журнала безопасности в формате XML, так как если событий много, то построчная обработка занимает достаточно большое количество времени.

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

1. Get-LogEvent security


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

— быстрый доступ к свойствам события;
— не нужна предварительная обработка для доступа к свойствам события.

Недостатки:

— доступ только с системному журналу безопасности, который хранится по пути: Windows/System32/winevt/security.evtx;
— долгая обработка содержимого тега . Обработка происходит путем построчной сепарации с ликвидацией спецсимволов.

2. Get-WinEvent –path “D:/”


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

— быстрая обработка журнала;
— доступ к любому журналу. Главное прописать полный путь.

Недостатки:

— для обработки полученного журнала требуется предварительная обработка.

Try {
$Events = Get-WinEvent -FilterHashTable $MyFilter
 } Catch {"No events were found in $Log"; Continue}
    ForEach ($Raw_Event in $Events)
    {	    
      Try{
          $EventXML = [xml]$Raw_Event.ToXML()
      } Catch {Write-Host "Unable to convert an event to XML"}
      $Event = @{}
      ForEach ($object in $EventXML.Event.EventData.Data) {
        $Event.Add($object.name,$object.'#text')
      }

      $Event.Add("ID",$Raw_Event.ID)
      $Event.Add("TimeCreated",$Raw_Event.TimeCreated)

Следующий шаг после того как мы получили доступ к журналу, это вытягивать из журнала требуемые события и принимать по ним соответствующие решения. В большинстве случаев – это отправка информационного сообщения на почту или логирование в отдельный файл.

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

image

1. Первый параметр предполагает, что журналы периодически экспортируются в определенный каталог, который и следует задать. Если журнал один, то задается стандартный каталог для хранения журналов: «C:\Windows\System32\winevt\Logs».

2. Второй параметр определяет сервер, по которому будет искаться логи. Если сервер один, то ставим «*».

3. Третий параметр предельно понятен: * — ищем события за весь период, если задана дата, например, 30.11.2015, то ищем за эту дату. Поиск за период осуществляется вводом начальной и конечной даты через тире (01.11.2015-30.11.2015).

4. Указываем путь для сохранения результата работы, например, «D:\log.log». Ниже приведен код, позволяющий построить интерфейс для скрипта:

$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "Ввод исходных данных"
$objForm.Size = New-Object System.Drawing.Size(300,450) 
$objForm.StartPosition = "CenterScreen"

# Events path
$objLabel1 = New-Object System.Windows.Forms.Label
$objLabel1.Location = New-Object System.Drawing.Size(10,20) 
$objLabel1.Size = New-Object System.Drawing.Size(280,40) 
$objLabel1.Text = "Введите полный путь к журналам в формате`nD:/.../.../ :"
$objForm.Controls.Add($objLabel1) 

$objTextBox1 = New-Object System.Windows.Forms.TextBox 
$objTextBox1.Location = New-Object System.Drawing.Size(10,60) 
$objTextBox1.Size = New-Object System.Drawing.Size(280,20) 
$objForm.Controls.Add($objTextBox1) 

#Find Server mode

$objLabel2 = New-Object System.Windows.Forms.Label
$objLabel2.Location = New-Object System.Drawing.Size(10,90) 
$objLabel2.Size = New-Object System.Drawing.Size(280,30) 
$objLabel2.Text = "1. * - по всем серверам.`n2. Укажите Сервер."
$objForm.Controls.Add($objLabel2) 

$objTextBox2 = New-Object System.Windows.Forms.TextBox 
$objTextBox2.Location = New-Object System.Drawing.Size(10,120) 
$objTextBox2.Size = New-Object System.Drawing.Size(280,30) 
$objForm.Controls.Add($objTextBox2)

#Type Events Mode

$objLabel3 = New-Object System.Windows.Forms.Label
$objLabel3.Location = New-Object System.Drawing.Size(10,150) 
$objLabel3.Size = New-Object System.Drawing.Size(280,45) 
$objLabel3.Text = "1. * - по всем событиям.`n2. Укажите событие.`n3. Перечислите через запятую события"
$objForm.Controls.Add($objLabel3) 

$objTextBox3 = New-Object System.Windows.Forms.TextBox 
$objTextBox3.Location = New-Object System.Drawing.Size(10,195) 
$objTextBox3.Size = New-Object System.Drawing.Size(280,30) 
$objForm.Controls.Add($objTextBox3)

#Date Events mode

$objLabel4 = New-Object System.Windows.Forms.Label
$objLabel4.Location = New-Object System.Drawing.Size(10,225) 
$objLabel4.Size = New-Object System.Drawing.Size(280,60) 
$objLabel4.Text = "1. * - за весь период.`n2. Укажите дату в формате ДД.ММ.ГГГГ.`n3. Укажите интервал в формате ДД.ММ.ГГГГ-ДД.ММ.ГГГГ"
$objForm.Controls.Add($objLabel4) 

$objTextBox4 = New-Object System.Windows.Forms.TextBox 
$objTextBox4.Location = New-Object System.Drawing.Size(10,285) 
$objTextBox4.Size = New-Object System.Drawing.Size(280,30) 
$objForm.Controls.Add($objTextBox4)

#Save Result

$objLabel5 = New-Object System.Windows.Forms.Label
$objLabel5.Location = New-Object System.Drawing.Size(10,315) 
$objLabel5.Size = New-Object System.Drawing.Size(280,30) 
$objLabel5.Text = "Путь для сохранения результата поиска"
$objForm.Controls.Add($objLabel5) 

$objTextBox5 = New-Object System.Windows.Forms.TextBox 
$objTextBox5.Location = New-Object System.Drawing.Size(10,345) 
$objTextBox5.Size = New-Object System.Drawing.Size(280,30) 
$objForm.Controls.Add($objTextBox5)

# Кнопки ОК и Отмена. Обработчки добавлен только на нажатие кнопки ОК. 

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,380)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($OKButton)
$OKButton.DialogResult=[System.Windows.Forms.DialogResult]::OK

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,380)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)

$objForm.Topmost = $True

$objForm.Add_Shown({$objForm.Activate()})
$dialogResult =  $objForm.ShowDialog()
# Описание интерфейса закончено

Получаем введенные данные:

# Определяем входящие параметры
if ($dialogResult -eq "OK"){
    $Log_Path       = $objTextBox1.Text
    $FindServerMode = $objTextBox2.Text
    $TypeEventsMode = $objTextBox3.Text
    $DateEventsmode = $objTextBox4.Text
    $SaveResult     = $objTextBox5.Text
}

Если в поле дата есть символ "-", значит введен интервал, если этот символ введен ошибочно — ваши проблемы. Проводим сепарацию по символу "-", определяем начальную и конечную дату диапазона.

if ($DateEventsmode -match "-"){
    $x = $DateEventsmode.split("-")
    $StartDate = $x[0]
    $EndDate = $x[1]
    $StartDate = [DateTime]::parse($StartDate)
    $StartDate 
    $EndDate = [DateTime]::parse($EndDate)
    $EndDate
}

Если во введенном поле нет ни "-", ни "*", то значит введена конкретная дата.

if ($DateEventsmode -notmatch "-" -and $DateEventsmode -ne "*"){
    $StartDate1 = [DateTime]::parse($DateEventsmode)
}

1. Поиск по всем серверам, по всем событиям, за весь период:

if ($FindServerMode -eq "*" -and $DateEventsmode -eq "*" -and $TypeEventsMode -eq "*" -and $Log_Path -ne ""){
Write-host "вошли в 1"
     $ALL_LOGS = Get-ChildItem -Path $Log_Path -recurse| Where {$_.Extension -eq ".evtx"} | Sort LastWriteTime
     $ALL_LOGS
     foreach ($Log in $ALL_LOGS){
        $LogFile = "Audit EventLog Security" +"`n"
        ($Log).FullName
        $MyFilter = @{Path=($Log).FullName}
        $i=0
        Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
        ForEach ($Raw_Event in $Events){
        	    
           Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
           
           $Event = @{}
           ForEach ($object in $EventXML.Event.EventData.Data) {
              $Event.Add($object.name,$object.'#text')
           }
           $Event.Add("ID",$Raw_Event.ID)
           $Event.Add("TimeCreated",$Raw_Event.TimeCreated) 
           $LogFile+= "EventID:            " + $Raw_Event.ID                      +"`n"
           $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
           $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
           $LogFile+= "Status:             " + $Event.Status                        +"`n"
           $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
           $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
           $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
           $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                     +"`n"
           $Reason = DefineReason -Id $Raw_Event.ID
           $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
           $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
           $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
           $LogFile+= "----------------------------------------------------------------`n"
           $i++ 
        }   
     }
}

2. Поиск по всем серверам, по фильтру событий, за весь период:

if ($FindServerMode -eq "*" -and $DateEventsmode -eq "*" -and $TypeEventsMode -ne "*" -and $Log_Path -ne ""){
Write-host "вошли в 2"
         $ALL_LOGS = Get-ChildItem -Path $Log_Path | Where {$_.Extension -eq ".evtx"} | Sort LastWriteTime
         $ALL_LOGS
         foreach ($Log in $ALL_LOGS){
            $LogFile = "Audit EventLog Security" +"`n"
            ($Log).FullName
            $MyFilter = @{Path=($Log).FullName;ID=$TypeEventsMode}
            Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
            ForEach ($Raw_Event in $Events){	    
               Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
               $Event = @{}
               ForEach ($object in $EventXML.Event.EventData.Data) {
                  $Event.Add($object.name,$object.'#text')
               }

               $Event.Add("ID",$Raw_Event.ID)
               $Event.Add("TimeCreated",$Raw_Event.TimeCreated)

               $LogFile+= "EventID:            " + $Event.ID                       +"`n"
               $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
               $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
               $LogFile+= "Status:             " + $Event.Status                        +"`n"
               $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
               $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
               $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
               $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                     +"`n"
               $Reason = DefineReason -Id $Raw_Event.ID
               $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
               $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
               $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
               $LogFile+= "----------------------------------------------------------------`n" 
            }
         }
     }

3. Поиск по всем серверам, по всем событиям, за диапазон:

if ($FindServerMode -eq "*" -and $DateEventsmode -match "-" -and $TypeEventsMode -eq "*" -and $Log_Path -ne ""){
Write-host "вошли в 3"
        $ALL_LOGS = Get-ChildItem -Path $Log_Path -Recurse| Where {$_.Extension -eq ".evtx" } | Sort LastWriteTime
        $ALL_LOGS
        foreach ($Log in $ALL_LOGS){
           $LogFile = "Audit EventLog Security" +"`n"
           ($Log).FullName
           $StartDate
           $EndDate
           $MyFilter = @{Path=($Log).FullName}
           Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
           ForEach ($Raw_Event in $Events){	    
              Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
              $Event = @{}
              ForEach ($object in $EventXML.Event.EventData.Data) {
                 $Event.Add($object.name,$object.'#text')
              }

              $Event.Add("ID",$Raw_Event.ID)
              $Event.Add("TimeCreated",$Raw_Event.TimeCreated)
              $Event.TimeCreated
              if ($Event.TimeCreated -gt $StartDate -and $Event.TimeCreated -lt $EndDate){
                   $LogFile+= "EventID:            " + $Raw_Event.ID                      +"`n"
                   $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
                   $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
                   $LogFile+= "Status:             " + $Event.Status                        +"`n"
                   $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
                   $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
                   $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
                   $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                     +"`n"
                   $Reason = DefineReason -Id $Raw_Event.ID
                   $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
                   $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
                   $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
                   $LogFile+= "----------------------------------------------------------------`n"
              }
            }
         }
     }

4. Поиск по всем серверам, по всем событиям, за определенную дату:

if ($FindServerMode -eq "*" -and $DateEventsmode -notmatch "-"  -and $DateEventsmode -ne "*" -and $TypeEventsMode -eq "*" -and $Log_Path -ne ""){
Write-host "вошли в 5"
    $ALL_LOGS = Get-ChildItem -Path $Log_Path -Recurse| Where {$_.Extension -eq ".evtx" -and $StartDate1 -ne "null" } | Sort LastWriteTime
    $ALL_LOGS
    foreach ($Log in $ALL_LOGS){
       $LogFile = "Audit EventLog Security" +"`n"
       ($Log).FullName
       $Log.LastWriteTime
       $StartDate
       $EndDate
       $MyFilter = @{Path=($Log).FullName}
       Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
       ForEach ($Raw_Event in $Events){	    
       Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
       $Event = @{}
       ForEach ($object in $EventXML.Event.EventData.Data) {
          $Event.Add($object.name,$object.'#text')
       }

       $Event.Add("ID",$Raw_Event.ID)
       $Event.Add("TimeCreated",$Raw_Event.TimeCreated)

       if ($Event.TimeCreated.Day -eq $StartDate1.Day -and $Event.TimeCreated.Month -eq $StartDate1.Month -and $Event.TimeCreated.Year -eq $StartDate1.Year){
            $LogFile+= "EventID:            " + $Raw_Event.ID                      +"`n"
            $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
            $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
            $LogFile+= "Status:             " + $Event.Status                        +"`n"
            $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
            $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
            $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
            $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                      +"`n"
            $Reason = DefineReason -Id $Raw_Event.ID
            $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
            $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
            $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
            $LogFile+= "----------------------------------------------------------------`n"
        }
     }
   }
}

5. Поиск по всем серверам, по фильтру событий, за определенный период:

if ($FindServerMode -eq "*"  -and $DateEventsmode -match "-" -and $DateEventsmode -ne "*" -and $TypeEventsMode -ne "*" -and $Log_Path -ne ""){
Write-host "вошли в 4"
     $ALL_LOGS = Get-ChildItem -Path $Log_Path -Recurse| Where {$_.Extension -eq ".evtx" -and $StartDate1 -ne ""} | Sort LastWriteTime
     $ALL_LOGS
     foreach ($Log in $ALL_LOGS){
        $LogFile = "Audit EventLog Security" +"`n"
        ($Log).FullName
        $Log.LastWriteTime
        $StartDate
        $EndDate
        $MyFilter = @{Path=($Log).FullName;ID=$TypeEventsMode}
        Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
        ForEach ($Raw_Event in $Events){	    
        Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
        $Event = @{}
        ForEach ($object in $EventXML.Event.EventData.Data) {
           $Event.Add($object.name,$object.'#text')
        }

        $Event.Add("ID",$Raw_Event.ID)
        $Event.Add("TimeCreated",$Raw_Event.TimeCreated)

        if ($Event.TimeCreated.Day -eq $StartDate1.Day -and $Event.TimeCreated.Month -eq $StartDate1.Month -and $Event.TimeCreated.Year -eq $StartDate1.Year){
            $LogFile+= "EventID:            " + $Raw_Event.ID                      +"`n"
            $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
            $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
            $LogFile+= "Status:             " + $Event.Status                        +"`n"
            $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
            $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
            $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
            $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                      +"`n"
            $Reason = DefineReason -Id $Raw_Event.ID
            $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
            $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
            $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
            $LogFile+= "----------------------------------------------------------------`n"
         }  
     }
  }              
}             

6. Поиск по всем серверам, по фильтру событий, за определенную дату:

if ($FindServerMode -eq "*" -and $TypeEventsMode -ne "*" -and $DateEventsmode -notmatch "-"  -and $DateEventsmode -ne "*" -and $Log_Path -ne "") {
Write-host "вошли в 6"
    $ALL_LOGS = Get-ChildItem -Path $Log_Path -Recurse| Where {$_.Extension -eq ".evtx" -and $StartDate1 -ne "" } | Sort LastWriteTime
    $ALL_LOGS
    foreach ($Log in $ALL_LOGS){
       $LogFile = "Audit EventLog Security" +"`n"
       ($Log).FullName
       $Log.LastWriteTime
       $StartDate
       $EndDate
       $MyFilter = @{Path=($Log).FullName;ID=$TypeEventsMode}
       Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
       ForEach ($Raw_Event in $Events){	    
          Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
          $Event = @{}
          ForEach ($object in $EventXML.Event.EventData.Data) {
             $Event.Add($object.name,$object.'#text')
          }

          $Event.Add("ID",$Raw_Event.ID)
          $Event.Add("TimeCreated",$Raw_Event.TimeCreated)

          if ($Event.TimeCreated.Day -eq $StartDate1.Day -and $Event.TimeCreated.Month -eq $StartDate1.Month -and $Event.TimeCreated.Year -eq $StartDate1.Year){
              $LogFile+= "EventID:            " + $Raw_Event.ID                      +"`n"
              $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
              $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
              $LogFile+= "Status:             " + $Event.Status                        +"`n"
              $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
              $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
              $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
              $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                      +"`n"
              $Reason = DefineReason -Id $Raw_Event.ID
              $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
              $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
              $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
              $LogFile+= "----------------------------------------------------------------`n"
           }
       } 
     }            
  }

7. Поиск на определенном, сервере поиск по всем событиям, за весь период:

if ($FindServerMode -ne "*" -and $DateEventsmode -eq "*" -and $TypeEventsMode -eq "*" -and $Log_Path -ne ""){
Write-host "вошли в 7"
    $ALL_LOGS = Get-ChildItem -Path $Log_Path -Recurse| Where {$_.Extension -eq ".evtx" -and $_.FullName -match $FindServerMode} | Sort LastWriteTime
    $ALL_LOGS
    foreach ($Log in $ALL_LOGS){
       $LogFile = "Audit EventLog Security" +"`n"
       ($Log).FullName
       $MyFilter = @{Path=($Log).FullName}
       Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
       ForEach ($Raw_Event in $Events){	    
          Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
          $Event = @{}
          ForEach ($object in $EventXML.Event.EventData.Data) {
             $Event.Add($object.name,$object.'#text')
          }

          $Event.Add("ID",$Raw_Event.ID)
          $Event.Add("TimeCreated",$Raw_Event.TimeCreated)

          $LogFile+= "EventID:            " + $Raw_Event.ID                      +"`n"
          $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
          $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
          $LogFile+= "Status:             " + $Event.Status                        +"`n"
          $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
          $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
          $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
          $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                      +"`n"
          $Reason = DefineReason -Id $Raw_Event.ID
          $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
          $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
          $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
          $LogFile+= "----------------------------------------------------------------`n"
        }
    }          
}

8. Поиск на определенном сервере, по фильтру событий, за весь период:

if ($FindServerMode -ne "*" -and $DateEventsmode -eq "*" -and $TypeEventsMode -ne "*" -and $Log_Path -ne ""){
     Write-host "вошли в 8"
     $ALL_LOGS = Get-ChildItem -Path $Log_Path -Recurse| Where {$_.Extension -eq ".evtx" -and $_.FullName -match $FindServerMode} | Sort LastWriteTime
     
     $ALL_LOGS
     foreach ($Log in $ALL_LOGS){
     $LogFile = "Audit EventLog Security" +"`n"
     ($Log).FullName
     $MyFilter = @{Path=($Log).FullName;ID=$TypeEventsMode}
     Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
     ForEach ($Raw_Event in $Events){	    
        Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
        $Event = @{}
        ForEach ($object in $EventXML.Event.EventData.Data) {
           $Event.Add($object.name,$object.'#text')
        }

        $Event.Add("ID",$Raw_Event.ID)
        $Event.Add("TimeCreated",$Raw_Event.TimeCreated)

        $LogFile+= "EventID:            " + $Event.ID                       +"`n"
        $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
        $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
        $LogFile+= "Status:             " + $Event.Status                        +"`n"
        $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
        $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
        $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
        $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                      +"`n"
        $Reason = DefineReason -Id $Raw_Event.ID
        $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
        $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
        $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
        $LogFile+= "----------------------------------------------------------------`n"
     }    
   }
}

9. Поиск на конкретном сервере, по всем событиям, за период:

if ($FindServerMode -ne "*"-and $DateEventsmode -match "-" -and $TypeEventsMode -eq "*" -and $Log_Path -ne ""){
Write-host "вошли в 9"
    $ALL_LOGS = Get-ChildItem -Path $Log_Path -Recurse| Where {$_.Extension -eq ".evtx" -and $_.FullName -match $FindServerMode -and $StartDate -ne "null" -and $EndDate -ne "null"} | Sort LastWriteTime
    $ALL_LOGS
    foreach ($Log in $ALL_LOGS){
       $LogFile = "Audit EventLog Security" +"`n"
       ($Log).FullName
       $Log.LastWriteTime
       $StartDate
       $EndDate
       $MyFilter = @{Path=($Log).FullName}
       Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
       ForEach ($Raw_Event in $Events){	    
          Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
          $Event = @{}
          ForEach ($object in $EventXML.Event.EventData.Data) {
             $Event.Add($object.name,$object.'#text')
          }

          $Event.Add("ID",$Raw_Event.ID)
          $Event.Add("TimeCreated",$Raw_Event.TimeCreated)

          if ($Event.TimeCreated -gt $StartDate -and $Event.TimeCreated -lt $EndDate){
              $LogFile+= "EventID:            " + $Raw_Event.ID                      +"`n"
              $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
              $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
              $LogFile+= "Status:             " + $Event.Status                        +"`n"
              $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
              $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
              $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
              $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                      +"`n"
              $Reason = DefineReason -Id $Raw_Event.ID
              $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
              $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
              $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
              $LogFile+= "----------------------------------------------------------------`n"
           }
        }
    }
}

10. Поиск на конкретном сервере, по фильтру событий, за период:

if ($FindServerMode -ne "*"  -and $DateEventsmode -match "-" -and $DateEventsmode -ne "*" -and $TypeEventsMode -ne "*" -and $Log_Path -ne ""){
Write-host "вошли в 10"
    $ALL_LOGS = Get-ChildItem -Path $Log_Path | Where {$_.Extension -eq ".evtx" -and  $_.FullName -match $FindServerMode -and $StartDate -ne "null" -and $EndDate -ne "null"} | Sort LastWriteTime
    $ALL_LOGS
    foreach ($Log in $ALL_LOGS){
       $LogFile = "Audit EventLog Security" +"`n"
       ($Log).FullName
       $Log.LastWriteTime
       $StartDate
       $EndDate
       $MyFilter = @{Path=($Log).FullName;ID=$TypeEventsMode}
       Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
       ForEach ($Raw_Event in $Events){	    
          Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
          $Event = @{}
          ForEach ($object in $EventXML.Event.EventData.Data) {
             $Event.Add($object.name,$object.'#text')
          }

          $Event.Add("ID",$Raw_Event.ID)
          $Event.Add("TimeCreated",$Raw_Event.TimeCreated)
                        
          if ($Event.TimeCreated -gt $StartDate -and $Event.TimeCreated -lt $EndDate){
               $LogFile+= "EventID:            " + $Raw_Event.ID                      +"`n"
               $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
               $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
               $LogFile+= "Status:             " + $Event.Status                        +"`n"
               $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
               $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
               $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
               $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                      +"`n"
               $Reason = DefineReason -Id $Raw_Event.ID
               $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
               $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
               $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
               $LogFile+= "----------------------------------------------------------------`n"
           }
        }
     }
 }

11. Поиск по конкретному серверу, по всем событиям, за определенную дату:

if ($FindServerMode -ne "*" -and $DateEventsmode -notmatch "-"  -and $DateEventsmode -ne "*" -and $TypeEventsMode -eq "*" -and $Log_Path -ne ""){
 Write-host "вошли в 11"
      $ALL_LOGS = Get-ChildItem -Path $Log_Path -Recurse| Where {$_.Extension -eq ".evtx" -and $StartDate1 -ne "null" } | Sort LastWriteTime
      $ALL_LOGS
      foreach ($Log in $ALL_LOGS){
         $LogFile = "Audit EventLog Security" +"`n"
         ($Log).FullName
         $Log.LastWriteTime
         $StartDate
         $EndDate
         $MyFilter = @{Path=($Log).FullName}
         Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
         ForEach ($Raw_Event in $Events){	    
            Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
            $Event = @{}
            ForEach ($object in $EventXML.Event.EventData.Data) {
               $Event.Add($object.name,$object.'#text')
            }

            $Event.Add("ID",$Raw_Event.ID)
            $Event.Add("TimeCreated",$Raw_Event.TimeCreated)

            if ($Event.TimeCreated.Day -eq $StartDate1.Day -and $Event.TimeCreated.Month -eq $StartDate1.Month -and $Event.TimeCreated.Year -eq $StartDate1.Year){
                 $LogFile+= "EventID:            " + $Raw_Event.ID                      +"`n"
                 $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
                 $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
                 $LogFile+= "Status:             " + $Event.Status                        +"`n"
                 $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
                 $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
                 $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
                 $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                      +"`n"
                 $Reason = DefineReason -Id $Raw_Event.ID
                 $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
                 $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
                 $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
                 $LogFile+= "----------------------------------------------------------------`n"
              }
            }          
        }
  }

12. Поиск по конкретному серверу, по фильтру событий, за определенную дату:

if ($FindServerMode -ne "*" -and $TypeEventsMode -ne "*" -and $DateEventsmode -notmatch "-"  -and $DateEventsmode -ne "*" -and $Log_Path -ne ""){
 Write-host "вошли в 12"
     $ALL_LOGS = Get-ChildItem -Path $Log_Path -Recurse| Where {$_.Extension -eq ".evtx" -and $StartDate1 -ne "null" } | Sort LastWriteTime
     $ALL_LOGS
     foreach ($Log in $ALL_LOGS){
        $LogFile = "Audit EventLog Security" +"`n"
        ($Log).FullName
        $Log.LastWriteTime
        $StartDate
        $EndDate
        $MyFilter = @{Path=($Log).FullName;ID=$TypeEventsMode}
        Try {$Events = Get-WinEvent -FilterHashTable $MyFilter} Catch {"No events were found in $Log"; Continue}
        ForEach ($Raw_Event in $Events){	    
           Try{$EventXML = [xml]$Raw_Event.ToXML()} Catch {Write-Host "Unable to convert an event to XML"}
           $Event = @{}
           ForEach ($object in $EventXML.Event.Message) {
              $Event.Add($object.name,$object.'#text')
           }

           $Event.Add("ID",$Raw_Event.ID)
           $Event.Add("TimeCreated",$Raw_Event.TimeCreated)
           $Event
           if ($Event.TimeCreated.Day -eq $StartDate1.Day -and $Event.TimeCreated.Month -eq $StartDate1.Month -and $Event.TimeCreated.Year -eq $StartDate1.Year){
                $LogFile+= "EventID:            " + $Raw_Event.ID                      +"`n"
                $LogFile+= "Target User Name:   " + $Event.TargetUserName                +"`n"
                $LogFile+= "Target Domain Name: " + $Event.TargetDomainName              +"`n"
                $LogFile+= "Status:             " + $Event.Status                        +"`n"
                $LogFile+= "TimeGenerated:      " + $Event.TimeCreated                   +"`n"
                $LogFile+= "Workstation Name:   " + $Event.WorkstationName               +"`n"
                $LogFile+= "IpAddress:          " + $Event.IpAddress                     +"`n"
                $LogFile+= "Computer:           " + [xml]$Raw_Event.ToXML().Event.System.Computer                      +"`n"
                $Reason = DefineReason -Id $Raw_Event.ID
                $AccessM = DefineReasonByAccessMask -AccessMask $Event.Status  
                $LogFile+= "Reason(RU):         " + $Reason  + " "+  $AccessM            +"`n"
                $LogFile+= "Reason(SYS):        " + $Event.Message                      +"`n"
                $LogFile+= "----------------------------------------------------------------`n"
           }
        } 
     }
}

В конце месяца (период индивидуально задается администраторами) журнал безопасности архивируется на сервер-хранилище, с указанием имени сервера и даты архивации.

После того как мы описали все варианты поиска событий. Полученный результат нам необходимо сохранить в файл, путь к которому прописал пользователь в последнем поле. Если путь задан, то результат сохраняется в файл. После отработки скрипта файл автоматически запускается. Если путь для сохранения результата не задан, то лог будет сохранен в рабочем каталоге под именем «log.log».

if ($SaveResult -ne ""){
   $LogFile | Out-File $SaveResult -Encoding utf8
   Invoke-Item  $SaveResult
   $Event2= @{}
   $Event = @{}
   $Log_Path=""

}
else{
   $LogFile | Out-File ".\log.log" -Encoding utf8
   Write-Host $LogFile
   $Event2= @{}
   $Event = @{}
   $Log_Path=""
}

Спасибо за внимание.

Во время написания скрипта очень полезной оказалась статья "PowerShell и аудит безопасности", спасибо автору.
Tags:
Hubs:
Total votes 12: ↑10 and ↓2+8
Comments8

Articles