3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PythonでWindows形式のイベントログであるevtxデータをCSVに変換してみました - Verup編

Posted at

概要

NetAppファイルサーバのイベントログであるevtxデータを サクッと確認するために CSV形式 へ変換保存するプログラムです。この記事 に 「Read/Write Offset」と「Read/Write Count」を参照できるようにバージョンアップしました。

実行環境

macOS Ventura 13.0
python 3.8.12

事前準備

事前に以下のモジュールをインポートしておきます。

$ pip install python-evtx

実行プログラム

extviewer3.py
import argparse
import time
from Evtx.Evtx import Evtx
import pandas as pd


# CSVファイルへの変換
def evtx_to_csv(evtx_file, mode):
    # イベントスキーマーの定義
    SCHEMA = 'http://schemas.netapp.com/events/event'

    # カラムの定義
    EventID = []
    EventName = []
    TimeCreated = []
    Computer = []
    SubjectIP = []
    DomainName = []
    UserName = []
    ObjectType = []
    ObjectName = []
    RWOffset = []
    RWCount = []
    
    # イベントファイルのオープン
    with Evtx(evtx_file) as log:

        # イベントレコードの取得
        for record in log.records():
            elm = record.lxml()

            # # 個々のrecord構造の確認(最初に確認しましょう)
            # print(record.xml())
            
            # Logon/off のイベントは無視する
            eventid_str = elm.xpath("//event:EventID", namespaces={"event":SCHEMA})[0].text
            if eventid_str == '4624' or eventid_str == '4625' or eventid_str == '4634':
                continue

            # イベントデータの取得
            EventID.append(elm.xpath("//event:EventID", namespaces={"event":SCHEMA})[0].text)
            EventName.append(elm.xpath("//event:EventName", namespaces={"event":SCHEMA})[0].text)
            TimeCreated.append(elm.xpath("//event:TimeCreated", namespaces={"event":SCHEMA})[0].get("SystemTime"))
            Computer.append(elm.xpath("//event:Computer", namespaces={"event":SCHEMA})[0].text)
            SubjectIP.append(elm.xpath("//event:Data", namespaces={"event":SCHEMA})[0].text)
            DomainName.append(elm.xpath("//event:Data", namespaces={"event":SCHEMA})[5].text)
            UserName.append(elm.xpath("//event:Data", namespaces={"event":SCHEMA})[6].text)
            ObjectType.append(elm.xpath("//event:Data", namespaces={"event":SCHEMA})[8].text)
            ObjectName.append(elm.xpath("//event:Data", namespaces={"event":SCHEMA})[10].text)

            eventname_str = elm.xpath("//event:EventName", namespaces={"event":SCHEMA})[0].text

            if eventname_str == 'Read Object' or eventname_str == 'Write Object' :
                RWOffset.append(elm.xpath("//event:Data", namespaces={"event":SCHEMA})[11].text)
                RWCount.append(elm.xpath("//event:Data", namespaces={"event":SCHEMA})[12].text)
            else :
                RWOffset.append('')
                RWCount.append('')


        # データフレームを作成
        df = pd.DataFrame({
            'EventID' : EventID,
            'EventName' : EventName,
            'TimeCreated' : TimeCreated,
            'Computer' : Computer,
            'SubjectIP' : SubjectIP,
            'DomainName' : DomainName,
            'UserName' : UserName,
            'ObjectType' : ObjectType,
            'ObjectName' : ObjectName,
            'RWOffset' : RWOffset,
            'RWCount' : RWCount
        })

        if mode == 'csv' :
            # CSVファイルへの書き込み
            output_file = evtx_file + '.csv'
            df.to_csv(output_file, header=True, index=True)
        else :
            # 画面への表示
            print(df.to_markdown())


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='extvをjson形式にするプログラム')
    parser.add_argument('-i', '--input', type=str, default=INPUT_FILE, help='対象となる extvファイル')
    parser.add_argument('-m', '--mode', type=str, default='view', help='View:画面表示,  csv:CSVファイル保存')
    args = parser.parse_args()

    # 経過時間の計測開始
    start = time.time()
    evtx_to_csv(args.input, args.mode)
    generate_time = time.time() - start

    print("\n処理時間:{0}".format(generate_time) + " [sec]\n")

プログラムの実行

.evtxデータを画面に表示してみます。

$ python extviewer3.py -i 20230511_13.evtx
|    |   EventID | EventName             | TimeCreated                | Computer           | SubjectIP   | DomainName   | UserName      | ObjectType                          | ObjectName                                                            | RWOffset   | RWCount   |
    : 
    :
| 10 |      4663 | Read Object           | 2023-05-09 13:07:44.851498 | FAS2750A/kg_domain | 10.2.1.6    | NETAPP       | administrator | File                                | (zidoma);/00_Develop/HeaderEncryption/testdir/rs-audit.db.encryptedrn | 0          | 4096      |
| 11 |      4663 | Write Object          | 2023-05-09 13:07:44.935497 | FAS2750A/kg_domain | 10.2.1.6    | NETAPP       | administrator | File                                | (zidoma);/00_Develop/HeaderEncryption/testdir/rs-audit.db.encryptedrn | 0          | 4096      |
    : 
    :
処理時間:0.18537306785583496 [sec]

.evtxデータをCSVに変換保存すしてみます。

$ python extviewer3.py -i 20230511_13.evtx -m csv

処理時間:0.13499021530151367 [sec]

作成されたCSVファイルを確認します。

$ vim 20230511_13.evtx.csv
-------------------------------
,EventID,EventName,TimeCreated,Computer,SubjectIP,DomainName,UserName,ObjectType,ObjectName,RWOffset,RWCount
    : 
    :
10,4663,Read Object,2023-05-09 13:07:44.851498,FAS2750A/kg_domain,10.2.1.6,NETAPP,administrator,File,(zidoma);/00_Develop/HeaderEncryption/testdir/rs-audit.db.encryptedrn,0,4096
11,4663,Write Object,2023-05-09 13:07:44.935497,FAS2750A/kg_domain,10.2.1.6,NETAPP,administrator,File,(zidoma);/00_Develop/HeaderEncryption/testdir/rs-audit.db.encryptedrn,0,4096
    : 
    :

まとめ

NetAppファイルサーバのイベントログの必要なデータとして「Read/Write Offset」と「Read/Write Count」を取得できるようにしました。これで、ファイルのどの場所から何バイト Read/Write したのかを把握できるようになりました。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?