概略
Eric Zimmerman(エリック・ジマーマン)氏が開発している CSVやTSVファイルのビューアーである Timeline Explorer には、複雑な構文が使えるフィルター機能があります。これによってフォレンジック調査で必要な事柄を抽出したりしていますが、肝心のフィルター構文については詳しい記載がありません。
どのような構文が使えるのか調べてみることにしました。
本稿に記載した内容は、個人的な見解を示したものであり、筆者の所属する企業・団体の公式見解ではありません。
フィルター構文の概要
Timeline Explorerは、大きく次の 3つのタイプのフィルターを備えています。
- Excelのようにカラム毎に指定するフィルター
- ファイル全体から文字列をもとに抽出するフィルター
- フィルターエディターを使って構文を直接編集するフィルター
このうち 3つ目のフィルターエディターについての具体的な構文例はEZTOOLのマニュアル からも見つけられませんでした。
Timeline Explorerは C#で開発されています。.NETでデータテーブルへのフィルター抽出を行う DataView.RowFilterプロパティの記法と、Timeline Explorerのフィルター構文は似ており、おそらく、この機能をそのまま利用しているのではないかと考えています。
であれば DataView.RowFilterの文法を確認することで Timeline Exploerer のフィルター構文も明確にできるはずです。
この試みは成功し、今のところ想定した通りのフィルター条件が使えています。本稿に利用できるフィルター構文の一覧を記載していますので、活用していただければと思います。
Timeline Explorer フィルター構文一覧
| 分類 | 構文 | 使い方 | ごく簡単な例 | 補足 |
|---|---|---|---|---|
| 基本 | - | 文字列の書き方 | 'Administrator' |
文字列は必ずシングルクォートで囲む |
| 基本 | - | 数値の書き方 | 4624 |
クォートしない |
| 基本 | - | 日付・日時 | #2025/12/01# |
# で囲む |
| 基本 | = | 等しい | [Event Id] = 4624 |
数値はそのまま書く |
| 基本 | <> | 等しくない | [User] <> 'SYSTEM' |
文字列は 'SYSTEM' のように囲む |
| 基本 | > >= < <= | 大小比較 | [Event Id] >= 4624 |
数値・日付で使用 |
| 基本 | [Column Name] | 列名指定 | [Event Id] |
TimelineExplorerの場合は空白が入る(後述) |
| 論理 | AND | 両方満たす | [Event Id]=4624 AND [Channel]='Security' |
条件を同時に満たす |
| 論理 | OR | どちらか | [Event Id]=4624 OR [Event Id]=4625 |
どちらか一方 |
| 論理 | NOT | 否定 | NOT [Channel]='Security' |
否定は括弧付きが安全 |
| 論理 | ( ) | グループ化 | ([A]=1 OR [A]=2) AND [B]=3 |
AND/OR混在時は必須 |
| 集合 | IN (数値) | 数値リスト一致 | [Event Id] IN (4624,4625) |
数値はクォート不要 |
| 集合 | IN (文字列) | 文字列リスト一致 | [Channel] IN ('Security','System') |
文字列は必ずシングルクォートで囲む |
| 文字列 | LIKE '%文字列%' | 部分一致 | [Message] LIKE '%RDP%' |
% は「0文字以上の任意の文字列」 |
| 文字列 | LIKE '文字列%' | 前方一致 | [IP] LIKE '10.%' |
先頭が一致すればOK |
| 文字列 | LIKE '%文字列' | 後方一致 | [Path] LIKE '%.exe' |
拡張子検索 |
| 文字列 | LIKE '_文字列' | 1文字+一致 | [User] LIKE '_dmin' |
_ は「任意の1文字」 |
| 文字列 | LIKE '__文字列' | n文字+一致 | [User] LIKE '__min' |
_ を重ねると文字数指定 |
| 文字列 | NOT LIKE | 否定一致 | [IP] NOT LIKE '10.%' |
条件から除外 |
| NULL | IS NULL | NULL判定 | [User] IS NULL |
値が「存在しない」 |
| NULL | IS NOT NULL | NULL以外 | [User] IS NOT NULL |
|
| 文字列 | = '' | 空文字 | [User] = '' |
値はあるが中身が空 |
| 文字列 | <> '' | 空文字以外 | [User] <> '' |
NULLとは別物 |
| 日付 | >= #日付# | 日付比較 | [Time Created] >= #2025/12/01# |
その日の 00:00:00 |
| 日付 | 範囲 | 日付範囲 | [Time Created] >= #2025/12/01# AND [TimeCreated] < #2025/12/02# |
1日分は翌日未満 |
| 日時 | >= #日付 時刻# | 日時指定 | [Time Created] >= #2025/12/01 10:00:00# |
時刻まで指定 |
| 日時 | BETWEEN | 日時範囲 | [Time Created] BETWEEN #2025/12/01 10:00:00# AND #2025/12/01 12:00:00# |
範囲の場合は BETWEENも使える |
| 真偽値 | = True / False | 真偽判定 | [In Use] = True |
|
| 演算 | + - * / | 四則計算 | [Actual Size] > [Expected Size] * 2 |
別のカラムを基準に計算させることもできる |
| その他 | /* */ | コメント | /* COMMENT */ | 改行を含んでも良い |
カラム名の指定に関する注意
Timeline Exploererでフィルターエディターを使う場合にはカラム名の書き方に注意が必要です。CSV生データのカラム名がキャメルケースの場合は、Timeline Explorerが自動的に空白を入れてカラム名を見やすくしてくれます。例えば、EventId というカラムがあった場合には表示上は Event Id となります。
フィルターのカラム名は Timeline Explorerの表示に倣う必要 があることに注意が必要です。データ上のカラム名が EventId であっても、フィルター構文では [Event Id] と記載しなければカラム名エラー Invalid Column: 'EventId'が発生します。
コメント記法
コメントの記法についても記載していますが、これは正式なコメントの文法ではないようです。少なくとも DataView.RowFilterの解説で正式なコメント記法を確認することはできませんでした。ですが、RowFilterパーサーが結果的に構文として解釈しないようで、事実上コメントとして利用することができます。
フィルター活用例
上記の構文を活用することで、複雑なフィルターを Timeline Explorerで利用することができるようになります。いくつか例を示して、本稿を締めることにします。
プライベートIPアドレスの除外
- IPアドレスを含むカラム
IPから、プライベートIPアドレスとループバックアドレスを除外するフィルター
[IP] NOT LIKE '10.%'
AND [IP] NOT LIKE '192.168.%'
AND [IP] NOT LIKE '127.%'
AND [IP] NOT LIKE 'fe80::%'
AND [IP] NOT LIKE 'fd%'
AND [IP] NOT LIKE 'fc%'
AND [IP] <> '::1'
AND NOT (
[IP] LIKE '172.16.%'
OR [IP] LIKE '172.17.%'
OR [IP] LIKE '172.18.%'
OR [IP] LIKE '172.19.%'
OR [IP] LIKE '172.2%.%'
OR [IP] LIKE '172.30.%'
OR [IP] LIKE '172.31.%'
)
リモートデスクトップ接続(接続先側)に関するフィルター
- EvtxECmd.exeが出力したCSVファイルの中から RDP接続に関連する主なイベントを抽出するフィルター
[Event Id] In ('1149') And [Channel] = 'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational'
Or
[Event Id] In ('21', '22', '23', '24', '25', '40') And [Channel] = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
Or
[Event Id] In ('4624', '4625', '4634', '4647', '4778', '4779') And [Channel] = 'Security'
Or
[Event Id] In ('9009') And [Channel] = 'System'