自動起動プログラムの調査
Updateという名前の登録を比較し、利用者領域とシステム領域の違い、ハッシュ、実行経路を照合します。設定が存在する範囲と、実行が確認できた範囲を分けて説明します。
説明
サービスやタスクの表示名が更新処理らしい名前でも、実行対象が正規のプログラムとは限りません。同名のファイルが別のディレクトリに置かれている場合は、完全なパスと内容を確認します。
Updateという名前の登録を比較し、利用者領域とシステム領域の違い、ハッシュ、実行経路を照合します。設定が存在する範囲と、実行が確認できた範囲を分けて説明します。
1登録名とパスを一覧する
nameは登録名で、ファイルの正当性を保証する値ではありません。
from oplab import *
db=connect(11)
show(db, 'SELECT登録名とパスを一覧する * FROM settings ORDER BY t')update.exeは二つの場所にあります。同じ名前でもハッシュh7とh8で実体が異なります。
2同じ実体を参照する設定を探す
パスとハッシュの両方を合わせて集計します。
show(db, 'SELECT同じ実体を参照する設定を探す path,hash,COUNT(*) AS registrations FROM settings GROUP BY path,hash ORDER BY path')利用者領域のh7はサービスとスタートアップから参照されています。対処対象を一つの設定だけに限定しない確認が必要です。
3変更主体を確認する
登録した主体と実行アカウントを分けて調べます。
show(db, 'SELECT変更主体を確認する id,kind,actor FROM settings ORDER BY id')s1とs3はalice、s2はadminです。変更権限の入手経緯や承認は追加の調査対象です。
4起動経路と実体を照合する
経路名、パス、ハッシュ、端末、時間を同時に合わせます。
show(db, 'SELECT起動経路と実体を照合する s.id,p.id,p.account FROM settings s JOIN run p ON s.host=p.host AND p.source=s.kind||"/"||s.name AND p.path=s.path AND p.hash=s.hash AND p.t>=s.t')s1にp1が対応し、SYSTEMで実行されています。同じパスの手動起動だけを、自動起動の実績として扱いません。
5登録に対応しない手動実行を読む
sourceがmanualの記録を確認します。
show(db, 'SELECT登録に対応しない手動実行を読む id,path,hash,account FROM run WHERE source="manual"')p2はh8の手動実行です。タスクの実行証拠とは別に残します。
6実行が未確認の登録を抽出する
対応する起動経路の記録がない設定を検索します。
show(db, 'SELECT実行が未確認の登録を抽出する s.id,s.kind,s.path FROM settings s WHERE NOT EXISTS (SELECT 1 FROM run p WHERE p.host=s.host AND p.source=s.kind||"/"||s.name AND p.path=s.path AND p.hash=s.hash AND p.t>=s.t)')s2とs3は設定の存在まで確認できています。実行済みのs1と同じ強さの主張にはしないようにします。
まとめ
s2とs3は設定の存在まで確認できています。実行済みのs1と同じ強さの主張にはしないようにします。
表示された証拠IDと検索条件を残すと、調査結果を元の記録までたどれます。
操作履歴と解説を振り返れます。
Python 3.15 / SQLite・固定の調査記録
from oplab import *
db=connect(11)
show(db, 'SELECT * FROM settings ORDER BY t')id | t | host | kind | name | path | hash | actor s1 | 10 | ws7 | service | UpdateSvc | C:/Users/alice/update.exe | h7 | alice s2 | 11 | ws7 | task | UpdateTask | C:/Windows/System32/update.exe | h8 | admin s3 | 12 | ws7 | startup | UpdateLink | C:/Users/alice/update.exe | h7 | alice
show(db, 'SELECT path,hash,COUNT(*) AS registrations FROM settings GROUP BY path,hash ORDER BY path')path | hash | registrations C:/Users/alice/update.exe | h7 | 2 C:/Windows/System32/update.exe | h8 | 1
show(db, 'SELECT id,kind,actor FROM settings ORDER BY id')id | kind | actor s1 | service | alice s2 | task | admin s3 | startup | alice
show(db, 'SELECT s.id,p.id,p.account FROM settings s JOIN run p ON s.host=p.host AND p.source=s.kind||"/"||s.name AND p.path=s.path AND p.hash=s.hash AND p.t>=s.t')id | id | account s1 | p1 | SYSTEM
show(db, 'SELECT id,path,hash,account FROM run WHERE source="manual"')id | path | hash | account p2 | C:/Windows/System32/update.exe | h8 | admin
show(db, 'SELECT s.id,s.kind,s.path FROM settings s WHERE NOT EXISTS (SELECT 1 FROM run p WHERE p.host=s.host AND p.source=s.kind||"/"||s.name AND p.path=s.path AND p.hash=s.hash AND p.t>=s.t)')id | kind | path s2 | task | C:/Windows/System32/update.exe s3 | startup | C:/Users/alice/update.exe
演習完了