Сбор и фильтрация событий входа в систему с помощью Log Parser



    Здравствуйте, уважаемое сообщество!


    ИТ-инфраструктура всегда находится в динамике. Тысячи изменений происходят ежеминутно. Многие из них требуется регистрировать. Аудит систем является неотъемлемой частью информационной безопасности организаций. Контроль изменений позволяет предотвратить серьезные происшествия в дальнейшем.

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

    Цели, которые мы преследуем:


    • Контроль ежедневных подключений пользователей к серверам организации, в том числе терминальным.
    • Регистрация события, как от доменных пользователей, так и от локальных.
    • Мониторинг рабочей активности пользователя (приход/уход).
    • Контроль подключений ИТ-подразделений к серверам ИБ.

    Для начала необходимо включить аудит и записывать события входа в журнал Windows. В качестве контроллера домена нам предоставлен Windows Server 2008 R2. Включив аудит, потребуется извлекать, фильтровать и анализировать события, определенные политикой аудита. Кроме того, предполагается отправка в третью систему на анализ, например, в DLP. В качестве альтернативы предусмотрим возможность формирования отчета в Excel.

    Анализ логов является рутинной операцией системного администратора. В данном случае объёмы фиксируемых событий в домене таковы, что это само по себе сложно. Аудит включается в групповой политике.

    События входа в систему формируются:

    1. контроллерами домена, в процессе проверки учетных записей домена;
    2. локальными компьютерами при работе с локальными учетными записями.

    Если включены обе категории политик (учетных записей и аудита), то входы в систему, использующие учетную запись домена, будут формировать события входа или выхода на рабочей станции или сервере и событие входа в систему на контроллере домена. Таким образом, аудит на доменные машины потребуется настроить через оснастку GPO на контроллере, аудит локальный — через локальную политику безопасности с помощью оснастки MMC.

    Настройка аудита и подготовка инфраструктуры:


    Рассмотрим этот этап подробно. Для уменьшения объемов информации мы смотрим только успешные события входа и выхода. Имеет смысл увеличить размер журнала security Windows. По умолчанию — это 128 Мегабайт.

    Для настройки локальной политики:

    image

    Открываем редактор политик – Пуск, в строке поиска пишем gpedit.msc и нажимаем Ввод.
    Открываем следующий путь: Local Computer Policy → Computer Configuration → Windows Settings → Security Settings → Local Policies → Audit Policy.

    Дважды кликаем параметр групповой политики Audit logon events (аудит входа в систему) и Audit account logon events (аудит событий входа в систему). В окне свойств устанавливаем Success-чекбокс для записи в журнал успешных входов в систему. Чекбокс Failure устанавливать не рекомендую во избежание переполнения. Для применения политики необходимо набрать в консоли gpupdate /force

    Для настройки групповой политики:

    Создаем новый объект GPO (групповую политику) с именем «Audit AD». Переходим в раздел редактирования и разворачиваем ветку Computer Configuration → Policies → Windows Settings → Security Settings → Advanced Audit Configuration. В данной ветке групповых политик находятся расширенные политики аудита, которые можно активировать в ОС семейства Windows для отслеживания различных событий. В Windows 7 и Windows Server 2008 R2 количество событий, для которых можно осуществлять аудит увеличено до 53. Эти 53 политики аудита (т.н. гранулярные политики аудита) находятся в ветке Security Settings\Advanced Audit Policy

    Configuration и сгруппированы в десяти категориях:

    Включаем:

    image

    • Account Logon – аудит проверки учетных данных, службы проверки подлинности Kerberos, операций с билетами Kerberos и других события входа;
    • Logon/Logoff – аудит интерактивных и сетевых попыток входа на компьютеры и сервера домена, а также блокировок учетных записей.

    После изменений выполняем gpupdate /force.

    Сразу оговорим типы событий, которые будет анализировать наш будущий скрипт:

    1. Remote access — удаленный вход через RDP-сессию.
    2. Interactive — локальный вход пользователя с консоли.
    3. Computer unlocked — разблокировка заблокированной станции.
    4. Logoff — выход из системы.

    В Windows 2008 событие успешного входа имеет идентификатор Event ID 4624, а logoff — Event ID 4672. Необходимо выбрать инструмент, позволяющий проанализировать огромное количество записей. Казалось бы, все можно написать, используя штатные инструменты. Однако, запросы на Powershell вида

    get-eventlog security | where  {$_.EventId -eq 4624 -and ($_.TimeGenerated.TimeOfDay
     -gt '08:00:00'  )}

    хорошо себя показывают только на стенде с контроллером домена на два пользователя. В продакшене средах сбор логов с сервера занимал по 20 минут. Поиски решения привели к утилите LOG PARSER , ранее обзорно рассмотренной на Хабре.

    Скорость обработки данных возросла в разы, полный прогон с формированием отчета с одного ПК сократился до 10 секунд. Утилита использует немало опций командной строки, поэтому мы будем вызывать cmd из powershell, чтобы избавиться от экранирования кучи специальных символов. Для написания запросов можно воспользоваться GUI — Log Parser Lizard. Он не бесплатен, но триального периода в 65 дней хватает. Ниже привожу сам запрос. Помимо интересующих нас, распишем и другие варианты входа в систему, на случай дальнейшего использования.

    SELECT 
    eventid, 
    timegenerated, 
     extract_token(Strings, 5, '|' ) as LogonName, 
    extract_token(Strings, 18, '|' ) as LogonIP, 
    case extract_token(Strings, 8, '|' ) 
     WHEN '2' THEN 'interactive' 
     WHEN '3' THEN 'network' 
     WHEN '4' THEN 'batch' 
     WHEN '5' THEN 'service' 
     WHEN '7' THEN 'unlocked workstation' 
     WHEN '8' THEN 'network logon using a cleartext password' 
     WHEN '9' THEN 'impersonated logons' 
     WHEN '10' THEN 'remote access' 
     ELSE extract_token(Strings, 8, '|' ) 
    end as LogonType, 
    case extract_token(Strings, 1, '|' ) 
     WHEN 'SERVER$' THEN 'logon' 
      
     ELSE extract_token(Strings, 1, '|' ) 
    end as Type 
    INTO \\127.0.0.1\c$\AUDIT\new\report(127.0.0.1).csv
    FROM \\127.0.0.1\Security
    WHERE 
    
     (EventID IN (4624) AND extract_token(Strings, 8, '|' )  LIKE '10') OR (EventID IN (4624) AND extract_token(Strings, 8, '|' ) LIKE '2') OR (EventID IN (4624) AND extract_token(Strings, 8, '|' ) LIKE '7') OR EventID IN (4647) AND
     TO_DATE( TimeGenerated ) = TO_LOCALTIME( SYSTEM_DATE() ) 
     ORDER BY Timegenerated DESC

    Далее привожу общее описание логики:

    1. Вручную формируем список хостов с настроенным локально аудитом, либо указываем контроллер домена, с которого забираем логи.
    2. Скрипт обходит список имен хостов в цикле, подключается к каждому из них, запускает службу Remote registry и, с помощью парсера, выполняет SQL-запрос audit.sql для сбора логов безопасности системы. Запрос модифицируется для каждого нового хоста с помощью примитивного регулярного выражения при каждой итерации. Полученные данные сохраняются в csv-файлах.
    3. Из файлов CSV формируется отчет в файле Excel (для красоты и удобства поиска) и тело письма в формате HTML.
    4. Создается почтовое сообщение отдельно по каждому файлу отчета и отправляется в третью систему.

    Готовим площадку для теста скрипта:


    Для корректной работы скрипта необходимо выполнение следующих условий:
    Создаем каталог на сервере/рабочей станции, с которой выполняется скрипт. Размещаем файлы скрипта в каталог С:\audit\. Список хостов и скрипт лежат в одном каталоге.

    Устанавливаем дополнительное ПО на сервер MS Log Parser 2.2 и Windows powershell 3.0 в составе management framework. Проверить версию Powershell можно, набрав $Host.version в консоли PS.

    Заполняем список интересующих нас серверов list.txt для аудита в каталоге С:\audit\ по именам рабочих станций. Настраиваем политику Аудита. Убеждаемся, что она работает.

    Проверяем, запущена ли служба удаленного реестра (скрипт делает попытку запуска и перевода службы в автоматический режим при наличии соответствующих прав). На серверах 2008/2012 эта служба запущена по умолчанию.

    Проверяем наличие прав администратора для подключения к системе и сбора логов.
    Проверяем возможность запуска неподписанных скриптов powershell на удаленной машине (подписать скрипт или обойти/отключить restriction policy).

    Внимание на параметры запуска неподписанных скриптов — execution policy на сервере:
    Обойти запрет можно подписав скрипт, либо отключить саму политику при запуске. Например:

    powershell.exe -executionpolicy bypass -file С:\audit\new\run_v5.ps1

    Привожу весь листинг скрипта:

    Get-ChildItem -Filter report*|Remove-Item -Force
    $date= get-date -uformat %Y-%m-%d
    cd 'C:\Program Files (x86)\Log Parser 2.2\'
    $datadir="C:\AUDIT\new\"
    $datafile=$datadir+"audit.sql"
    $list=gc $datadir\"list.txt"
    $data=gc $datafile
    $command="LogParser.exe -i:EVT -o:CSV file:\\127.0.0.1\c$\audit\new\audit.sql"
    $MLdir= [System.IO.Path]::GetDirectoryName($datadir)
    function send_email {
    $mailmessage = New-Object system.net.mail.mailmessage 
    $mailmessage.from = ($emailfrom) 
    $mailmessage.To.add($emailto)
    $mailmessage.Subject = $emailsubject
    $mailmessage.Body = $emailbody
    $attachment = New-Object System.Net.Mail.Attachment($emailattachment, 'text/plain')
    $mailmessage.Attachments.Add($attachment)
    #$SMTPClient.EnableSsl = $true
    $mailmessage.IsBodyHTML = $true
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25)  
    #$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("$SMTPAuthUsername", "$SMTPAuthPassword") 
    $SMTPClient.Send($mailmessage)
    }
    foreach ($SERVER in $list) { 
    Get-Service -Name RemoteRegistry  -ComputerName $SERVER | set-service -startuptype auto
    Get-Service -Name RemoteRegistry  -ComputerName $SERVER | Start-service
    $pattern="FROM"+" "+"\\$SERVER"+"\Security"
    $pattern2="report"+"("+$SERVER+")"+"."+"csv"
    $data -replace "FROM\s+\\\\.+", "$pattern" -replace "report.+", "$pattern2"|set-content $datafile
    <# #IF WE USE IP LIST
    $data -replace "FROM\s+\\\\([0-9]{1,3}[\.]){3}[0-9]{1,3}", "$pattern" -replace "report.+", "$pattern2"|set-content $datafile 
    #>
    cmd /c $command 
    }
    cd $datadir
    foreach ($file in Get-ChildItem $datadir -Filter report*) {
    #creating excel doc#
    $excel = new-object -comobject excel.application
    $excel.visible = $false
    $workbook = $excel.workbooks.add()
    $workbook.workSheets.item(3).delete()
    $workbook.WorkSheets.item(2).delete()
    $workbook.WorkSheets.item(1).Name = "Audit"
    $sheet = $workbook.WorkSheets.Item("Audit")
    $x = 2
    $colorIndex = "microsoft.office.interop.excel.xlColorIndex" -as [type]
    $borderWeight = "microsoft.office.interop.excel.xlBorderWeight" -as [type]
    $chartType = "microsoft.office.interop.excel.xlChartType" -as [type]
    For($b = 1 ; $b -le 5 ; $b++)
    {
     $sheet.cells.item(1,$b).font.bold = $true
      $sheet.cells.item(1,$b).borders.ColorIndex = $colorIndex::xlColorIndexAutomatic
     $sheet.cells.item(1,$b).borders.weight = $borderWeight::xlMedium
    }
    $sheet.cells.item(1,1) = "EventID"
    $sheet.cells.item(1,2) = "TimeGenerated"
    $sheet.cells.item(1,3) = "LogonName"
    $sheet.cells.item(1,4) = "LogonIP"
    $sheet.cells.item(1,5) = "LogonType"
    $sheet.cells.item(1,6) = "Type"
    
    Foreach ($row in $data=Import-Csv $file -Delimiter ',' -Header EventID, TimeGenerated, LogonName, LogonIP, LogonType, Tipe)
    { 
     $sheet.cells.item($x,1) = $row.EventID
     $sheet.cells.item($x,2) = $row.TimeGenerated
     $sheet.cells.item($x,3) = $row.LogonName
     $sheet.cells.item($x,4) = $row.LogonIP
     $sheet.cells.item($x,5) = $row.LogonType
     $sheet.cells.item($x,6) = $row.Tipe
     $x++
    } 
    $range = $sheet.usedRange
     $range.EntireColumn.AutoFit() | Out-Null
      $Excel.ActiveWorkbook.SaveAs($MLdir +'\'+'Audit'+ $file.basename.trim("report")+ $date +'.xlsx')
    if($workbook -ne $null)
     {
         $sheet = $null
         $range = $null
      
         $workbook.Close($false)
     }
     if($excel -ne $null)
     {
         $excel.Quit()
         $excel = $null
         [GC]::Collect()
         [GC]::WaitForPendingFinalizers()
     }
    $emailbody= import-csv $file|ConvertTo-Html
    $EmailFrom = "audit@vda.vdg.aero"
    $EmailTo = foreach ($a in (Import-Csv -Path $file).logonname){$a+"@"+"tst.com"}
    $EmailSubject = "LOGON"  
    $SMTPServer = "10.60.34.131"
    #$SMTPAuthUsername = "username"
    #$SMTPAuthPassword = "password"
    $emailattachment =  "$datadir"+"$file" #$$filexls
    send_email
           }

    Для полноценных отчетов в Excel устанавливаем Excel на станцию/сервер, с которой работает скрипт.

    Добавляем скрипт в планировщик Windows на ежедневное выполнение. Оптимальное время —конец дня — поиск событий проводится за последние сутки.

    Поиск событий возможен, начиная с систем Windows 7, Windows server 2008.
    Более ранние Windows имеют другие коды событий (значение кода меньше на 4096).

    Примечания и заключение:


    Еще раз подытожим выполненные действия:

    1. Настроили локальные и доменные политики аудита на нужных серверах и собрали список серверов.
    2. Выбрали машину для выполнения скрипта, установили нужный софт (PS 3.0, LOG PARSER, Excel).
    3. Написали запрос для LOG PARSER.
    4. Написали скрипт, запускающий этот запрос в цикле для списка,.
    5. Написали оставшуюся часть скрипта, обрабатывающую полученные результаты.
    6. Настроили планировщик для ежедневного запуска.

    Сгенерированные ранее отчеты лежат в каталоге до следующего выполнения скрипта. Список пользователей, выполнивших подключение, автоматически добавляется в получатели письма. Cделано это для корректной обработки при отправке отчета в систему анализа. В целом, благодаря LOG PARSER, получилось достаточно мощное, и, возможно, единственное средство автоматизации этой задачи. Удивительно, что такая полезная утилита с обширными возможностями не широко распространена. В минусы утилиты можно отнести слабую документацию. Запросы выполняются методом проб и ошибок. Желаю удачных экспериментов!
    InfoWatch
    Company

    Comments 9

      0
      Это всё конечно хорошо, проделан большой труд, но зачем мурыжить систему обработкой кучи логов. Не проще ли написать скрипт который будет заносить событие входа в систему в определенный файл, тоже самое и на клиентских компах. Распространить этот скрипт через GPO, триггер запуска поставить на вход пользователя… И всё!!! будет файл где видны от какой учетной записи и на каком компьютере был вход.
        0
        Согласен с вами, обычно чем проще тем лучше
        Но, во первых пользователь может обладать административными правами и отключить триггер/ отобрать права на запись в файл. Во вторых заказчик может не использовать GPO централизованно, а хочется универсальное решение.
        0
        Очень странные рекомендации «отключить failure». 1). Журнал не должен переполнится, Вы должны спланировать достаточное место под него. 2). Откуда возьмется переполнение если нет перебора пароля? 3). Если есть перебор пароля на ваших серверах, Вы закрываете глаза на него и ждете пока у брутфорсера success logon не наступит?
          0
          1. Да, но потери производительности сервера однозначно будут с ростом журнала аудита.
          2. Не рассматриваю только попытки перебора, событий и так много, ведь любое обращение к DC зафиксируется. Например триггеры от пользователя с истекшим паролем, попытки входа с локальным пользователем на доменные ресурсы, всевозможные update сервисы. Также преследую задачу по интеграции полученных результатов в другую систему. Важны успешные попытки входа, хочу отделить мух от котлет уже на первом этапе фильтрации.
          0

          Единственный способ, говорите? :) Тогда форвард логов на выделенный сервер, передача нужных событий в sql — тоже, в своем роде, единственные.

            0
            Перенаправить логи можно, но что дальше? Предлагаете поставить СУБД и дамп лога загрузить в SQL server?
              0

              А, что же, это не способ, что-ли? Он ещё и штатный, между прочим.


              В одном соглашусь на 200%: LOGPARSER -очень мощная штука, список типов и форматов источников, куда он умеет лазить довольно большой. Да и описанный Вами сценарий — далеко не единственное применение утилиты.

            0
            Какие видите плюсы и минусы по сравнению с MS OpsMgr ACS?

            ( по-моему, решает похожие задачи:
            Collecting Security Events Using Audit Collection Services in Operations Manager
            )
              0
              Я бы не стал их сравнивать — консольная утилита vs система проактивного мониторинга.
              Из плюсов, наверное, простота установки (без агентов) и бесплатность.
              Насчет минусов затрудняюсь сказать, мало работал с Operation manager

            Only users with full accounts can post comments. Log in, please.