スクリプトの取得と実行の追跡
利用者のディレクトリに保存されたPythonスクリプトを、取得元、保存時刻、引数、出力へ照合します。処理内容はファイルの存在確認です。ツールの名前だけで目的を決めず、記録された処理と結果を読みます。
説明
スクリプトは、ファイル自体の拡張子だけでなく、どのインタープリターへ渡されたかを調べます。取得した内容が、実際に起動時に使われた内容と同じかも確認が必要です。
利用者のディレクトリに保存されたPythonスクリプトを、取得元、保存時刻、引数、出力へ照合します。処理内容はファイルの存在確認です。ツールの名前だけで目的を決めず、記録された処理と結果を読みます。
1取得元と保存先を確認する
sourceは取得元URLです。URLが残っているだけでは、そのサーバーの管理者や実体まで特定できません。
from oplab import *
db=connect(10)
show(db, 'SELECT取得元と保存先を確認する id,t,path,hash,source FROM files WHERE id="f2"')report.pyは利用者領域に保存されています。そこに置かれたこと自体を不正の判定に使わず、取得経緯と実行を調べます。
2取得した本文を読む
固定試料の短縮ハッシュを使って本文を対応付けます。
show(db, 'SELECT取得した本文を読む f.id,s.text FROM files f JOIN script s USING(hash) WHERE f.id="f2"')Path("report.txt").exists()はファイルの存在を調べ、結果を表示します。相対パスなので、実行時の作業ディレクトリも意味を持ちます。
3同じパスを引数にした起動を探す
ファイル名ではなく、Pythonへ渡された引数のパスを検索します。
show(db, 'SELECT同じパスを引数にした起動を探す id,t,actor,image,arg FROM processes WHERE arg="C:/Users/alice/report.py" ORDER BY t')p2とp3があります。パスが同じでも、二回の起動時にファイル内容が同じだったとは限りません。
4取得後の実行を絞る
保存時刻より後に開始したプロセスを照合します。
show(db, 'SELECT取得後の実行を絞る p.id,p.actor,p.image,f.hash FROM processes p JOIN files f ON p.host=f.host AND p.arg=f.path WHERE f.id="f2" AND p.t>=f.t')p3が候補です。実行時ハッシュがない場合、保存後に書き換えられていないことの確認は別途必要です。
5プロセスに対応する出力を読む
outputは取得済みのプロセス出力をIDで関連付けた表です。
show(db, 'SELECTプロセスに対応する出力を読む p.id,o.id,o.text FROM processes p JOIN output o ON p.id=o.process_id')p3にはTrueが記録されています。この出力が示すのは存在確認の結果で、report.txtを読んだことや外へ送ったことではありません。
6親子関係と出力をまとめる
親プロセスと出力を同じ行でたどれるようにします。
show(db, 'SELECT親子関係と出力をまとめる p.id,parent.id AS parent_event,p.arg,o.text FROM processes p LEFT JOIN processes parent ON p.host=parent.host AND p.parent=parent.guid LEFT JOIN output o ON p.id=o.process_id WHERE p.id="p3"')p3の親はp2です。取得、起動、本文、結果を別の証拠として対応付け、確認できた処理の範囲を説明します。
まとめ
p3の親はp2です。取得、起動、本文、結果を別の証拠として対応付け、確認できた処理の範囲を説明します。
表示された証拠IDと検索条件を残すと、調査結果を元の記録までたどれます。
操作履歴と解説を振り返れます。
Python 3.15 / SQLite・固定の調査記録
from oplab import *
db=connect(10)
show(db, 'SELECT id,t,path,hash,source FROM files WHERE id="f2"')id | t | path | hash | source f2 | 16 | C:/Users/alice/report.py | script7 | https://files.example.test/report.py
show(db, 'SELECT f.id,s.text FROM files f JOIN script s USING(hash) WHERE f.id="f2"')id | text
f2 | from pathlib import Path
print(Path("report.txt").exists())show(db, 'SELECT id,t,actor,image,arg FROM processes WHERE arg="C:/Users/alice/report.py" ORDER BY t')id | t | actor | image | arg p2 | 15 | alice | python.exe | C:/Users/alice/report.py p3 | 18 | alice | python.exe | C:/Users/alice/report.py
show(db, 'SELECT p.id,p.actor,p.image,f.hash FROM processes p JOIN files f ON p.host=f.host AND p.arg=f.path WHERE f.id="f2" AND p.t>=f.t')id | actor | image | hash p3 | alice | python.exe | script7
show(db, 'SELECT p.id,o.id,o.text FROM processes p JOIN output o ON p.id=o.process_id')id | id | text p3 | o1 | True
show(db, 'SELECT p.id,parent.id AS parent_event,p.arg,o.text FROM processes p LEFT JOIN processes parent ON p.host=parent.host AND p.parent=parent.guid LEFT JOIN output o ON p.id=o.process_id WHERE p.id="p3"')id | parent_event | arg | text p3 | p2 | C:/Users/alice/report.py | True
演習完了