PythonによるWindowsイベントログ(.evtxファイル)の解析と活用: 特定のイベントの抽出、フィルタリング
Windowsイベントログは、システム、セキュリティ、アプリケーションなどの動作状況を記録する重要な情報源です。これらのログは .evtx 形式で保存されており、セキュリティ監査、システムトラブルシューティング、アプリケーションの動作分析などに利用されます。本記事では、Pythonの pyevtx ライブラリを使用して、Windowsイベントログを効率的に解析し、特定の情報を抽出する方法を解説します。
- 1. pyevtxライブラリのインストール
- 2. イベントログファイルの読み込みと基本情報の取得
- 3. 特定のイベントIDの抽出
- 4. 高度なフィルタリングとデータ抽出
- 5. 抽出したイベントログの出力
- 6. 応用例
- 7. まとめ
1. pyevtxライブラリのインストール
pyevtx はWindowsイベントログファイル(.evtx)を解析するためのPythonライブラリです。以下のコマンドでインストールします。
pip install pyevtx
2. イベントログファイルの読み込みと基本情報の取得
まず、pyevtx を使用してイベントログファイルを読み込み、基本的な情報を取得する方法を説明します。
import pyevtx # イベントログファイルのパス (例: セキュリティログ) evtx_file = "C:\\Windows\\System32\\winevt\\Logs\\Security.evtx" # 一般的なイベントログファイルのパスの例 # - システムログ: "C:\\Windows\\System32\\winevt\\Logs\\System.evtx" # - アプリケーションログ: "C:\\Windows\\System32\\winevt\\Logs\\Application.evtx" try: with pyevtx.open(evtx_file) as log: print(f"ファイル: {evtx_file}") print(f"レコード数: {log.get_number_of_records()}") for record in log.records: print(f"レコード番号: {record.get_record_id()}") print(f"イベントID: {record.get_event_identifier()}") print(f"タイムスタンプ: {record.get_creation_time()}") # XML形式でデータを取得 print(f"XMLデータ:\n{record.get_xml_string()}") break # 最初のレコードのみ表示して終了 except FileNotFoundError: print(f"エラー: ファイル {evtx_file} が見つかりません。") except Exception as e: print(f"エラー: {e}")
指定されたパス(evtx_file)のイベントログファイルを開き、log オブジェクトとして扱います。データの概要を掴むために、開いたログファイルから全レコード数を取得し表示します。また、データの形式の概要を掴むためログファイル内の最初のレコードについて、レコード番号、イベントID、生成日時、XML形式のデータなどを取得して表示していきます。
pyevtxで取得できる主な情報
| メソッド | 説明 |
|---|---|
get_record_id() |
レコード番号 |
get_event_identifier() |
イベントID |
get_creation_time() |
イベントの生成日時 (UTC) |
get_event_source() |
イベントソース |
get_string_value(identifier) |
指定された識別子に対応する文字列値(XMLデータから抽出) |
get_xml_string() |
イベントレコード全体のXML表現 |
3. 特定のイベントIDの抽出
次に、特定のイベントIDを持つレコードのみを抽出する方法を示します。ここでは、ログオン成功を示すイベントID 4624 を例にフィルタリングを行います。
import pyevtx evtx_file = "C:\\Windows\\System32\\winevt\\Logs\\Security.evtx" desired_event_id = 4624 # ログオン成功 try: with pyevtx.open(evtx_file) as log: for record in log.records: if record.get_event_identifier() == desired_event_id: print(f"レコード番号: {record.get_record_id()}") print(f"イベントID: {record.get_event_identifier()}") print(f"タイムスタンプ: {record.get_creation_time()}") print(f"XMLデータ:\n{record.get_xml_string()}") except FileNotFoundError: print(f"エラー: ファイル {evtx_file} が見つかりません。") except Exception as e: print(f"エラー: {e}")
各レコードからイベントIDを取得し、desired_event_id 変数に指定された値(ここでは4624)と比較して、一致するレコードの情報を表示します。
4. 高度なフィルタリングとデータ抽出
より高度なフィルタリングとして、複数のイベントIDを指定したり、特定の期間のイベントを抽出したりする方法を紹介します。
4.1 複数のイベントIDによるフィルタリング
import pyevtx evtx_file = "C:\\Windows\\System32\\winevt\\Logs\\Security.evtx" desired_event_ids = [4624, 4625, 4634] # ログオン成功、ログオン失敗、ログオフ try: with pyevtx.open(evtx_file) as log: for record in log.records: if record.get_event_identifier() in desired_event_ids: print(f"レコード番号: {record.get_record_id()}") print(f"イベントID: {record.get_event_identifier()}") print(f"タイムスタンプ: {record.get_creation_time()}") except FileNotFoundError: print(f"エラー: ファイル {evtx_file} が見つかりません。") except Exception as e: print(f"エラー: {e}")
desired_event_ids というリストを作成し、抽出したレコードのIDを列挙します。ここでは、格納された複数のイベントID(4624, 4625, 4634)のいずれかに一致するレコードを抽出して表示します。
4.2 日付によるフィルタリング
import pyevtx import datetime evtx_file = "C:\\Windows\\System32\\winevt\\Logs\\Security.evtx" # 抽出したい期間の開始日時と終了日時 start_time = datetime.datetime(2023, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc) end_time = datetime.datetime(2024, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc) try: with pyevtx.open(evtx_file) as log: for record in log.records: record_time = record.get_creation_time() if start_time <= record_time <= end_time: print(f"レコード番号: {record.get_record_id()}") print(f"イベントID: {record.get_event_identifier()}") print(f"タイムスタンプ: {record_time}") except FileNotFoundError: print(f"エラー: ファイル {evtx_file} が見つかりません。") except Exception as e: print(f"エラー: {e}")
start_time と end_time で指定した期間内に生成されたイベントレコードを抽出します。record.get_creation_time()で取得したイベントの生成日時が指定期間内にあるかを確認します。
5. 抽出したイベントログの出力
抽出したイベントログの出力方法を解説します。pyevtx 自体には、抽出したレコードを新しい .evtx ファイルとして保存する機能は直接は提供されていません。.evtx は複雑なバイナリフォーマットであるため、Python だけで書き出すのは容易ではありません。抽出したイベントログの情報を CSV (Comma Separated Values) 形式で出力するのは、比較的簡単で、データの可搬性も高いため、おすすめです。
CSV 形式での出力
import pyevtx import csv import datetime evtx_file = "C:\\Windows\\System32\\winevt\\Logs\\Security.evtx" output_csv = "extracted_events.csv" desired_event_ids = [4624, 4625] # 抽出したい期間 start_time = datetime.datetime(2023, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc) end_time = datetime.datetime(2024, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc) try: with pyevtx.open(evtx_file) as log, open(output_csv, 'w', newline='', encoding='utf-8') as csvfile: csv_writer = csv.writer(csvfile) # CSVのヘッダー行 csv_writer.writerow(["RecordID", "EventID", "Timestamp", "EventSource", "XMLData"]) for record in log.records: if record.get_event_identifier() in desired_event_ids: record_time = record.get_creation_time() if start_time <= record_time <= end_time: record_id = record.get_record_id() event_id = record.get_event_identifier() timestamp = record_time.isoformat() event_source = record.get_event_source() xml_data = record.get_xml_string() # CSVに行を書き込む csv_writer.writerow([record_id, event_id, timestamp, event_source ,xml_data]) except FileNotFoundError: print(f"エラー: ファイル {evtx_file} が見つかりません。") except Exception as e: print(f"エラー: {e}") print(f"CSVファイル {output_csv} に出力しました。")
6. 応用例
pyevtx を利用したイベントログ解析は、以下のような様々な応用が可能です。
- セキュリティインシデント調査: 不正アクセス、マルウェア感染、情報漏洩などのインシデント発生時に、関連するイベントログを抽出して詳細な分析を行います。例えば、特定のユーザーアカウントに対する多数のログオン失敗イベントを検出し、ブルートフォース攻撃の可能性を調査できます。
- システムパフォーマンス監視: システムの起動時間、シャットダウン時間、アプリケーションのクラッシュなどの情報を収集し、システムの安定性やパフォーマンスの問題を特定します。
- コンプライアンス監査: 特定の操作 (ファイルアクセス、ユーザー権限変更など) の記録を収集し、組織のポリシーや規制要件への準拠状況を監査します。
7. まとめ
Pythonと pyevtx ライブラリを組み合わせることで、Windowsイベントログの解析が効率的に行えます。
セキュリティ監視、システム管理、コンプライアンス対応など幅広い分野で活用可能です。
本記事で紹介した基本的な使い方から、さらに高度なフィルタリングやデータ抽出、CSV出力などを組み合わせることで、目的に応じた柔軟なログ分析を実現できます。