多くの組織は、業務を遂行するためにMicrosoftのテクノロジーに依存しています。同時に、脅威行為者はWindowsなどのオペレーティングシステムを悪用することができます。幸いなことに、WindowsはOSのセキュリティイベントを記録し、このような行動を追跡するのに役立ちます。
Windowsによって生成されるセキュリティイベントは、インシデント対応プロセスにおいて重要なリソースとなります。MicrosoftのWindowsイベントビューアなどのツールを使用することで、キャプチャされたイベントを確認するためのアクセス権が提供されますが、混雑したログを手動でスクロールして異常を検出することは現実的ではありません。
この記事では、監査ポリシー、Windowsイベントログ、およびPowerShellを使用してセキュリティ侵害の可能性を追跡する方法について学びます。
前提条件
この記事は、PowerShellを使用してWindowsのセキュリティイベントを分析する方法を教える情報を伝えることを目的としています。デモンストレーションに参加する場合は、次のものが必要です:
- A Windows 10+ PC – This PC will be used to generate and track down potential security events in the event log. This tutorial will be using Windows PowerShell 5.1.
- Windows PC上での管理者権限
- A PowerShell code editor such PowerShell ISE or Visual Studio (VS) Code.
Windowsがセキュリティイベントを保存する場所
Windowsオペレーティングシステムでアクションが実行されると、Windowsはそのアクションを1つ以上のイベントログとして記録します。Windowsイベントログは、デフォルトでファイルシステムに%SystemRoot%\system32\winevt\logsディレクトリに保存されます。この場所は、対応するイベントログのEventLogレジストリサブキーを変更することで変更できます。
システム上の最も重要なイベントログ(Application、Security、およびSystem)の保存場所を確認したい場合は、以下のコードをPowerShellコンソールにコピーして貼り付けるか、スクリプトとして保存してください。
セキュリティログファイルの保存場所にアクセスするには、管理者としてコードを実行する必要があります。
次のスクリーンショットは、コードの予想される出力を示しており、Application、Security、およびSystemログファイルのログ名と保存場所を表示しています。

Audit Policies: Defining Events to Record
デフォルトでは、Windowsは侵害を検出または調査するために必要なすべてのセキュリティイベントを記録しません。Windowsが記録するイベントを制御するには、監査ポリシーを定義して適用する必要があります。監査ポリシーは、Windowsに渡される命令のセットであり、記録するイベントを指示します。
監査ポリシーを割り当て、操作するためのいくつかの異なる方法がありますが、グループポリシーなどがあります。 グループポリシーは、多くのマシンにわたる監査ポリシーを実装する必要がある場合に適しています。ただし、この記事では単一のデバイスに焦点を当てるため、auditpolツールを使用します。auditpolツールはWindowsにインストールされており、Windowsシステム上で監査ポリシーを見つけて設定することができます。
監査ポリシーの検索
たとえば、Windowsシステム上のすべての監査ポリシーのステータスを見つけるには、以下に示すように/get
パラメーターを使用します。ワイルドカードに続けて/category
パラメーターを使用すると、auditpolに特定のカテゴリやサブカテゴリに一致するものだけでなく、すべての監査ポリシーのステータスを見つけるように指示します。
以下のスクリーンショットは、コードの予想される出力の切り詰められたバージョンを示しており、アカウント管理監査ポリシーカテゴリ、サブカテゴリ、およびステータス(設定)が表示されています。

