一覧OP-11-1 · 永続化・権限利用・横展開の痕跡

自動起動プログラムの調査

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・固定の調査記録

1
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
2
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
3
show(db, 'SELECT id,kind,actor FROM settings ORDER BY id')
id | kind | actor
s1 | service | alice
s2 | task | admin
s3 | startup | alice
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')
id | id | account
s1 | p1 | SYSTEM
5
show(db, 'SELECT id,path,hash,account FROM run WHERE source="manual"')
id | path | hash | account
p2 | C:/Windows/System32/update.exe | h8 | admin
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)')
id | kind | path
s2 | task | C:/Windows/System32/update.exe
s3 | startup | C:/Users/alice/update.exe

演習完了