При работе над этой серией статей я почти поверил, что с PowerShell у нас появилась технология, которая непонятным образом попала к нам из будущего. Помните сериал «Звездный путь» — оригинальный, конечно же, — когда старший офицер звездолета «Энтерпрайз» Спок смотрел в свой визор, сканируя парсеки космоса? На самом деле Спок разглядывал результаты работы одобренного Звездным флотом скрипта PowerShell.
Трикодеры? Также работают на основе технологии PowerShell.
Да, я являюсь поклонником технологии PowerShell, и смело исследую тему, которую никто из блогеров ранее не рассматривал. Для тех, кто воспитывался на элементарных языках оболочки Linux, PowerShell выглядит как сверхпродвинутая технология. Одна из высокотехнологичных функций PowerShell, как я упоминал ранее в своей заметке, — это возможность отслеживания низкоуровневых событий ОС, например обновления файлов.
Подробный анализ запроса Register-WmiEvent
Давайте вернемся к замечательному коду PS для мониторинга файлов всего из одной строки, который я представил в прошлый раз.
1. Register-WmiEvent -Query "SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA 'CIM_DataFile' and TargetInstance.Path = '\Users\bob\' and targetInstance.Drive = 'C:' and (targetInstance.Extension = 'doc' or targetInstance.Extension = 'txt)' and targetInstance.LastAccessed > '$($cur)' " -sourceIdentifier "Accessor" -Action $action
Как вы могли догадаться, логика того, что отслеживается, содержится в WQL в параметре запроса Register-WmiEvent.
Как мы помним, WQL позволяет авторам скриптов получать общую информацию о событиях системы Windows и, как в нашем случае, о событиях файлов — создании, обновлении или изменении файлов. С помощью этого запроса я легко получаю из темных глубин Windows сведения о событиях модификаций файлов, которые представлены в виде класса CIM_DataFile.
WQL позволяет задавать носитель и папку, в которых необходимо выполнить поиск. Для этого используются указанные выше свойства Driveи Path.
Хотя мне нельзя использовать поиск с применением подстановочных символов, — это особенность языка, а не ошибка — вместо этого я могу искать конкретные расширения файлов. При разработке скрипта для этой заметки моей целью было помочь специалистам по ИТ-безопасности обнаружить чрезмерную активность, связанную с текстовыми файлами. Поэтому я задал логическое условие для поиска файлов с расширениями doc или txt. Логично?
Теперь рассмотрим один неочевидный момент.
Мне требуется собирать сведения о событиях, возникающих, когда кто-либо пытается получить доступ к файлу, включая случаи, когда осуществляется только чтение документов Microsoft Word без внесения изменений.
Можно ли сделать это?
Всем нам знакомо поле «Дата изменения», доступное при просмотре списка файлов в проводнике Windows. Но знали ли вы, что существует также и поле «Дата доступа»? Каждый раз при чтении файла Windows в этом поле теоретически указывается текущая временная метка. Вы можете сами проверить это (см. далее), нажав заголовки столбцов и включив поле со сведениями о доступе.
Однако на практике компьютеры Windows обычно не настроены на обновление этого внутреннего поля, когда файл открывается только для чтения, а не для изменения. Компания Microsoft утверждает, что это снижает производительность. Но давайте отбросим сомнения.
Для настройки постоянного обновления времени доступа к файлам в Windows используйте недооцененную служебную программу fsutil (потребуются права администратора) со следующими параметрами:
fsutil set behavior disablelastaccess 0
Настроив события доступа к файлам в моей тестовой среде, я также активировал в Windows запись событий, связанных только с чтением.
В итоге я указал в приведенном выше коде WQL такой логичный критерий поиска:
targetInstance.LastAccessed > '$($cur)'
Он означает, что меня интересуют только события файлов, в которых доступ к файлам осуществляется после запуска Register-WmiEvent. Переменной $cur, кстати, присваивается значение текущего времени, получаемое из командлета Get-Date.
Анализ доступа к файлам
Мы рассмотрели язык WQL, теперь давайте перейдем к оставшимся параметрам Register-WmiEvent.
SourceIdentifer позволяет задать имя события. Присвоение имен — людям, полосатым кошкам или терьерам — рекомендуется использовать, поскольку это позволяет вызывать их при необходимости.
И это подходит и для событий! Есть несколько командлетов, для которых требуется этот идентификатор. Для новичков: Unregister-Event используется для удаления заданной подписки на события, Get-Event позволяет просматривать все события, которые были помещены в очередь, Remove-Event используется для удаления текущих событий в очереди, и наконец, Wait-Event используется для явного синхронного ожидания. Мы будем использовать некоторые из этих командлетов в конечном коде.
Я разобрал основные составляющие своего скрипта.
Остается рассмотреть параметр Action. Поскольку Register-WmiEvent реагирует на события асинхронно, требуется код, обрабатывающий реакцию на запускающие события, и в нем, скажем так, и заключается действие — в блоке передаваемого кода PowerShell.
И это нас приводит к тому, чего я на самом деле пытаюсь достичь с помощью своего скрипта, поэтому мне придется раскрыть свои грандиозные планы по завоеванию всего мира анализа поведения пользователей с помощью нескольких строк кода PowerShell.
Вот этот план. Этот скрипт PS будет отслеживать интенсивность событий доступа к файлам, сравнивать ее с эталонным значением и решать, попадает ли эта интенсивность в диапазон нехарактерных значений, который может указывать на потенциальную попытку взлома. При достижении этого порогового значения отобразится великолепная информационная панель с данными о последних действиях.
Другими словами, у меня будет система отслеживания угроз с оповещением, которая будет отмечать необычное поведение в отношении текстовых файлов в заданном каталоге.
Будет ли Powershell вытеснять с рынка другие решения для безопасности?
Нет, компании Varonis не стоит беспокоится об этом по нескольким причинам.
Во-первых, отслеживание событий в Windows нельзя назвать эффективным. На самом деле компания Microsoft предупреждает, что включение обновлений о последнем доступе к файлу посредством fsutil увеличивает нагрузку на систему. Кроме того, Register-WmiEvent разгоняет маховик внутренних событий: я столкнулся с комментариями, в которых утверждается, что командлеты могут замедлить работу системы.
Во-вторых, я заметил, что этот мониторинг выполняется не в реальном или близком к реальному времени: есть задержка при получении событий файлов, которая достигает 30 или более минут. По крайней мере таков был мой опыт запуска скриптов на моей виртуальной машине AWS. Возможно на вашей конкретной машине результаты будут лучше, но я не думаю, что компания Microsoft может что-то обещать по этому поводу.
В-третьих, как бы я не старался, у меня не получилось связать событие изменения файла с пользователем приложения, которое являлось причиной события. Другими словами, я знаю, что событие файла произошло, но, как это не прискорбно, не представляется возможным с помощью Register-WMIEvent выяснить, кто это сделал.
Поэтому я получил скрипт, который может отслеживать доступ к файлам, но без установления личности. Хммм… давайте создадим новую категорию контроля безопасности, называемую анализом доступа к файлам, которая собирает данные о моих действиях. Gartner, вы меня слышите?
Безусловно, анализ поведения пользователей — это гораздо более эффективный способ определения угроз, поскольку действия конкретных пользователей представляют собой интересную информацию. Мой менее детализированный анализ доступа к файлам, хотя и является полезным, не может точно определить неправомерное поведение, поскольку собирает данные о событиях нескольких пользователей.
Однако для небольших компаний с небольшим числом зарегистрированных учетных записей анализа доступа к файлам может быть достаточно. Например, администратор может использовать эти скрипты, если ему кажется подозрительным поведение пользователя, который слишком часто интересуется каталогом с конфиденциальными данными. Также у этого кода есть еще несколько привлекательных возможностей.
И даже если мой скрипт не до конца выполняет свою работу, еще более важным аргументом является понимание сложности работы с событиями Windows с помощью PowerShell (или другого используемого вами языка), что заставляет вас обратить внимание на решения корпоративного класса.
Теперь мы готовы посмотреть на блок скрипта Powershell моего командлета Register-WmiEvent:
1. $action = {
2. $Global:Count++
3. $d=(Get-Date).DayofWeek
4. $i= [math]::floor((Get-Date).Hour/8)
5.
6. $Global:cnts[$i]++
7.
8. #event auditing!
9.
10. $rawtime = $EventArgs.NewEvent.TargetInstance.LastAccessed.Substring(0,12)
11. $filename = $EventArgs.NewEvent.TargetInstance.Name
12. $etime= [datetime]::ParseExact($rawtime,"yyyyMMddHHmm",$null)
13.
14. $msg="$($etime)): Access of file $($filename)"
15. $msg|Out-File C:UsersbobDocumentsevents.log -Append
16.
17.
18. $Global:evarray.Add(@($filename,$etime))
19. if(!$Global:burst) {
20. $Global:start=$etime
21. $Global:burst=$true
22. }
23. else {
24. if($Global:start.AddMinutes(15) -gt $etime ) {
25. $Global:Count++
26. #File behavior analytics
27. $sfactor=2*[math]::sqrt( $Global:baseline["$($d)"][$i])
28. write-host "sfactor: $($sfactor))"
29. if ($Global:Count -gt $Global:baseline["$($d)"][$i] + 2*$sfactor) {
30.
31.
32. "$($etime): Burst of $($Global:Count) accesses"| Out-File C:UsersbobDocumentsevents.log -Append
33. $Global:Count=0
34. $Global:burst =$false
35. New-Event -SourceIdentifier Bursts -MessageData "We're in Trouble" -EventArguments $Global:evarray
36. $Global:evarray= [System.Collections.ArrayList] @();
37. }
38. }
39. else { $Global:burst =$false; $Global:Count=0; $Global:evarray= [System.Collections.ArrayList] @();}
40. }
41. }
Да, я проверяю вход в систему с помощью командлета Out-File, чтобы создавать для каждого случая доступа записи с временной меткой. И сравнивая число событий с эталонным значением в массиве $Global:baseline, я обнаруживаю всплески доступа к файлам через каждые 15 минут.
Здесь я немного пофантазировал и настроил мифическое среднее значение для числа событий в эталонном значении для каждого дня недели, разделяя каждый день на три восьмичасовых периода. Когда пиковая активность для заданного периода выпадает на дальний конец хвоста кривой нормального распределения, можно считать, что обнаружена угроза.
Информационная панель анализа доступа к файлам
Получив данные о пиковом увеличении числа событий в $Global:evarray (открывавшиеся файлы с указанием временных меток) я решил, что будет хорошей идеей отобразить эти данные в виде стильной информационной панели. Но вместо того, чтобы добавить этот код в блок скрипта, я «помещаю в очередь» эти данные в отдельном событии, которое может обрабатываться отдельными приложениями.
Что?!
Позвольте мне объяснить. Здесь вступает в игру командлет New-Event, указанный в конце представленного выше блока скрипта. Он просто позволяет мне асинхронно посылать сигналы другому приложению или скрипту, не привязывая таким образом этот код к блоку скрипта, чтобы потом можно было обработать следующее событие доступа к файлу.
Я представлю полный код моего скрипта PowerShell для анализа доступа к файлам в следующей заметке. Сейчас я просто скажу, что настроил командлет Wait-Event, единственным назначением которого является отбор этих всплесков событий и последующая их отправка на выход красивой таблицы с помощью Out-GridView.
Вот конечный результат, который отобразится в консоли администратора:
Великолепное решение, если учесть, что вся «платформа» анализа доступа к файлам реализована в 60 строках кода PS.
Мы рассмотрели много материала, на сегодня хватит.
Мы поговорим подробнее о скрипте анализа доступа к файлам в следующий раз, затем мы перейдем к рассмотрению превосходных возможностей классификации содержимого PowerShell.
Автор: Alexandra_Varonis