A Setting that is configured as No Auditing means that all events associated with that audit policy subcategory will not be logged.
監査ポリシーの設定
auditpolツールは、監査ポリシー設定を表示するだけでなく、auditpol /set
コマンドを使用して変更することもできます。このチュートリアルの後のセクションをデモンストレーションするために、管理者としてPowerShellコンソールを開き、以下のコマンドを実行します。このコマンドは、ログオンのサブカテゴリに属するすべてのイベント(成功および失敗)の記録を開始します。
ログオンのサブカテゴリを構成すると、システムは以下のイベントを記録します:
- 4624:アカウントが正常にログオンしました
- 4625:アカウントのログオンに失敗しました
- 4626:ユーザー/デバイスのクレーム情報
- 4648: ログオンが明示的な資格情報を使用して試行されました
- 4675: SID がフィルタリングされました
ベストプラクティスの監査ポリシー設定をサポートするために、Center for Internet Security (CIS) Benchmarks、Defense Information Systems Agency (DISA) Security Technical Implementation Guides (STIG)、およびMicrosoftが公開したガイダンスなど、多くのリソースが利用可能です。
分析のためのログオン失敗ログの生成
この記事はチュートリアルですので、進行に従ってください。Windowsをログオンイベントを監査するように設定した場合、後で分析するためのセキュリティイベントを生成しましょう。具体的には、35回の失敗したログオン試行を生成し、システムのセキュリティログに記録します。ブルートフォースのアクティビティを模倣します。
1. お気に入りのコードエディタを開きます。
2. 以下のコードをコピーしてコードエディタに貼り付けます。 このコードスニペットは、偽のユーザー名とパスワードを使用して Start-Process
コマンドレットを使用して PowerShell.exe プロセスを開こうとします。
3. PowerShell スクリプトを Invoke-BogusEvents.ps1 などの名前で保存してスクリプトを実行します。
実行すると、35 回の期待されるエラーが繰り返され、ユーザー名またはパスワードが間違っていますというメッセージが表示されます。

期待される出力を受け取っていない場合は、Secondary Logon サービスが実行中であることを確認してください。
PowerShell で Windows イベントにアクセスする
これで少なくとも 35 個の Windows セキュリティイベントがあることが確認できたので、PowerShell の Get-WinEvent
コマンドレットを使用してそれらを見つける方法について説明します。
おそらく PowerShell の
Get-EventLog
コマンドレットはおなじみかもしれませんが、これもプログラムでイベントログにアクセスするために使用されます。Get-EventLog
は非推奨の Win32 アプリケーションプログラミングインターフェイス(API)を使用しており、この投稿では説明しません。
管理者として PowerShell コンソールを開き、以下に示すように Get-WinEvent
コマンドレットを呼び出し、FilterHashtable
および MaxEvents
パラメーターを渡します。
以下のコマンドは、システムのセキュリティログ(LogName='Security'
)をクエリし、イベント ID 4625(ID=4625
)の最新の10件を返します(MaxEvents 10
)。
成功すると、以下のような出力が表示されます:

Get-WinEvent によるイベントのプロパティへのアクセス
前述のセクションでは、Get-WinEvent
を使用して Windows セキュリティイベントを高レベルで表示しましたが、Windows イベントにはさらに多くの情報が含まれています。各 Windows イベントには、より深い分析に使用できる貴重なプロパティがあります。
XML 形式の Windows イベント
Windows がイベントを記録すると、それは XML 形式で保存されます。それならば、なぜ Get-WinEvent
コマンドが通常の PowerShell オブジェクトを返したのでしょうか? Get-WinEvent
コマンドレットは、ネイティブの Windows API を読み込み、イベントを PowerShell オブジェクトに変換して機能を向上させています。
各 Windows イベントには、特定のXML スキーマまたは構造に従うさまざまな属性があります。
以下で、各イベントが特定の構造に従っていることがわかります:
name
– プロパティの名前inType
– 入力タイプの定義またはイベントが値を受け入れる方法outputType
– 出力タイプの定義またはイベントが記録される方法
PowerShellでイベントXMLテンプレートを見つける
前述のように、すべてのWindowsセキュリティイベントはXMLに格納されており、特定のスキーマがありますが、そのスキーマはどのように見えるのでしょうか?さて、それを見つけましょう。
以前のセクションの1つで、セキュリティイベントログでID 4625のいくつかのイベントを生成しました。このタイプのイベントにはそれにのみ適用される特定の属性があります。これらの属性とテンプレートの外観を見つけるには:
1. PowerShellコンソールを管理者として開きます(まだ開いていない場合)。
2. ListProvider
パラメーターを使用して、Windowsがセキュリティイベントログにイベントを記録するために使用するプロバイダーを指定し、Events
プロパティのみを返すように、再度Get-WinEvent
を実行します。
Events
プロパティには、リストプロバイダーが記録したすべてのイベントが含まれており、それぞれのイベントのXMLテンプレートが公開されています。

