一覧OP-10-1 · 初期侵入・実行の痕跡

メール添付ファイルからの侵入調査

請求書という名前の固定文書を調査し、メール配送、保存、文書を開いたプロセス、Pythonの起動へ進みます。どこまで直接の記録があり、どこから追加確認が必要かを説明します。

説明

メールが受信されたこと、添付が保存されたこと、文書が開かれたこと、子プロセスが起動したことは異なる観測です。各段階をメッセージID、ファイルの実体、プロセスGUIDで照合します。

請求書という名前の固定文書を調査し、メール配送、保存、文書を開いたプロセス、Pythonの起動へ進みます。どこまで直接の記録があり、どこから追加確認が必要かを説明します。

1配送状態を確認する

acceptedは受理、deliveredは配信、rejectedは拒否の記録です。

from oplab import * db=connect(10) show(db, 'SELECT配送状態を確認する * FROM mail ORDER BY t,id')

msg7は配信されています。msg8の拒否を受信者端末への到達と数えないようにします。

2添付と保存ファイルを結合する

メッセージIDと添付のハッシュ識別子を合わせます。hashは教材用の短縮値です。

show(db, 'SELECT添付と保存ファイルを結合する m.id,f.id,f.host,f.path FROM mail m JOIN files f ON m.message_id=f.source AND m.attachment_hash=f.hash WHERE m.stage="delivered"')

m2とf1が対応し、ws7にinvoice.docxが保存されています。保存だけでは文書を開いたかは分かりません。

3文書を引数にした起動を探す

同じ端末で保存後にファイルを開いた候補を調べます。

show(db, 'SELECT文書を引数にした起動を探す f.id,p.id,p.image,p.arg FROM files f JOIN processes p ON f.host=p.host AND f.path=p.arg AND p.t>=f.t WHERE f.id="f1"')

p1のwriter.exeが文書を引数にしています。文書のどの機能が動いたかは、このプロセス記録だけでは決まりません。

4文書アプリの子を探す

ParentProcessGuidに相当するparentを照合します。

show(db, 'SELECT文書アプリの子を探す c.id,c.t,c.image,c.arg FROM processes c JOIN processes p ON c.host=p.host AND c.parent=p.guid WHERE p.id="p1"')

p2は文書アプリの子としてPythonを起動しています。利用者が手動で起動した通常操作かどうかも調査事項です。

5引数のファイルがその時点に保存されていたか調べる

実行開始と取得時刻の前後を比較します。

show(db, 'SELECT引数のファイルがその時点に保存されていたか調べる p.id,p.t AS started,f.t AS saved,p.t-f.t AS delta FROM processes p JOIN files f ON p.host=f.host AND p.arg=f.path WHERE p.id="p2"')

p2はf2の保存より1秒前です。後から保存されたファイルを、p2がその内容で実行したと結び付けてはいけません。

6保存後の実行候補を絞る

時刻条件を加え、取得済みファイルとの対応候補を残します。

show(db, 'SELECT保存後の実行候補を絞る p.id,p.t,p.image,f.id,f.hash FROM processes p JOIN files f ON p.host=f.host AND p.arg=f.path AND p.t>=f.t WHERE f.id="f2"')

p3は保存後の実行です。配送から親子関係まで確認しつつ、ファイル内容との対応には取得時刻と必要に応じて実行時ハッシュを使います。

まとめ

p3は保存後の実行です。配送から親子関係まで確認しつつ、ファイル内容との対応には取得時刻と必要に応じて実行時ハッシュを使います。

表示された証拠IDと検索条件を残すと、調査結果を元の記録までたどれます。

操作履歴と解説を振り返れます。

Python 3.15 / SQLite・固定の調査記録

1
from oplab import * db=connect(10) show(db, 'SELECT * FROM mail ORDER BY t,id')
id | message_id | recipient | stage | t | attachment_hash
m1 | msg7 | alice | accepted | 10 | doc7
m2 | msg7 | alice | delivered | 11 | doc7
m3 | msg8 | bob | rejected | 11 | doc8
2
show(db, 'SELECT m.id,f.id,f.host,f.path FROM mail m JOIN files f ON m.message_id=f.source AND m.attachment_hash=f.hash WHERE m.stage="delivered"')
id | id | host | path
m2 | f1 | ws7 | C:/Users/alice/invoice.docx
3
show(db, 'SELECT f.id,p.id,p.image,p.arg FROM files f JOIN processes p ON f.host=p.host AND f.path=p.arg AND p.t>=f.t WHERE f.id="f1"')
id | id | image | arg
f1 | p1 | writer.exe | C:/Users/alice/invoice.docx
4
show(db, 'SELECT c.id,c.t,c.image,c.arg FROM processes c JOIN processes p ON c.host=p.host AND c.parent=p.guid WHERE p.id="p1"')
id | t | image | arg
p2 | 15 | python.exe | C:/Users/alice/report.py
5
show(db, 'SELECT p.id,p.t AS started,f.t AS saved,p.t-f.t AS delta FROM processes p JOIN files f ON p.host=f.host AND p.arg=f.path WHERE p.id="p2"')
id | started | saved | delta
p2 | 15 | 16 | -1
6
show(db, 'SELECT p.id,p.t,p.image,f.id,f.hash FROM processes p JOIN files f ON p.host=f.host AND p.arg=f.path AND p.t>=f.t WHERE f.id="f2"')
id | t | image | id | hash
p3 | 18 | python.exe | f2 | script7

演習完了