Аудит журнала безопасности помог моему коллеге контролировать практически любые действия сотрудников, которые имеют хоть какой-то доступ к серверам или 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)
Следующий шаг после того как мы получили доступ к журналу, это вытягивать из журнала требуемые события и принимать по ним соответствующие решения. В большинстве случаев – это отправка информационного сообщения на почту или логирование в отдельный файл.
Задать параметры, по которым будем вытягивать информацию, возможно, используя интерфейсное решения. Диалоговое окно с вводом параметров.
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 и аудит безопасности", спасибо автору.
ссылка на оригинал статьи http://habrahabr.ru/post/271963/
Добавить комментарий