3. 今、すべてのイベントタイプのテンプレートを見つけるコードを持っているので、それをID 4625に関連付けられたイベントのみを返すように絞り込みます。
4. イベントID 4625のログオンイベントタイプのみを返すようになったら、以下のようにTemplate
プロパティのみを表示します。
次のスクリーンショットは、コードの出力の切り詰めバージョンを示し、イベントのプロパティ名、入力タイプ、および出力タイプを特定しています。イベントID 4625に関連するイベントプロパティには、さまざまな入力および出力の定義が含まれていることがわかります。
以下のスクリーンショットは、イベントID 4625のSubjectUserSid
プロパティを強調しています。この特定のイベントでは、入力タイプ(inType
)としてwin:SID
を受け入れ、出力(outType
)をstring
としてレンダリングします。これは、セキュリティログ内での保存方法です。

PowerShellがXMLをオブジェクトにどのように変換するか
WindowsがイベントをXMLで保存する方法とPowerShellでそのテンプレートを表示する方法を見てきましたが、次にPowerShellがそのXMLをオブジェクトにどのように変換するかを見てみましょう。
1. 再びGet-WinEvent
コマンドを実行して、イベントID 4625を返します。これまでのところ、これは新しいことではありません。PowerShellが表示するプロパティは、TimeCreated
、Id
、LevelDisplayName
、Message
のみであることに注意してください。

Get-WinEvent
コマンドレットは、デフォルトではイベントのXMLデータソースからすべての属性をPowerShellオブジェクトとして返しません。
2. 上記のコマンドの出力をSelect-Object
コマンドレットにパイプし、Property
パラメーターを指定して値を渡すことで、すべてのプロパティを表示します。
以下のことに注意してください。PowerShellは多くの異なるプロパティを非表示にしていました。具体的には、Properties
という名前のプロパティです。Properties
プロパティには、XMLテンプレートで以前に見た各イベント属性の値が含まれています。

3. Get-WinEvent
コマンドの出力を制限して、Properties
プロパティを表示します。このプロパティには、すべてのイベントプロパティが格納されています。ただし、PowerShellオブジェクトのプロパティではありません。このプロパティは配列に格納されます。
以下のスクリーンショットの左側には、上記のコマンドの出力があります。配列には、スクリーンショットの右側のXMLテンプレートの各XML属性の値が含まれています。
スクリーンショットに表示されているコードの出力によれば、AtaBlogUser
(TargetUserName
)ユーザーのシステムDesktop-XXXXX
(WorkstationName
)からの認証失敗が発生し、IPアドレス::1
(IpAddress
)を使用しています。

おそらくTargetUserName
イベントプロパティの値だけを返すことを希望しているかもしれません。すでにすべてのイベントプロパティを$eventProperties
という変数に保存しているので、TargetUserName
の値を保持している5番目のインデックスを参照します。
個々のイベントプロパティオブジェクトのvalue
プロパティを参照して、値(AtaBlogUser
)だけを返す必要があります。 $eventProperties[5].value

