セキュリティ対策の第一歩は、自社システムの挙動を把握することです。そのために重要なのがログの収集と分析です。
PowerShellは、Windows環境で効率的にログを収集・分析できる強力なツールとして注目されています。
本記事では、PowerShellを活用したセキュリティ監査の基本を解説します。実際に手を動かしながら学べるよう、サンプルスクリプトや演習問題もご用意しました。
セキュリティログの重要性とPowerShellの利点
セキュリティログは、以下の目的で利用されます:
- 不審なアクセスや挙動の検知
- インシデント発生後の調査
- 法的およびコンプライアンス要件の遵守
Windows環境では、イベントログに多くの情報が記録されています。これらのログを効率的に取得し、分析するためにPowerShellを活用すると、以下のような利点があります:
- 柔軟性の高いクエリ:特定のイベントIDや期間を指定して抽出可能
- 自動化:定期的な監査プロセスの自動化
- 他ツールとの連携:結果をCSVやJSON形式で保存、他の解析ツールに渡すことが可能
PowerShellでのログ収集方法
イベントログの基本情報を確認する
まず、システムに記録されているイベントログの情報を確認してみましょう。
# イベントログのリストを表示
Get-EventLog -List
このコマンドにより、利用可能なログの種類(System、Application、Securityなど)が表示されます。
特定のイベントログを取得する
次に、セキュリティログから直近の100件を取得してみます。
# セキュリティログの最新100件を取得
Get-EventLog -LogName Security -Newest 100
特定のイベントIDで絞り込む
例えば、不正ログインの兆候を示すイベントID(4625: ログオン失敗)を調査する場合、以下のようにコマンドを実行します。
# ログオン失敗のログを取得
Get-EventLog -LogName Security | Where-Object {$_.EventID -eq 4625}
ログの保存とフォーマット変換
収集したログを他のツールで分析するためには、適切なフォーマットで保存することが重要です。
CSV形式で保存
# ログオン失敗のログをCSV形式で保存
Get-EventLog -LogName Security | Where-Object {$_.EventID -eq 4625} | Export-Csv -Path "C:\Logs\SecurityLogonFailures.csv" -NoTypeInformation
JSON形式で保存
JSON形式は、データの柔軟な構造が必要な場合に適しています。
# ログオン失敗のログをJSON形式で保存
Get-EventLog -LogName Security | Where-Object {$_.EventID -eq 4625} | ConvertTo-Json | Out-File -FilePath "C:\Logs\SecurityLogonFailures.json"
ログ分析の実践
収集したログを分析して、不審なパターンを発見します。
IPアドレスの頻度分析
以下のスクリプトでは、ログオン失敗(4625)の記録からIPアドレスを抽出し、頻度をカウントします。
# ログオン失敗のイベントからIPアドレスをカウント
$logFailures = Get-EventLog -LogName Security | Where-Object {$_.EventID -eq 4625}
$ipCounts = $logFailures | ForEach-Object {
if ($_ -match "Source Network Address: (\d+\.\d+\.\d+\.\d+)") {
$matches[1]
}
} | Group-Object | Sort-Object Count -Descending
# 結果を表示
$ipCounts | Format-Table Name, Count
定期的な監査スクリプトの自動化
PowerShellスクリプトをタスクスケジューラに登録することで、定期的なログ監査を自動化できます。
自動化スクリプト例
以下のスクリプトを保存し、タスクスケジューラに登録します。
# ログオン失敗のログをCSVに保存するスクリプト
$logPath = "C:\Logs\SecurityLogonFailures_$(Get-Date -Format yyyyMMdd).csv"
Get-EventLog -LogName Security | Where-Object {$_.EventID -eq 4625} | Export-Csv -Path $logPath -NoTypeInformation
Get-WinEventの基本構文
PowerShellでログを収集する際、Get-EventLogは便利なコマンドレットですが、モダンなログ収集にはGet-WinEventの方が柔軟性とパフォーマンスの面で優れています。Get-WinEventを使用することで、カスタマイズ性が高く、大量のログを効率的に処理することが可能です。
Get-WinEventは、より多機能で新しいWindowsイベントログを扱うためのコマンドレットです。以下は基本的な構文です。
Get-WinEvent -LogName <ログ名> -MaxEvents <取得するイベント数>
例えば、セキュリティログから最新の100件を取得する場合:
Get-WinEvent -LogName Security -MaxEvents 100
Get-EventLogとの違いは、Get-WinEventが「拡張イベントログ形式」をサポートしている点です。これにより、より多くのデータにアクセスできます。
特定条件でのログフィルタリング
Get-WinEventでは、-FilterHashTableパラメータを使用して、イベントIDや期間で詳細に絞り込みを行えます。
イベントIDで絞り込む
例えば、ログオン失敗(イベントID 4625)を取得する場合:
Get-WinEvent -FilterHashTable @{LogName='Security'; Id=4625}
複数の条件を指定する
特定の期間内で複数のイベントIDを取得するには、以下のようにします:
Get-WinEvent -FilterHashTable @{
LogName='Security';
Id=@(4624, 4625);
StartTime=(Get-Date).AddDays(-7);
EndTime=(Get-Date)
}
このスクリプトは、過去7日間に記録されたログオン成功(4624)および失敗(4625)のイベントを収集します。
イベントXMLによる高度な検索
Get-WinEventは、カスタムクエリとしてXMLを使用することで、さらに高度な条件でログを抽出できます。以下は例です。
特定ユーザーによるイベント抽出
ユーザー名が「Admin」のイベントを取得するXMLクエリ:
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
*[System[EventID=4624]] and
*[EventData[Data[@Name='TargetUserName']='Admin']]
</Select>
</Query>
</QueryList>
PowerShellでこのクエリを使用するには、以下のスクリプトを実行します:
$query = @"
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
*[System[EventID=4624]] and
*[EventData[Data[@Name='TargetUserName']='Admin']]
</Select>
</Query>
</QueryList>
"@
Get-WinEvent -FilterXml $query
ログの出力形式と保存
CSV形式で保存
Get-WinEventの出力をCSV形式で保存します。
Get-WinEvent -FilterHashTable @{LogName='Security'; Id=4625} | Export-Csv -Path "C:\Logs\WinEventLogFailures.csv" -NoTypeInformation
JSON形式で保存
JSON形式は、柔軟なデータ解析に役立ちます。
Get-WinEvent -FilterHashTable @{LogName='Security'; Id=4625} | ConvertTo-Json | Out-File -FilePath "C:\Logs\WinEventLogFailures.json"
実践例:IPアドレスの抽出と頻度分析
スクリプト例
以下のスクリプトでは、ログオン失敗(4625)のイベントからIPアドレスを抽出し、その出現回数をカウントします。
# ログオン失敗イベントからIPアドレスを抽出
$events = Get-WinEvent -FilterHashTable @{LogName='Security'; Id=4625}
$ipCounts = $events | ForEach-Object {
$_.Message -match "Source Network Address:\s+(\d+\.\d+\.\d+\.\d+)" | Out-Null
$matches[1]
} | Group-Object | Sort-Object Count -Descending
# 結果を表示
$ipCounts | Format-Table Name, Count
演習問題と解答例
演習問題
- 基本情報の取得
イベントログに記録されている「Application」ログの最新50件を取得し、出力してください。 - 特定イベントの抽出
イベントIDが「4624」(正常なログオン)で、ログオンタイプが「10」(リモートログオン)のログを抽出するスクリプトを作成してください。 - データ保存と分析
「System」ログの中から、イベントID「7036」(サービスの状態変更)のログを抽出し、その結果をJSON形式で保存してください。
解答例
1. 基本情報の取得
Get-EventLog -LogName Application -Newest 50
2. 特定イベントの抽出
Get-EventLog -LogName Security | Where-Object {
$_.EventID -eq 4624 -and $_.Message -match "Logon Type:\s+10"
}
3. データ保存と分析
Get-EventLog -LogName System | Where-Object {$_.EventID -eq 7036} | ConvertTo-Json | Out-File -FilePath "C:\Logs\ServiceStateChanges.json"
まとめ
PowerShellを活用することで、セキュリティログの収集・分析を効率化できることが分かりました。
本記事で紹介した内容をベースに、自社システムの監査プロセスを構築してみてください。
今後は、さらに高度な分析やアラート設定を組み込むことで、リアルタイム監視も可能になります。