четверг, 26 мая 2016 г.

ч2. Аудит сетевых файловых ресурсов / Audit network file shares

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

Первым делом необходимо включить ведение штатного аудита объектов в локальной политике файлового сервера:
 Вызываем консоль "Локальных политик" командой "gpedit.msc"
WIN+R >> вставить "gpedit.msc" >> ввод

По пути
– Computer Configuration
  – Windows Settings
     – Security Settings
        – Local Policies
           – Audio Policy
                 – Audit object Access
необходимо установить флаг Success.




Создаем папку с путем "C:\Scripts\"
В ней текстовый файл с именем, например audit_shared и расширением "ps1"
в него необходимо записать следующий код и сохранить

#Что бы сразу начать загружать события установим время начала загрузки событий -1 секунду с момента запуска

$Start_Time = (Get-Date).AddSeconds(-1)
#Необходимо получить версию ОС, так как на 2008 и 2012 журналы событий ведутся по #разному
$OS = (Get-WmiObject Win32_OperatingSystem).version


#Вводные переменные, сервер база и тп., последняя строчка преобразует все в правильный вид
$SQl_Server = 'prm-test-sql'
$SQLDateBase = 'audit_adm'
$BD_Table = 'audit_fs'
$BD_Table = $SQLDateBase + '.dbo.' + $BD_Table

#Подгружаем модуль для работы с SQL, про него можно прочитать тут
Import-Module ("C:\Scripts\SQLDataTools\SQLDataTools.psm1")

#Описываем функцию запросов к базе, что бы упростить структуру скрипта
function Query {Invoke-DatabaseQuery -verbose -connectionString ('Server=' + $SQl_Server + ';Database=' + $SQLDateBase + ';Trusted_Connection=True;') -isSQLServer -query $args[0]}

#Описываем функцию которая будет непосредственно загружать  события в базу
function Create_Query {
$STR_Q = $Null
[string]$STR_Q = 'INSERT INTO ' + $BD_Table + ' (SubjectUserName,IpAddress,ShareName,ShareLocalPath,RelativeTargetName,AccessMask,DateEvent,SRV) VALUES (N''' + $args[0] + ''',''' + $args[1] + ''',N''' + $args[2] + ''',N''' + $args[3] + ''',N''' + $args[4] + ''',''' + $args[5] + ''',''' + $args[6] + ''',''' + $args[7] + ''') ;'
Query $STR_Q
}


#Запускаем цикл загрузки и обработки событий из журнала Security с ID 5145
        Do{

$Events= $NUll
# Загрузка событий журнала, в зависимости от ОС. Маски указаны в запросе
if( $OS -match '6.1'){$Events = Get-WinEvent -FilterHashtable @{LogName="Security";ID=5145;StartTime=$Start_Time;Data="0x12019f","0x20","0x110080","0x10080"} }
if( $OS -match '6.3'){$Events = Get-WinEvent -FilterHashtable @{LogName="Security";ID=5145;StartTime=$Start_Time;Data="0x10080","0x2","0x100180","0x110080"} }


    #######################
    If ($Events -ne $Null){

#####
foreach ($Event in $Events){
if ($Events[0] -ne $Null) {
#$Start_Time = (($Events[0]).TimeCreated).AddMilliseconds(1)

$Start_Time = (($Events[0]).TimeCreated).AddMilliseconds(1)
$Start_Time = (($Start_Time).DateTime + '.' + ($Start_Time.Millisecond))

}

$AccessMask = $NUll
$AccessMask = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "AccessMask"}) -replace "^.+>")

$SubjectUserName = $NUll
$IpAddress = $NUll
$ShareName = $NUll
$ShareLocalPath = $NUll
$RelativeTargetName = $NUll


$SubjectUserName = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "SubjectUserName"}) -replace "^.+>")
$IpAddress = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "IpAddress"}) -replace "^.+>")
$ShareName = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "ShareName"}) -replace "^.+>")
$ShareLocalPath = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "ShareLocalPath"}) -replace "^.+>")
$RelativeTargetName = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "RelativeTargetName"}) -replace "^.+>")

$ShareLocalPath = $ShareLocalPath -replace '\\..\\'
$ShareName = $ShareName -replace "[\\*]"

    #условие исключающее не нужные сетевые ресурсы, а также логины пользователей
    if(($ShareName -ne 'IPC$') -and ($SubjectUserName -notmatch "s-")) {

        #Условие исключающее служебные файлы
        if ( ($RelativeTargetName -notmatch "Thumbs.db") -and ($RelativeTargetName -notmatch ".*tmp") -and ($RelativeTargetName -notmatch ".*~$*") -and ($RelativeTargetName -notmatch ".*~lock*")) {
          
            #У каждого события в журнале есть Маска, именно они определяют, что произошло с объектом. Расщифровку можно посмотреть тут
            #Расшифровка масок, в зависимости от ОС
            if( $OS -match '6.1'){$AccessMask = $AccessMask -replace '0x10080','delete' -replace '0x12019f','write' -replace '0x20','moveTo' -replace '0x110080','moveFrom' }
            if( $OS -match '6.3'){$AccessMask = $AccessMask -replace '0x10080','delete' -replace '0x2','write' -replace '0x100180','moveTo' -replace '0x110080','moveFrom' }
          
          
            Write-Host (($Event.TimeCreated).DateTime + ":" + ($Event.TimeCreated).Millisecond) $SubjectUserName $ShareName\$RelativeTargetName $AccessMask

            Create_Query $SubjectUserName $IpAddress $ShareName $ShareLocalPath $RelativeTargetName $AccessMask $Event.TimeCreated $env:computername

        }

  
    }
}

    }
    #######################

#Удаление старых записей старше 180 дней
#Query ('delete From ' + $BD_Table + ' where DateEvent <= cast (dateadd (day, -180, GETDATE()) as DATE)')
echo ("==" + $Start_Time + ":" + $Start_Time.Millisecond)
#Пауза 10 сек перед новым проходом
sleep 10
    }While($Stop_Flag -eq $NUll)

После чего, создаем задание в Task Scheduler с расписание после старта компьютера
 

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

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


Комментариев нет:

Отправить комментарий