一覧OP-03-2 · Windowsプロセス・永続化の記録

サービス・タスク・Runキーによる永続化

サービス、定期タスク、Runキーの固定記録から、設定した主体と起動条件を読みます。実行記録の経路まで照合し、パスが一致するだけで特定の起動設定が使われたと断定しない方法を学びます。

説明

自動起動の設定は、登録、起動条件の成立、実際の実行という別の段階を持ちます。同じ実行ファイルがサービスと手動操作の両方から起動される場合もあります。

サービス、定期タスク、Runキーの固定記録から、設定した主体と起動条件を読みます。実行記録の経路まで照合し、パスが一致するだけで特定の起動設定が使われたと断定しない方法を学びます。

1登録された設定を一覧する

kindが登録の種類、triggerが起動条件です。ここでは製品ログから抽出した調査用の列を使います。

from oplab import * db=connect(3) show(db, 'SELECT登録された設定を一覧する * FROM startup ORDER BY t')

同じreport.exeがサービスとRunキーにあります。種類によって実行される契機とアカウントが変わります。

2設定を変更した主体を調べる

誰が登録したかと、実行時に誰の権限を使うかは別の項目です。

show(db, 'SELECT設定を変更した主体を調べる id,name,actor,trigger FROM startup ORDER BY t')

ReportSvcはadminが登録し、NightReportとRunはaliceが登録しています。実行アカウントは次の記録で確認します。

3同じパスを使う実行を探す

まずパスの一致だけで候補を広く出します。

show(db, 'SELECT同じパスを使う実行を探す s.id,s.kind,x.id,x.source,x.account FROM startup s JOIN executions x USING(path) ORDER BY s.id,x.id')

ReportSvcとRunの両方にx1とx2が結び付きます。この段階では四つの候補にすぎず、起動経路の確認が必要です。

4サービス経由の実行を絞る

sourceに含まれる登録名と時刻も確認します。

show(db, 'SELECTサービス経由の実行を絞る s.id,x.id,x.t,x.account FROM startup s JOIN executions x ON x.source="service/"||s.name AND x.path=s.path AND x.t>=s.t WHERE s.kind="service"')

s1とx1が対応し、SYSTEMで実行されています。手動実行のx2をサービス起動の証拠に混ぜずに済みます。

5実行記録のない登録を調べる

登録経路に対応する実行がない項目を残します。

show(db, 'SELECT実行記録のない登録を調べる s.id,s.kind,s.trigger FROM startup s WHERE NOT EXISTS (SELECT 1 FROM executions x WHERE x.source=s.kind||"/"||s.name AND x.path=s.path AND x.t>=s.t)')

タスクとRunキーの起動は、この資料では裏付けられません。登録時刻だけから実行済みとしないようにします。

6起動経路ごとに証拠をまとめる

実行記録そのものを読み返し、登録の表と分けて説明します。

show(db, 'SELECT起動経路ごとに証拠をまとめる id,source,path,account FROM executions ORDER BY t')

確認できる実行はサービス経由と手動の2件です。設定の存在、起動条件、実際に使われた経路を対応付けて報告します。

まとめ

確認できる実行はサービス経由と手動の2件です。設定の存在、起動条件、実際に使われた経路を対応付けて報告します。

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

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

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

1
from oplab import * db=connect(3) show(db, 'SELECT * FROM startup ORDER BY t')
id | t | kind | name | path | trigger | actor
s1 | 20 | service | ReportSvc | C:/Tools/report.exe | automatic | CORP/admin
s2 | 22 | task | NightReport | C:/Tools/night.exe | 02:00 | CORP/alice
s3 | 23 | registry | Run/Report | C:/Tools/report.exe | user_logon | CORP/alice
2
show(db, 'SELECT id,name,actor,trigger FROM startup ORDER BY t')
id | name | actor | trigger
s1 | ReportSvc | CORP/admin | automatic
s2 | NightReport | CORP/alice | 02:00
s3 | Run/Report | CORP/alice | user_logon
3
show(db, 'SELECT s.id,s.kind,x.id,x.source,x.account FROM startup s JOIN executions x USING(path) ORDER BY s.id,x.id')
id | kind | id | source | account
s1 | service | x1 | service/ReportSvc | SYSTEM
s1 | service | x2 | user_manual | CORP/alice
s3 | registry | x1 | service/ReportSvc | SYSTEM
s3 | registry | x2 | user_manual | CORP/alice
4
show(db, 'SELECT s.id,x.id,x.t,x.account FROM startup s JOIN executions x ON x.source="service/"||s.name AND x.path=s.path AND x.t>=s.t WHERE s.kind="service"')
id | id | t | account
s1 | x1 | 25 | SYSTEM
5
show(db, 'SELECT s.id,s.kind,s.trigger FROM startup s WHERE NOT EXISTS (SELECT 1 FROM executions x WHERE x.source=s.kind||"/"||s.name AND x.path=s.path AND x.t>=s.t)')
id | kind | trigger
s2 | task | 02:00
s3 | registry | user_logon
6
show(db, 'SELECT id,source,path,account FROM executions ORDER BY t')
id | source | path | account
x1 | service/ReportSvc | C:/Tools/report.exe | SYSTEM
x2 | user_manual | C:/Tools/report.exe | CORP/alice

演習完了