Powershellを使用してファイルの削除とアクセスを監査し、イベントをログファイルに書き込む



多くの人があなたに来て問題に直面し、「共有リソースにファイルがありません。消えました。誰かがそれを削除したようです。誰がそれをやったか確認できますか?」時間がないので、最悪の場合はログでこのファイルの言及を見つけてください。 また、ファイルサーバーでファイル監査がオンになっている場合、そこにあるログは、控えめに言って「非常に大きい」ため、そこにあるものを見つけるのは非現実的です。

ここに私は、別のそのような質問(OK、1日に数回バックアップが行われます)と私の答え:「誰がこれをやったのかわかりませんが、あなたのためにファイルを復元します」の後に、私はこれが基本的に私に合わないと判断しました...



始めましょう。



まず、ポリシーをグループ化するためにファイルとフォルダーへのアクセスを監査する機能を有効にします。

ローカルセキュリティポリシー->セキュリティポリシーの詳細設定->オブジェクトアクセス

成功と失敗の場合は、「ファイルシステムの監査」をオンにします。

その後、必要なフォルダーの監査を構成する必要があります。

ファイルサーバー上の共有フォルダーのプロパティに移動し、[セキュリティ]タブに移動して、[詳細設定]をクリックし、[監査]タブに移動して、[変更]および[追加]をクリックします。 監査対象のユーザーを選択します。 「すべて」を選択することをお勧めします。そうしないと意味がありません。 アプリケーションレベル「このフォルダーとそのサブフォルダーとファイル用」。

監査を実施するアクションを選択します。 「ファイルの作成/データの回復」成功/失敗、「フォルダーの作成/データの回復」成功/失敗、サブフォルダーとファイルを削除して、削除も成功/失敗時に選択しました。

OKをクリックします。 すべてのファイルに監査ポリシーを適用することを楽しみにしています。 その後、多くのファイルおよびフォルダーアクセスイベントがセキュリティイベントログに表示されます。 イベントの数は、共有リソースを使用している作業ユーザーの数に直接比例します。もちろん、使用のアクティビティからです。



そのため、ログには既にデータがあり、そこからデータを引き出して、不必要な「水」なしに関心のあるデータのみを引き出します。 その後、データをタブで1行ずつ慎重にテキストファイルに挿入し、たとえば将来、スプレッドシートエディターで開くようにします。



# ,         ,     .    - 1 . ..      . $time = (get-date) - (new-timespan -min 60) #$BodyL -     - $BodyL = "" #$Body - ,        ID. $Body = Get-WinEvent -FilterHashtable @{LogName="Security";ID=4663;StartTime=$Time}|where{ ([xml]$_.ToXml()).Event.EventData.Data |where {$_.name -eq "ObjectName"}|where {($_.'#text') -notmatch ".*tmp"} |where {($_.'#text') -notmatch ".*~lock*"}|where {($_.'#text') -notmatch ".*~$*"}} |select TimeCreated, @{n="_";e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq "ObjectName"} | %{$_.'#text'}}},@{n="_";e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq "SubjectUserName"} | %{$_.'#text'}}} |sort TimeCreated #         (   , : Secret) foreach ($bod in $body){ if ($Body -match ".*Secret*"){ # ,     $BodyL    : ,   ,  .  #       ,         .   #  ,   $BodyL            . $BodyL=$BodyL+$Bod.TimeCreated+"`t"+$Bod._+"`t"+$Bod._+"`n" } } #..      (      ),     # .   -  .      AccessFile  : , , . $Day = $time.day $Month = $Time.Month $Year = $Time.Year $name = "AccessFile-"+$Day+"-"+$Month+"-"+$Year+".txt" $Outfile = "\serverServerLogFilesAccessFileLog"+$name #          -. $BodyL | out-file $Outfile -append
      
      







そして今、非常に興味深いスクリプトです。





スクリプトは、削除されたファイルに関するログを書き込みます。



 # $Time         . $time = (get-date) - (new-timespan -min 60) #$Events -         ID=4660.     . #!!!!  !!!      2 ,  ID=4660  ID=4663. $Events = Get-WinEvent -FilterHashtable @{LogName="Security";ID=4660;StartTime=$time} | Select TimeCreated,@{n="";e={([xml]$_.ToXml()).Event.System.EventRecordID}} |sort  #   .   ,   . $BodyL = "" $TimeSpan = new-TimeSpan -sec 1 foreach($event in $events){ $PrevEvent = $Event. $PrevEvent = $PrevEvent - 1 $TimeEvent = $Event.TimeCreated $TimeEventEnd = $TimeEvent+$TimeSpan $TimeEventStart = $TimeEvent- (new-timespan -sec 1) $Body = Get-WinEvent -FilterHashtable @{LogName="Security";ID=4663;StartTime=$TimeEventStart;EndTime=$TimeEventEnd} |where {([xml]$_.ToXml()).Event.System.EventRecordID -match "$PrevEvent"}|where{ ([xml]$_.ToXml()).Event.EventData.Data |where {$_.name -eq "ObjectName"}|where {($_.'#text') -notmatch ".*tmp"} |where {($_.'#text') -notmatch ".*~lock*"}|where {($_.'#text') -notmatch ".*~$*"}} |select TimeCreated, @{n="_";e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq "ObjectName"} | %{$_.'#text'}}},@{n="_";e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq "SubjectUserName"} | %{$_.'#text'}}} if ($Body -match ".*Secret*"){ $BodyL=$BodyL+$Body.TimeCreated+"`t"+$Body._+"`t"+$Body._+"`n" } } $Month = $Time.Month $Year = $Time.Year $name = "DeletedFiles-"+$Month+"-"+$Year+".txt" $Outfile = "\serverServerLogFilesDeletedFilesLog"+$name $BodyL | out-file $Outfile -append
      
      







