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

スクリプトの取得と実行の追跡

利用者のディレクトリに保存された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・固定の調査記録

1
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
2
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())
3
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
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')
id | actor | image | hash
p3 | alice | python.exe | script7
5
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
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"')
id | parent_event | arg | text
p3 | p2 | C:/Users/alice/report.py | True

演習完了