PowerShellログの復元と収集範囲
固定のスクリプトブロック断片を並べ、完成した内容と欠けた内容を分けます。WMIの記録や収集設定も調べ、文字列が記録されたこと、処理が成功したこと、ログが残る条件を別々に評価します。
説明
PowerShellのスクリプトブロック記録は一つの内容が複数のイベントへ分割されることがあります。部分番号と総数を確認してから結合しないと、処理の一部を読み落とします。
固定のスクリプトブロック断片を並べ、完成した内容と欠けた内容を分けます。WMIの記録や収集設定も調べ、文字列が記録されたこと、処理が成功したこと、ログが残る条件を別々に評価します。
1断片番号を読む
blockはScriptBlockId、partとtotalは分割番号と総数に相当する抽出列です。
from oplab import *
db=connect(3)
show(db, 'SELECT断片番号を読む id,block,part,total,text FROM script WHERE block IS NOT NULL ORDER BY block,part')sb7は1/2と2/2があり、sb8は1/2だけです。同じブロックの断片を順序付きで扱います。
2欠けているブロックを見つける
重複した配送があっても充足と誤認しないよう、異なる部分番号を数えます。
show(db, 'SELECT欠けているブロックを見つける block,COUNT(DISTINCT part) AS parts,MAX(total) AS expected FROM script WHERE block IS NOT NULL GROUP BY block')sb7は2/2、sb8は1/2です。総数が一致するかに加え、番号の範囲や総数の不一致も本来の検査対象です。
3順番どおりに本文を復元する
並び順を指定した副問い合わせからgroup_concatへ渡します。
show(db, 'SELECT順番どおりに本文を復元する group_concat(text,"") AS script_text FROM (SELECT text FROM script WHERE block="sb7" ORDER BY part)')Get-Content C:/Data/report.txtになります。スクリプト内容の記録だけでは、読み出しが成功したか、出力がどこへ届いたかは分かりません。
4WMI側の観測を確認する
WMIの操作記録には、呼出元プロセスや結果コードが含まれる場合があります。
show(db, 'SELECTWMI側の観測を確認する id,t,text FROM script WHERE channel="WMI-Activity/Operational"')w1にはClientProcessId=500があります。PID再利用を考え、端末と時刻を合わせずに別記録へ結び付けないようにします。
5監査が有効だった期間を調べる
開始を含み終了を含まない区間として収集設定を記録しています。
show(db, 'SELECT監査が有効だった期間を調べる * FROM coverage ORDER BY channel,start')PowerShellは時刻10から、WMIは15からが対象です。それ以前に検索結果がないことは、活動がなかった証拠になりません。
6不完全な本文を抽出する
完全な内容として扱えないブロックを調査課題として残します。
show(db, 'SELECT不完全な本文を抽出する block FROM script WHERE block IS NOT NULL GROUP BY block HAVING COUNT(DISTINCT part)<>MAX(total)')sb8は追加取得が必要です。復元できた文字列、実行結果、未収集の範囲を一つの確実な結論へまとめないようにします。
まとめ
sb8は追加取得が必要です。復元できた文字列、実行結果、未収集の範囲を一つの確実な結論へまとめないようにします。
表示された証拠IDと検索条件を残すと、調査結果を元の記録までたどれます。
操作履歴と解説を振り返れます。
Python 3.15 / SQLite・固定の調査記録
from oplab import *
db=connect(3)
show(db, 'SELECT id,block,part,total,text FROM script WHERE block IS NOT NULL ORDER BY block,part')id | block | part | total | text b1 | sb7 | 1 | 2 | Get-Content b2 | sb7 | 2 | 2 | C:/Data/report.txt b3 | sb8 | 1 | 2 | Get-Item
show(db, 'SELECT block,COUNT(DISTINCT part) AS parts,MAX(total) AS expected FROM script WHERE block IS NOT NULL GROUP BY block')block | parts | expected sb7 | 2 | 2 sb8 | 1 | 2
show(db, 'SELECT group_concat(text,"") AS script_text FROM (SELECT text FROM script WHERE block="sb7" ORDER BY part)')script_text Get-Content C:/Data/report.txt
show(db, 'SELECT id,t,text FROM script WHERE channel="WMI-Activity/Operational"')id | t | text w1 | 18 | ClientProcessId=500; ResultCode=0x0
show(db, 'SELECT * FROM coverage ORDER BY channel,start')channel | start | end | enabled PowerShell/Operational | 0 | 10 | 0 PowerShell/Operational | 10 | 30 | 1 WMI-Activity/Operational | 15 | 30 | 1
show(db, 'SELECT block FROM script WHERE block IS NOT NULL GROUP BY block HAVING COUNT(DISTINCT part)<>MAX(total)')block sb8
演習完了