判明したように、ファイルを削除して記述子を削除すると、ID = 4663の下で同じイベントがログに作成されます。 同時に、メッセージ本文には、「アクセス操作」の異なる値が含まれる場合があります。 データの記録(またはファイルの追加)、DELETEなど。

もちろん、DELETE操作に興味があります。 しかし、それだけではありません。 最も興味深いのは、ファイルの通常の名前変更中に、ID 4663の2つのイベントが作成されることです。1つ目はアクセス操作:DELETE、2つ目は操作:データの書き込み(またはファイルの追加)です。 したがって、単に4663を選択すると、多くの誤った情報が得られます。ファイルがどこに移動するか、削除されるだけでなく、単に名前が変更されるだけです。

ただし、ファイルが明示的に削除されると、ID 4660の別のイベントが作成されることに気付きました。このイベントでは、メッセージ本文を慎重に調べると、ユーザー名とより多くのサービス情報が含まれていますが、ファイル名はありません。 ただし、記述子コードがあります。



ただし、このイベントの前のイベントはイベントID 4663でした。ファイル名、ユーザー名と時刻、操作はすべて同じDELETEです。 そして最も重要なことは、上記のイベントのハンドル番号に対応するハンドル番号があります(4660、覚えていますか?ファイルが明示的に削除されたときに作成されます)。 したがって、どのファイルが削除されたかを正確に知るには、ID 4660のすべてのイベントと、各イベントの前にあるイベント(コード4663のイベント)を見つける必要があります。これには、目的の記述子の数が含まれます。



これらの2つのイベントは、ファイルの削除時に同時に生成されますが、最初に4663、次に4660の順に記録されます。この場合、シリアル番号は1つ異なります。 4660のシリアル番号は1よりも大きい1663です。

このプロパティによって、目的のイベントが検索されます。





つまり ID 4660のすべてのイベントが取得され、作成時間とシリアル番号の2つのプロパティが取得されます。

次に、ループで、各イベント4660が一度に1つずつ取得され、そのプロパティ、時刻、およびシリアル番号が選択されます。

次に、$ PrevEvent変数に、必要なイベントの番号を入力します。これには、削除されたファイルに関する必要な情報が含まれています。 また、特定のシリアル番号を使用してこのイベントを検索する必要がある時間枠も決定されます($ PrevEventで入力したものと同じです)。 なぜなら イベントがほぼ同時に生成されると、検索は2秒に短縮されます:+-1秒。

(はい、それは+1秒と-1秒です。正確に言えば、実験的に検出されたとは言えません。1秒追加しないと、これらの2つのイベントが前後に生成される可能性があるため、一部が見つかりません。後で、その逆)。

1時間以内にすべてのイベントをシリアル番号だけで検索するのは非常に時間がかかるので、すぐに予約します。 シリアル番号はイベントの本文にあり、それを判断するには、各イベントを解析する必要があります-これは非常に長い時間です。 そのため、2秒という短い時間が必要です(4660イベントから-1秒、覚えていますか?)。

この期間に、必要なシーケンス番号を持つイベントが検索されます。

見つかった後、フィルターは機能します。

 |where{ ([xml]$_.ToXml()).Event.EventData.Data |where {$_.name -eq "ObjectName"}|where {($_.'#text') -notmatch ".*tmp"} |where {($_.'#text') -notmatch ".*~lock*"}|where {($_.'#text') -notmatch ".*~$*"}}
      
      





つまり 削除された一時ファイル(。* tmp)、MS Officeドキュメントロックファイル(。*ロック)、およびMS Office一時ファイル(。*〜$ *)に関する情報は記録しません。

同様に、このイベントから必要なフィールドを取得し、それらを$ BodyL変数に書き込みます。

すべてのイベントを見つけたら、ログのテキストファイルに$ BodyLを書き込みます。



削除されたファイルのログには、スキームを使用します。1つの月に1つのファイル、月番号と年を含む名前を付けます)。 なぜなら 削除されたファイルは、アクセスされたファイルよりも何倍も小さくなります。



その結果、真実を求めてログを無限に「掘る」代わりに、任意のスプレッドシートエディタでログファイルを開き、ユーザーまたはファイルごとに必要なデータを表示できます。



推奨事項



必要なイベントを探す時間を自分で決定する必要があります。 期間が長いほど、検索時間が長くなります。 それはすべてサーバーのパフォーマンスに依存します。 弱い場合-その後10分で開始します。 どれだけ速く動作するかをご覧ください。 10分より長い場合は、再び大きくするか、突然助けになるか、またはその逆で期間を5分に短縮します。



期間を決定した後。 このスクリプトをタスクスケジューラに配置し、このスクリプトを5.10.60分ごとに実行する必要があることを示します(スクリプトで指定した期間によって異なります)。 60分ごとに表示されます。 $ time =(get-date)-(new-timespan -min 60)



PS



これらのスクリプトはどちらも、100 GBのネットワークリソースで機能します。ネットワークリソースでは、毎日平均50人のユーザーがアクティブに作業しています。

1時間あたりの削除されたファイルの検索時間は10〜15分です。

アクセス可能なすべてのファイルの検索時間は3〜10分です。 サーバーの負荷に応じて。



All Articles