С помощью аудита событий доступа к объектам файловой системы вы можете определить конкретного пользователя, который создал, удалил или изменил определенный файл. В этой статье мы покажем, как настроить аудит событий удаления объектов в общей сетевой папке на Windows Server 2016. После настройки аудита, вы можете с помощью информации в журнале событий найти пользователя, который удалил на файловом сервере.
Включаем политику аудита доступа к файлам и папкам в Windows
По умолчанию в Windows Server не включен аудит событий доступа к объектам на файловой системе. Вы можете включить и настроить аудит событий с помощью групповой политики. Если нужно включить политики аудита на нескольких серверах или компьютера, можно использовать доменные GPO (настраиваются с помощью консоли управления gpmc.msc). Если нужно настроить аудит только на одном сервере, можно воспользоваться локальной групповой политикой.
- Запустите консоль редактора локальной политики –
gpedit.msc
; - Перейдитевраздел GPO срасширенными политиками аудита Windows Settings -> Security Settings -> Advanced Audit Policy Configuration -> Object Access;
- Откройте политику Audit File System и укажите, что вы хотите сохранять в журнал только успешные события доступа к объектам файловой системы (Configure the following audit events -> Success);Также можно включить аудит доступа к локальным объектам с помощью политики Audit Object Access в разделе Windows Settings -> Security Settings -> Local Policy -> Audit Policy. Однако использование политики Audit File System предпочтительнее, поскольку она отслеживает только события NTFS.
- Сохраните изменения и обновите настройки локальной групповой политики с помощью команды
gpupdate /force
.
Настройка аудита событий удаления файлов из конкретной папки
Теперь нужно настроить аудит в свойствах общей сетевой папки, доступ к которой вы хотите отслеживать. Запустите проводник и откройте свойства общей папки. Перейдите на вкладку Security. Нажмите кнопку Advanced -> вкладка Auditing.
Если появится сообщение You must be an administrator or have been given the appropriate privileges to view the audit properties of this object, нажмите кнопку Continue.
Затем нажмите кнопку Add чтобы указать пользователя или группу, для которых нужно записывать все события аудита. Если вы хотите отслеживать события для всех пользователей, укажите группу Everyone.
Затем нужно указать использование каких разрешений доступа к объекту нужно записывать в лог. Чтобы сохранять в Event Log только события удаления файлов, нажмите кнопку Show advanced permissions. В списке событий оставьте аудит только для событий удаления папок и файлов — Delete и Delete subfolders and files.
$Path = "D:\Public"
$AuditChangesRules = New-Object System.Security.AccessControl.FileSystemAuditRule('Everyone', 'Delete,DeleteSubdirectoriesAndFiles', 'none', 'none', 'Success')
$Acl = Get-Acl -Path $Path
$Acl.AddAuditRule($AuditChangesRules)
Set-Acl -Path $Path -AclObject $Acl
Теперь, если пользователь удалит любой файл или папку в сетевой папке, в журнале безопасности системы появляется событие File System -> Audit Succes c Event ID 4663 от источника Microsoft Windows security auditing.
Откройте mmc консоль Event Viewer (
eventvwr.msc
), разверните секцию Windows Logs -> Security. Включите фильтр событий по EventID 4663.
Откройте любой их оставшихся событий в Event Viewer. Как вы видите, в нем есть информация об имени удаленного файла и учетной записи пользователя, который удалил файл.
An attempt was made to access an object. Subject: Security ID: CORP\aaivanov Account Name: aaivanov Account Domain: CORP Logon ID: 0x61B71716 Object: Object Server: Security Object Type: File Object Name: E:\Distr\Backup.rar Handle ID: 0x7bc4 Resource Attributes: S:AI Process Information: Process ID: 0x4 Process Name: Access Request Information: Accesses: DELETE Access Mask: 0x10000
После настройки аудита, найдите в журнале Security вы сможете найти с:
- Кто и когда удалил файл в сетевой папке;
- Из какого приложения удален файл;
- На какой момент времени нужно восстанавливать бэкап данного каталога.
Запись событий удаления файлов в SQL базу (MySQL/MSSQL)
Если после включения аудита удаления файлов в сетевой папке, вы видите в журнале много событий, найти что-то в логах бывает проблематично. Во-первых, найти нужную запись среди тысячи событий довольно сложно (в Windows отсутствуют вменяемые средства поиска интересующего события с возможностью гибкой фильтрации), а во-вторых, если файл был удален давно, это событие может просто отсутствовать в журнале, т.к. было перезатерто более новыми.
Вы можете записывать все нужные событий в отдельную SQL базу данных. Для хранения событий можно использовать Microsoft SQL Server, Elasticsearch или MySQL/MariaDB.
В этом примере мы покажем, как записывать события аудита в отдельную таблицу БД на сервере MySQL. Формат таблицы:
- Имя сервера;
- Имя удаленного файла
- Время удаления;
- Имя пользователя, удалившего файл.
MySQL запрос на создание такой таблицы будет выглядеть так:
CREATE TABLE track_del (id INT NOT NULL AUTO_INCREMENT, server VARCHAR(100), file_name VARCHAR(255), dt_time DATETIME, user_name VARCHAR(100), PRIMARY KEY (ID));
Если вы хотите использовать Microsoft SQL, обратите внимание на статью “Как выполнить запрос к MSSQL Server из скрипта PowerShell?”.
Для получения событий с EventID 4663 из журнала Security за текущий день можно использовать такой PowerShell скрипт:
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @{LogName="Security";starttime="$today";id=4663} | Foreach {
$event = [xml]$_.ToXml()
if($event)
{
$Time = Get-Date $_.TimeCreated -UFormat "%Y-%m-%d %H:%M:%S"
$File = $event.Event.EventData.Data[6]."#text"
$User = $event.Event.EventData.Data[1]."#text"
$Computer = $event.Event.System.computer
}
}
Следующий PowerShell скрипт запишет полученные данные в БД MySQL на удаленном сервере:
Set-ExecutionPolicy RemoteSigned
Add-Type –Path ‘C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v4.5\MySql.Data.dll'
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@{ConnectionString='server=10.7.7.13;uid=posh;pwd=P@ssw0rd;database=aduser'}
$Connection.Open()
$sql = New-Object MySql.Data.MySqlClient.MySqlCommand
$sql.Connection = $Connection
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @{LogName="Security";starttime="$today";id=4663} | Foreach {
$event = [xml]$_.ToXml()
if($event)
{
$Time = Get-Date $_.TimeCreated -UFormat "%Y-%m-%d %H:%M:%S"
$File = $event.Event.EventData.Data[6]."#text"
$File = $File.Replace(‘\’,’|’)
$User = $event.Event.EventData.Data[1]."#text"
$Computer = $event.Event.System.computer
$sql.CommandText = "INSERT INTO track_del (server,file_name,dt_time,user_name ) VALUES ('$Computer','$File','$Time','$User')"
$sql.ExecuteNonQuery()
}
}
$Reader.Close()
$Connection.Close()
Теперь, чтобы узнать, кто удалил файл «document1 — Copy.DOC». Достаточно в консоли PowerShell выполнить следующий скрипт.
$DeletedFile = "%document1 - Copy.DOC%"
Set-ExecutionPolicy RemoteSigned
Add-Type –Path ‘C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v4.5\MySql.Data.dll'
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@{ConnectionString='server=10.7.7.13;uid=posh;pwd=P@ssw0rd;database=aduser'}
$Connection.Open()
$MYSQLCommand = New-Object MySql.Data.MySqlClient.MySqlCommand
$MYSQLDataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter
$MYSQLDataSet = New-Object System.Data.DataSet
$MYSQLCommand.Connection=$Connection
$MYSQLCommand.CommandText="SELECT user_name,dt_time from track_del where file_name LIKE '$DeletedFile'"
$MYSQLDataAdapter.SelectCommand=$MYSQLCommand
$NumberOfDataSets=$MYSQLDataAdapter.Fill($MYSQLDataSet, "data")
foreach($DataSet in $MYSQLDataSet.tables[0])
{
write-host "User:" $DataSet.user_name "at:" $DataSet.dt_time
}
$Connection.Close()
В результате в консоли PS появится имя пользователя и время удаления файла.
$DataSet.file_name.Replace(‘|’,’\’)
. Спасибо Alex Kornev за замечание!Скрипт сброса данных из журнала в БД можно выполнять один раз в конце дня по планировщику или повесить триггер на событие удаления (On Event), что более ресурсоемко. Все зависит от требования к системе.
Можно создать реагировать простую веб страницу на php для получения информации о событиях удаления файлов в более удобном виде. Задача решается силами любого php программиста за 1-2 часа.
Запись информации о событиях удаления файлов в текстовый файл
Если вы не хотите вести отдельную БД, можно сохранять события аудита удалений файлов в текстовый лог файл. Воспользуйтесь таким PowerShell скриптом:
$Outfile = "C:\ps\delete-file-log.txt"
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @{LogName="Security";starttime="$today";id=4663} | Foreach {
$event = [xml]$_.ToXml()
if($event)
{
$Time = Get-Date $_.TimeCreated -UFormat "%Y-%m-%d %H:%M:%S"
$File = $event.Event.EventData.Data[6]."#text"
$User = $event.Event.EventData.Data[1]."#text"
$strLog = $Computer + " " + $File + " " + $Time + " " + $User
$strLog | out-file $Outfile –append
}
}
[/alert]
Итак, мы предложили идею и некий общий каркас системы аудита и хранения информации об удаленных файлах в сетевых шарах, при желании ее с лёгкостью можно будет модифицировать под ваши нужды.
Предполагается, видимо, что MySQL уже установлен и настроен?
100 лет уже не имел дела с «мускулом»…
Да, конечно. Причем он даже под Windows ставится несколькими кликами.
В общем-то код и всю технику можно легко адаптировать и под MSSql, но с точки зрения зрения легкости, отдаю предпочтению мусклу.
Прошелся по любимому сайту и нашел 🙂
https://winitpro.ru/index.php/2014/09/10/ustanovka-mysql-na-windows-server-2012-windows-8/
Извини если туплю, но из статьи НЕ очевтдно
куда засунуть и как запустить скрипт
«Скрипт сбора информации из журнала событий. Мы фильтруем журнал по событию с ID 4663 за текущий день»
а за ним все остальные
Подразумевал, что раз в сутки планировщик (допустим в 23:58) запускает powershell скрипт, который получает все события за прошедшие сутки и пишет из в базу.
Т.е. в создаем задание планировщика, которое запускет программу C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe с аргументом в виде имени файла со вторым скриптом C:\myscripts\WriteDelEventDB.PS1
«Скрипт сбора информации из журнала событий» — это просто пример работы с журналом событий, фильтрации и получения значений определенных полей. Он используется внутри следующего скрипта.
Что-то пошло не так. Или — что я сделал не так?
На первой же строке скрипта вылезает матершина:
(все делается под одним из Domain Admin аккаунтов)
PS C:\Users\admin> Get-WinEvent -FilterHashTable @{LogName=»Security»;starttime=»$today»;id=4663}
Get-WinEvent : Could not retrieve information about the Security log. Error: Attempted to perform
an unauthorized operation..
At line:1 char:1
+ Get-WinEvent -FilterHashTable @{LogName=»Security»;starttime=»$today»;id=4663}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WinEvent], Exception
+ FullyQualifiedErrorId : LogInfoUnavailable,Microsoft.PowerShell.Commands.GetWinEventCommand
Get-WinEvent : There is not an event log on the localhost computer that matches «Security».
At line:1 char:1
+ Get-WinEvent -FilterHashTable @{LogName=»Security»;starttime=»$today»;id=4663}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Security:String) [Get-WinEvent], Exception
+ FullyQualifiedErrorId : NoMatchingLogsFound,Microsoft.PowerShell.Commands.GetWinEventCommand
Get-WinEvent : The parameter is incorrect
At line:1 char:1
+ Get-WinEvent -FilterHashTable @{LogName=»Security»;starttime=»$today»;id=4663}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WinEvent], EventLogException
+ FullyQualifiedErrorId : System.Diagnostics.Eventing.Reader.EventLogException,Microsoft.Power
Shell.Commands.GetWinEventCommand
Пардону просим
Run As Administrator забыл сделать Ж-)
Здравствуйте, отличная статья. Решал подобную задачу для сбора статистики с KMS сервера, но использовал связку PS и MSSQL Express. Через год работы наткнулся на проблему, что превысил лимит базы данных в 10Гб, в итоге сделал ротацию данных в БД Наверное в вашем случае тоже было бы неплохо предусмотреть удаление старых данных? Могу поделиться наработками, если интересно. 🙂
Приветствую,
Насчет удаления старых данных пока не думал. Сложно оценить насколько будет большой база и за какой период нужна информация. Здесь больше идея рассматривается, какие-то выводы и усовершенствования можно делать только после опыта более продолжительного использования.
А инфой конечно, делитесь! Можно оформить отдельной статьей, думаю тема сбора и хранения статистики использования KMS сервера будет многим интересна.
Мой емайл есть на странице https://winitpro.ru/index.php/o-bloge/
Странно как-то себя MySQL повел ….
Поставил, для удобства, Navicat Premium Enterprise 11.2.4
)
и получается как-то странно
если делать, этим Navicat, Export всей таблицы из базы, то в поле file_name попадает имя файла целиком (правда отделенное пробелом почему-то от всего остального)
«id» «server» «file_name» «dt_time» «user_name»
«1440» «AUDITTEST» «DeviceHarddiskVolume2TEST 0000.txt» «5.5.2016 12:12:24» «name»
а когда делаешь select … то имя файла обрезается до полного пути до него
SELECT track_del.file_name,track_del.dt_time,track_del.user_name FROM track_del
а на выходе
file_name dt_time user_name
DeviceHarddiskVolume2TEST 2016-05-05 12:12:24 name
Если присмотреться, то в поле file_name попадается пробел. И, походу, по нему и режется. А пока оно так себя ведет, дальше ничего не работает. То есть невозможно сделать LIKE по значению, которое не показывается
Починил.
В скрипте, который заполняет таблицу в БД, вставил строку, которая меняет в имени файла, получаемого из Security Even Log’a все ‘\’ на ‘|’ Вот здесь:
$File = $event.Event.EventData.Data[6].»#text»
$File = $File.Replace(‘\’,’|’)
После этого имя файла перестало «теряться» и попадает в БД как надо 🙂
И потом, слегка «доработал» скрипт, который выдает результат. Мне плказалось так и красивее, и правильнее. Добавлен вывод имени файла с полным путем. с обратной заменой ‘|’ на ‘\’
foreach($DataSet in $MYSQLDataSet.tables[0])
{
write-host «File:» $DataSet.file_name.Replace(‘|’,’\’) — «User:» DataSet.user_name «at:» $DataSet.dt_time
}
А ведь это был _очень_неприятный баг MySQL, на самом деле
Файл, на котором я «тренировался», я назвал
00000.txt
(5 нулей) и, в итоге, в базу из Event Log’a попадало вот чтоDeviceHarddiskVolume2TEST 0000.txt
То есть при выполнении INSERT MySQL «выгрызал» все символы ‘\’ и, более того делал из подстроки
0000.txt
такое вот"[SPACE]0000.txt"
типа пытался «интерпретироватьпо своему»?
А после того как я, предварительно, заменял все ‘\’ на ‘|’ — все проходило как надо
Дмитрий, думаю не лишним будет или упомянуть об этой «особенности» или поправить скрипт, который заносит имя файла в таблицу БД.
Видимо проблема в сочетании
"\"+"0"
, которое как-то интерпретируется mysql, то ли пустая строка, то ли что-то в этом роде.Согласен, в скрипте лучше всего заменить ‘\’ на ‘|’, а при выборке делать обратную замену.
Сейчас внесу изменения в статью. Спасибо!
А что скажете про [regex]::Escape(‘c:\’) ?
Я подобную штуку сейчас проворачиваю, но отправляю пошиком не напрямую в базу, а через пхп, так вот эскейп работает как надо. Мне интересно как будут обстоять дела, если пошиком напрямую в базу лить, но сам пробовать не хочу ))
Коллеги кто нибуть настраивал данную возможность с помощью SCOM?
Есть ли информация по данному вопросу,может быть кто то уже имел опыт,заранее спасибо за ответ.
Для настройки мониторинга данного EventID нужно в SCOM создать новое правило (Rule).
Правило создаём тут: Authoring -> Management Pack Objects -> Rules.
При создании указываем Type: Alert Generating Rules -> Event Based -> NT Event Log (Alert); Rule target: Windows Domain controller, Log Name: Security, Event ID eq 4663. Затем нужно привязаться к новому правилу действие в Subscription.
Странная команда в скрите
«Следующий скрипт запишет полученные данные в БД MySQL на удаленном сервере:»
вот эта
$Reader.Close()
PowerShell ругается на нее. Наверное и правильно. Ведь закрывается то, что не открывалось.
А для Win2k как сделать подобное?
В нем аудит естьт, политика безопасности — есть, а события 4663 не выдается (((
Может кто сталкивался?
ID события скорее всего другие, да и не факт что PowerShell вообще заведется на W2k..
ЗЫ. Закапывайте мамонта
MySQL запрос на создание такой таблицы будет выглядеть так:
CREATE TABLE track_del (id INT NOT NULL AUTO_INCREMENT, server VARCHAR(100), file_name VARCHAR(255), dt_time DATETIME, user_name VARCHAR(100), PRIMARY KEY (ID));
результат.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ‘AUTO_INCREMENT’.
Понял my SQL
Здраствуйте. Никогда раньше ни делал ничего подобного. Со второго раза вроде получилось. У меня вопрос в событии у меня есть строка » 192.168.201.153″ как добавть дополнительный столбец в таблицу и как в него записывать Ip адресс?
добрый день.
собран кластер на WS2016.
Есть CSV. Эту шару я и хочу логировать. Делаю все по инструкции, но когда что-либо оттуда удаляю, нет записи в логах Security.
Был ли опыт проведения аудита на кластерной шаре?
Спасибо. Хорошая статья.
Под рукой такой конфигурации нет. Могу посоветовать
1) проверить, что политики аудита применяются для обычных шар (записи в логе появляются).
2) в случае CSV возможно стоит проверять все логи на всех нодах кластера
1) работает, идеально.
2) проверяю на всех, к сожалению нет.
Запускай на каждой ноде. В Скрипте проверяй кто владеет нодой:
$ClusterRoleOwner = (Get-ClusterGroup | Where-Object {($_.Name -eq «ИМЯ ТВОЕЙ РОЛИ»)}).OwnerNode
если тот кто надо, то читаешь логи:
if ($ClusterRoleOwner -eq $env:computername)
Отличный каркас для работы с логами. После лёгкой косметической допилки всё полетело на MSSQL Express 2014 ADV (ставить на сервер вторую СУБД смысла нет). Бага с чир-символом в этой версии MSSQL нет. Всё загружается и выгружается чётко. 🙂
Спасибо автору))
Спасибо! Очень полезная вещь!
Пожалуйста подскажите, как быть с кириллицей в имени каталогов и файлов? В таблице вместо кириллицы знаки вопроса «…??????|?????.docx».
Что делать с русской кодировкой в именах файлах, к сожалению, не знаю. Как вариант — экспортировать журналы в csv файлы. А потом при загружать их через Get-Content -Encoding UTF8. Но это на уровне идеи…
Для правильного сохранения кириллицы добавьте в конец строки «charset=utf8»
Должно получится так
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@{ConnectionString='server=10.7.7.13;uid=posh;pwd=P@ssw0rd;database=aduser;charset=utf8'}
Отлично! Спасибо за полезную инфу!
Доброго времени суток. Попробовал, все равно «??????|?????.pdf» 🙁
Спасибо огромное. Разобрался. Нужно было сменить кодировку в самой БД на utf8_unicode_ci.
Для работы с любыми логами использую graylog community edition можно купить enterprise edition , и там делаю с логами что угодно
А что для визуализации данных и логов используете (графические дашборды, отчеты)?
С Elasticsearch обычно используют Kibana. А что у graylog как аналог?
PS C:\WINDOWS\system32> $event = [xml]$_.ToXml()
Невозможно вызвать метод для выражения со значением NULL.
строка:1 знак:1
+ $event = [xml]$_.ToXml()
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Как поправить?
Какая ОС и версия PowerShell?
Windows Server 2012 R2 6.3.9600.18969 64-разрядная
Version PS : 5.1.14409.1018
Странно у меня в такой же конфигурации все работает. Windows Server случайно не русская? Я такую принципиально не пользую, только eng.
Нет. Проверил в 10-ке (правда «русской») — тоже такая же «петрушка»
Ну вот у меня код работает даже в русской Windows….
Запускаете в PowerShell ISE под админом?
Да, под админом
Не работает
А если удалять файлы с помощью Shift+DEL, то регистрируется только событие с id 4659. По крайней мере у меня на Windows Server 2012 так.
Здравствуйте, у нас стоят 2 сервера с Windows 2019, и на них установлен DFS с авторепликацией на оба сервера.
В результате у нас нет нормального аудита: в списках по событию 4663 (мы используем дополнительно фильтр по маске 0х10000, что предположительно соответствует операции DELETE) есть файлы с названиями типа
D:\System Volume Information\DFSR\Private\{ABC…}-{DEF…}\Installing\Teil-of-name-{123..}-v123456.doc
(это после удаления всех файлов типа .log, .tmp и \~$ ). Причём в качестве пользователя стоит имя сервера.
Ещё есть удаления целых каталогов (?!), тоже с именем сервера. В поле ProzessName стоит C:\Windows\System32\dfsrs.exe
Есть и удаления от конкретных пользователей, но от них идут несколько удалений одних и тех же файлов — это вероятно результаты неоднократных редактирований того же файла… При этом поле ProzessName вообще пустое!
Вопрос: каким образом можно обнаружить удаления при использовании DFS ?
Колеги а как очистить журнал после того, как витянул данные с журнала?
Я же буду на постой дозаписывать то, что уже есть.
Очистка журналов событий в Windows: https://winitpro.ru/index.php/2017/07/31/ochistka-zhurnalov-sobytij-windows-s-pomoshhyu-powershell-i-wevtutil/
Нужно искать пару : id 4663 а потом 4660 с аналогичным кодом дескриптора в двух событиях. Тогда это будет реальное удаление.
https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4660
Доброго времени, уважаемые коллеги!
У меня сервер 2008. Сделал всё как тут написано, получилось на ура. Но хотелось бы задать вопрос. В событиях по коду 4663 регистрируется только пользователь и действия с файлом, которые он инициировал. Но хотелось бы в событиях поиметь или имя компа или его айпишник. Думал, на 2008 серваке такого нет, а есть в более поздних серверных версиях, но нет. На работе посмотрел, также без айпишников логи ведутся.
Есть ли возможность добавить в событие 4663 IP или имя компа? Хочу вычислить, откуда вирусня прёт, а то в этой организации многие сидят под одним логином. Я говорю, давайте каждому учётку заведём. Нет, говорят. Нам так удобнее. Ну что с такими делать?
Имеено это событие вы никак не расширите. Тут нужно скорре всего нужно дополнительно анализировать события логона компьютера на ваш сервере из журнала Security. Скорее всего они будут связаны по logonID или handleID. И уже из события логона вытягивать имя компьютера.
Сначала попробуйте вручную разобраться с ID события и их связью с 4663 . Пришлите инфу сюда, может помогу в чем.
—
4663
1
0
12800
0
0x8020000000000000
1013357
Security
pismo
—
S-1-5-21-2924944393-1657555545-3026754319-501
Гость
PISMO
0xc4bc6
Security
File
D:\pismo1\!Tinchlik\Бизнес кредитларни ундириш шўъбаси\ФАЙЛ
0xc68
%%1537
0x10000
0x4
S:AI
здесь вошел в систему как гость, и все пользователи входят в систему под этим именем. Как я могу определить IP-адрес, чтобы найти человека или компьютер, который удалил файл?
Выполнена попытка получения доступа к объекту.
Субъект:
ИД безопасности: PISMO\Гость
Имя учетной записи: Гость
Домен учетной записи: PISMO
ИД входа: 0xC4BC6
Объект:
Сервер объекта: Security
Тип объекта: File
Имя объекта: D:\pismo1\!Tinchlik\Бизнес кредитларни ундириш шўъбаси\ФАЙЛ
Код дескриптора: 0xc68
Атрибуты ресурса: S:AI
Сведения о процессе:
ИД процесса: 0x4
Имя процесса:
Сведения о запросе на доступ:
Операции доступа: DELETE
Маска доступа: 0x10000
Спасибо за статью. Пришлось исправить, т.к. у меня Server 2008 R2 (соответственно там старая версия Powershell), данные выгружаются в MySQL 5.0.95, который находится на другом старом Linux сервере:
1) В базе выполнил SQL-запрос:
SET SESSION old_passwords=0;
SET PASSWORD FOR db_user_name=PASSWORD(‘db_user_password’);
2) Скрипт выглядит так:
Set-ExecutionPolicy RemoteSigned
Add-Type –Path ‘C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v2.0\MySql.Data.dll’
$connectionString = «server=server_IP;uid=db_user_name;pwd=db_user_password;database=db_name;»
$connection = New-Object MySql.Data.MySqlClient.MySqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$sql = New-Object MySql.Data.MySqlClient.MySqlCommand
$sql.Connection = $Connection
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @{LogName=»Security»;starttime=»$today»;id=4663} | Foreach {
$event = [xml]$_.ToXml()
if($event)
{
$Time = Get-Date $_.TimeCreated -UFormat «%Y-%m-%d %H:%M:%S»
$File = $event.Event.EventData.Data[6].»#text»
$File = $File.Replace(‘\’,’|’)
$User = $event.Event.EventData.Data[1].»#text»
$Computer = $event.Event.System.computer
$sql.CommandText = «INSERT INTO track_del (server,file_name,dt_time,user_name ) VALUES (‘$Computer’,’$File’,’$Time’,’$User’)»
$sql.ExecuteNonQuery()
}
}
$Connection.Close()
3) Создал задание в планировщике с такими параметрами:
Вкладка Общие:
-выполнять вне зависимости от регистрации пользователя
-выполнять с наивысшими правами
-выполнять от учетки админа домена
Вкладка Триггеры:
-начать задачу при событии
-Параметры: Простое, Журнал — Безопасность, Источник — Microsoft Windows security auditing, Код события — 4663
-внизу галочка — Включено
Вкладка Действия:
-Действие — Запуск программы
-Программа или сценарий: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
-Добавить аргументы: E:\scripts\file_del_to_db.ps1 (путь к скрипту)
Вкладка Параметры:
-Разрешать выполнение задачи по требованию
-Останавливать задачу, выполняемую дольше: 3 дн.
-Принудительная остановка задачи, если она не прекращается по запросу
-Если задача уже выполняется, то применять правило: Не запускать новый экземпляр.
Ну и при сохранении задачи естественно нужно будет ввести пароль пользователя, от имени которого она будет выполняться (у меня учетка админа домена).
Теперь особенность. За 1,5 дня у меня в базе 8000 записей. Как бы много, и не очень удобно в случае чего искать нужные.
Просьба к автору статьи, не могли бы Вы изменить скрипт так, чтобы данные в базу писались каждый день в отдельные таблицы или как-то по-другому их отделить, а также сделать исключение файлов, например, по расширению (а то пользователи напрямую открывают по сети файлы Microsoft Office и в базу потом пишутся записи об удалённых файлах *.tmp). Спасибо))).
За инфу спасибо.
1) Писать в разные таблицы? а зачем, не проще фильтровать записи по дате.
2) Чтобы писать инфу только по нужным расширениям файлам, просто сделайте дополнительную проверку содержимого $File на соответствие нужным расширениям файлов перед запись в базу:
$allowedext = @('.doc','.docx','.xlsx','.xls')
$fileext=[System.IO.Path]::GetExtension($file)
if ($allowedext -match $fileext')
{
write to db
}
Спасибо за ответ. Не могу точно знать какие типы файлов там есть, т.к. структура папок огромная, всего примерно 2 млн. файлов))) Конечно и ненужные есть, но рыться там у меня нет желания, у каждого отдела своя папка… короче там чёрт ногу сломит))). Поэтому вышел из положения так:
1) Перенес базу на новый Linux сервер, там 10.3.28-MariaDB. В ней есть уже планировщик заданий.
2) В phpmyadmin создал задачу, которая каждый день в 00:00 удаляет из базы записи о файлах *.tmp.
Параметры задачи такие:
Название события: file_del_tmp_every_day
Состояние: ENABLED
Тип события: RECURRING
Выполнять каждые: 1 DAY
Начало: 2021-05-14 00:00:00
Конец: (Пусто)
Определение: delete from `db_name`.`track_del` where file_name like ‘%.tmp’
Сохранить при окончании: (Поставил галочку)
Определитель: root@localhost
Также нужно не забыть:
Статус планировщика событий: Включить
Пока пусть будет так. Правда с 14 мая 2021 до сегодня (21 мая 2021) размер базы 114 МБ и количество строк примерно 530000))). Жесть конечно, пока не знаю что с этим делать))).
Из личных наблюдений. События 4660 и 4663 появляются при локальном удалении из локальной или сетевой папки, т.е. пользователь совершил локальный вход на сервер и удаляет файл с диска или из папки в общем доступе. Событие 4659 — при сетевом удалении из сетевой папки. Так что как применять статью не понятно.
В новых версиях Windows при удалении минуя корзину ещё записываются события с кодом 4659. Достаточно добавить код этого события в скрипт. Например, для записи списка удаленных файлов в текстовый файл изменить строку примерно так:
…
Get-WinEvent -FilterHashTable @{LogName=»Security»;starttime=»$today»;id=4663,4459} | Foreach {
…
Скрипт записи в текстовый файл дополненный выборкой только по удаленным файлам:
$Outfile = «C:\ps\delete-file-log.txt»
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @{LogName=»Security»;starttime=»$today»;id=4663} | Foreach {
$event = [xml]$_.ToXml()
if($event.Event.EventData[9].’#text’ -eq ‘0x10000’)
{
$Time = Get-Date $_.TimeCreated -UFormat «%Y-%m-%d %H:%M:%S»
$File = $event.Event.EventData.Data[6].»#text»
$User = $event.Event.EventData.Data[1].»#text»
$strLog = $Computer + » » + $File + » » + $Time + » » + $User
$strLog | out-file $Outfile –append
}
}
Корректировка) пропустил Data[9]
$event.Event.EventData.Data[9]
Статья нужная, но нам нужно было на создание файлов в обмене и отправлялся отчет. Добавили в планировщик задачу с выполнением скрипта. Если кому нужно сам скрипт:
$Outfile = "D:\audit.txt" #$(Get-Date -UFormat "%d-%m-%Y_%H_%M_%S").txt" - у меня сохраняет в единый файл, но кому надо будет создавать ежедневный отчет.
$today = [datetime]::Today.AddDays(-5) #Get-Date -DisplayHint date -UFormat %d-%m-%Y Указал за последние 5 дней сбор данных
$strLog = @()
Get-WinEvent -FilterHashTable @{ LogName = "Security"; starttime = $today; id = 4663} | Foreach {
$event = [xml]$_.ToXml()
if($event) {
$Time = Get-Date $_.TimeCreated -UFormat "%d-%m-%Y %H:%M:%S"
$File = $event.Event.EventData.Data[6]."#text"
$User = $event.Event.EventData.Data[1]."#text"
If ($User -notmatch "SERVER\$|LOCAL SERVICE" -and $File -match "F:\\obmen") { # исключаем наименование сервера SERVER\$|LOCAL SERVICE (у вас будет имя иначе) и включать только записи с расположением папки obmen
$strLog += $Time + " " + $User + " " + $Computer + " " + $File
}
}
}
$strLog | out-file $Outfile
#Отправляем письмо с отчетом о проведении аудита
$ToAddress = "[email protected]"
$CcAddress = "[email protected]"
$FromAddress = "[email protected]"
$SmtpServer = "mail.pochta.ru"
$sabj = "Аудит обмена"
$text = "text"
$mailparam = @{
To = $ToAddress
Cc = $CcAddress
From = $FromAddress
Subject = $sabj
Body = $text
SmtpServer = $SmtpServer
Attachments = "d:\audit.txt"
}
Send-MailMessage @mailparam -Encoding UTF8
Пользуйтесь.
А можно пример скрипта который в текстовой файл записывает удаленные и редактируемые объекты
(вывод в формате расположение файла-время-пользователь-действие)
Отличная статья, спасибо!
Правда у меня не всё получилось. На некоторых подпапках отключено наследование прав по аудиту и устанавливая аудит на родительскую папку, внутри на часть папок аудит так и не доезжает. Пробовал рекурсией пройтись по всем каталогам, но в таком случае права аудит выставляются на каждый каталог в отдельности.
Может есть идеи, как найти все подпапки с отключённым наследованием прав аудита и включить наследование на них?
Можно вывести папки (включая вложенные), для которых не включено наследование с помощью PowerShell:
DIR "C:\Folder" -directory -recurse | GET-ACL | where {$_.Access.IsInherited -eq $false}
Нужно что бы когда пользователь удаляет файл/папку приходило уведомления об этом на почту админа. С этим все ок. Через task shedule настроено на конкретный eventid запуск powershell скрипта, уведомления приходит но проблема в том что когда пользователь удаляет файл/папку приходит несколько писем одновременно (доступ на файл, удаления и др.). А мне нужно только удаления. Фильтировать с помощью 4660 не получилось так как разные действия (доступ,удаления и т.д.) приходят под одну категорию. Нащел решения переходить на ID 4656, там тоже получаем несколько уведомлений при одном удаление, но фильтровать чистое удаления можно с помощью категории (выбрав «Файловая система»), но никак не могу заставить работать фильтр под категорию (например: Where-Object {$_.Category -match 12800}).
Буду благодарен за идею.
$EventId = 4660
$A = Get-WinEvent -MaxEvents 1 -FilterHashTable @{Logname = "Security" ; ID = $EventId}
$Message = $A.Message
$EventID = $A.Id
$MachineName = $A.MachineName
$Source = $A.ProviderName
$Password = Get-Content "C:\fy.txt" | ConvertTo-SecureString
$EmailFrom = "[email protected]"
$EmailTo = "[email protected]"
$Subject ="Alert From $MachineName"
$Body = "EventID: $EventID`nSource: $Source`nMachineName: $MachineName `nMessage: $Message"
$SMTPServer = "smtp.office365.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("[email protected]", $Password);
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
Добрый день! Сделал все по инструкции , но возникла проблема. Когда удаляю папку , в логах записывается, но когда удаляю файл , в логах ничего не пишется
Посмотрите в настройках аудита папки, что выбран режим This folder, subfolder and files.
Подскажите, а если вместо имени папки в привычном виде отображается что-то типа:
Имя объекта: C:\Windows\WinSxS\FileMaps\$$_system32_21f9a9c4a2f8b514.cdf-ms
Как это исправить?
Чтобы в файл из журнала записывались события только по нужной папке, можно сделать так (выше приведены уже были скрипты в комментариях):
If ($File -match «ПУТЬ К НЕОБХОДИМОЙ ПАПКЕ АУДИТА»)
{
$strLog = $Computer + » » + $File + » » + $Time + » » + $User
$strLog | out-file $Outfile -append
}