このセクションで説明されている方法は、このポストの後続セクションで、以前にシミュレートしたブルートフォースの試みを追跡するために使用されます。
ブルートフォース攻撃の検出
あなたは今、PowerShellのスキルを使用して、この投稿で再現したブルートフォース攻撃を追跡する準備が整いました!テストのために、特定の時間枠に基づいてブルートフォース攻撃を追跡する様子をシミュレートしましょう。
例えば、組織が重要なWindows Serverに管理アカウントを使用しようとする試みがあるとの通知を受けました。この活動は昨日から始まりました。過去24時間に発生したイベントID4625:アカウントのログオンに失敗しましたの数を見つけ、各イベントのログオンタイプを判別する必要があります。
1. 過去24時間のWindowsセキュリティログ(LogName="Security"
)でイベントID 4625(ID=4625
)を持つすべてのイベントを見つけます(StartTime=((Get-Date).AddDays(-1).Date
)、現在の時刻で終了します(Get-Date
)。
2. 今、変数に格納されたすべてのイベントをカウントして、予想よりも失敗したログオンイベントが多いかどうかを判断します。
これで、過去24時間のセキュリティイベントログでイベントID 4625が見つかった回数を示す数値が表示されるはずです。
3. ブルートフォース攻撃が発生したことが判明したので、これらのWindowsセキュリティイベントに関する詳細情報を追跡します。それには、興味のある各イベントからの属性のみを返します。
以前に述べたように、特定のイベントの各値は、特定のインデックスで配列に格納されます。このデモ用の興味深いイベントのプロパティは以下の通りです。
- TargetUserName インデックス:
[5]
- LogonType インデックス:
[10]
- WorkstationName インデックス:
[13]
- IpAddress インデックス:
[19]
以下のコードサンプルでは、$events変数内の各オブジェクトを読み取り、興味深いプロパティのみを収集し、それらを1行に連結します。
次のスクリーンショットは、コードの予想される出力の要約バージョンを示しており、TargetUserName、LogonType、WorkstationName、およびIpAddressのカンマ区切りのリストを詳細に説明しています。

4. 以前のXMLテンプレートからわかるように、イベントID 4625のテンプレートにはLogonType
属性があります。この属性は、アカウントが認証を試みた方法を示します。さらなる調査の結果、LogonType
が時折異なることに気付きました。

LogonType
attributeLogonType
の値は2から11までの数値ですが、それは何を意味していますか?いくつかの調査を行い、各値が何を意味するかを発見しました。
2 – インタラクティブ – このコンピュータにログオンしているユーザー。
3 – ネットワーク – ネットワークからこのコンピュータにログオンしているユーザーまたはコンピューター。
4 – バッチ – バッチログオンタイプは、プロセスがユーザーの直接的な介入なしにユーザーを代表して実行されるバッチサーバーで使用されます。
5 – サービス – サービスがサービス制御マネージャーによって開始されました。
7 – ロック解除 – このワークステーションがロック解除されました。
8 – NetworkCleartext – ユーザーがネットワークからこのコンピュータにログオンしました。ユーザーのパスワードは、ハッシュ化されていない形式で認証パッケージに渡されました。組み込みの認証パッケージはすべて、パスワードをハッシュ化してからネットワークを横断して送信します。資格情報は平文(クリアテキストとも呼ばれる)でネットワークを横断しません。
9 – NewCredentials – 呼び出し元が現在のトークンをクローン化し、アウトバウンド接続のための新しい資格情報を指定しました。新しいログオンセッションは同じローカルIDを持ちますが、他のネットワーク接続には異なる資格情報を使用します。
10 – RemoteInteractive – 呼び出し元が現在のトークンをクローン化し、アウトバウンド接続のための新しい資格情報を指定しました。新しいログオンセッションは同じローカルIDを持ちますが、他のネットワーク接続には異なる資格情報を使用します。
11 – CachedInteractive – このコンピュータにネットワーク資格情報を使用してログオンしたユーザー。ドメインコントローラーは資格情報を確認するために連絡されませんでした。
今、各LogonType
の理解が深まったので、出力で数値ではなく、より記述的な文字列を見たいと思います。PowerShellで”maps”を作成するには、ハッシュテーブルを使用します。
5. Get-WinEvent
とLogonType
ハッシュテーブルをForEach-Object
と組み合わせて、以下に示すようにユーザーフレンドリーなLogonType
の値を持つプロパティのみを返すスクリプトを作成します。Format-Table
コマンドレットは、PowerShellの応答をテーブルとしてフォーマットすることで、ユーザーフレンドリーな出力に追加します。
この時点で、PSCustomObjectタイプのオブジェクトを返すスクリプトがあり、さまざまな種類の分析を実行できます!このチュートリアルの分析を最終的に終了するには、TargetUserName
による認証失敗の試行を優先します。 TargetUserName
プロパティによって失敗を優先させるには、上記のコードをGroup-Object
コマンドレットと組み合わせます。 Sort-Object
およびそのDescending
スイッチを使用して、最も問題のあるユーザーを特定します。
素晴らしい仕事です!あなたはPowerShellを使用して、このポストで前もってシミュレートした総当たり攻撃を検出しました。出力によれば、AtaBlogUserは過去24時間で30回認証に失敗しました!

次の手順
このチュートリアルでは、Windowsがイベントをログに記録する方法、特定のイベントタイプのイベントログ記録を有効にする方法、およびこれらのイベントをクエリするPowerShellツールを構築する方法を学びました。
今持っているPowerShellスクリプトを使って、どのように改善できますか?今日学んだコードをどのように活かして、より優れたツールを構築しますか?
Source:
https://adamtheautomator.com/windows-security-events/