データ送信の目的と成否の調査
800バイトの外向き送信と800000バイトのバックアップを調べます。失敗した試行を転送成功へ加算せず、量の大小と不審さを別々に評価する方法を学びます。
説明
大きな転送量は調査の手掛かりですが、バックアップなどの正常処理でも発生します。方向、成功・失敗、業務ジョブ、通常時の量をそろえて比較する必要があります。
800バイトの外向き送信と800000バイトのバックアップを調べます。失敗した試行を転送成功へ加算せず、量の大小と不審さを別々に評価する方法を学びます。
1送信記録を比較する
bytesはこの資料で記録された要求側の転送量です。resultが転送完了の判定です。
from oplab import *
db=connect(12)
show(db, 'SELECT送信記録を比較する * FROM transfer ORDER BY t')最大はbackup7の転送です。ws7には同じ800バイトの成功と失敗が一つずつあります。
2成否ごとの量を計算する
失敗行を含めた総和と成功分を分けます。
show(db, 'SELECT成否ごとの量を計算する host,result,SUM(bytes) AS bytes FROM transfer GROUP BY host,result ORDER BY host,result')ws7の成功は800バイトです。失敗の800をそのまま加えて1600バイトの持出し成功と報告することはできません。
3業務ジョブの通常範囲を照合する
ジョブ名を台帳へ結び、通常量の幅を表示します。
show(db, 'SELECT業務ジョブの通常範囲を照合する t.id,t.bytes,b.min_bytes,b.max_bytes,b.owner FROM transfer t JOIN baseline b USING(job)')t2の800000は700000〜900000の範囲です。通常範囲内という理由だけで、送信先や内容の確認を省くこともできません。
4業務との対応がない送信を絞る
台帳のない転送のうち、成功記録を抽出します。
show(db, 'SELECT業務との対応がない送信を絞る t.id,t.host,t.destination,t.bytes FROM transfer t LEFT JOIN baseline b USING(job) WHERE b.job IS NULL AND t.result="success"')t1が追加調査対象です。対応する業務記録がないことと、悪意が確定していることは異なります。
5送信元プロセスの先行活動を見る
転送元と同じプロセスの記録を検索します。
show(db, 'SELECT送信元プロセスの先行活動を見る a.id,a.action,a.target,a.result FROM activity a WHERE a.process=(SELECT process FROM transfer WHERE id="t1") ORDER BY a.t')直前に読取りとアーカイブ作成が観測されています。持出しの可能性を調べる理由になりますが、内容の同一性は未確認です。
6観測した成功量を宛先別に残す
送信量の集計条件を明示して結果を残します。
show(db, 'SELECT観測した成功量を宛先別に残す destination,SUM(bytes) AS successful_bytes,COUNT(*) AS transfers FROM transfer WHERE result="success" GROUP BY destination ORDER BY destination')外部保存先800、バックアップ先800000です。どちらも集計条件付きの観測量であり、意図や漏えいしたファイル数を直接表す数値ではありません。
まとめ
外部保存先800、バックアップ先800000です。どちらも集計条件付きの観測量であり、意図や漏えいしたファイル数を直接表す数値ではありません。
表示された証拠IDと検索条件を残すと、調査結果を元の記録までたどれます。
操作履歴と解説を振り返れます。
Python 3.15 / SQLite・固定の調査記録
from oplab import *
db=connect(12)
show(db, 'SELECT * FROM transfer ORDER BY t')id | t | host | process | destination | bytes | result | job t1 | 20 | ws7 | g7 | external-store | 800 | success | NULL t2 | 21 | backup7 | g8 | backup-store | 800000 | success | nightly t3 | 22 | ws7 | g7 | external-store | 800 | failed | NULL
show(db, 'SELECT host,result,SUM(bytes) AS bytes FROM transfer GROUP BY host,result ORDER BY host,result')host | result | bytes backup7 | success | 800000 ws7 | failed | 800 ws7 | success | 800
show(db, 'SELECT t.id,t.bytes,b.min_bytes,b.max_bytes,b.owner FROM transfer t JOIN baseline b USING(job)')id | bytes | min_bytes | max_bytes | owner t2 | 800000 | 700000 | 900000 | backup-team
show(db, 'SELECT t.id,t.host,t.destination,t.bytes FROM transfer t LEFT JOIN baseline b USING(job) WHERE b.job IS NULL AND t.result="success"')id | host | destination | bytes t1 | ws7 | external-store | 800
show(db, 'SELECT a.id,a.action,a.target,a.result FROM activity a WHERE a.process=(SELECT process FROM transfer WHERE id="t1") ORDER BY a.t')id | action | target | result e1 | list | C:/Data | success e2 | read | C:/Data/a.csv | success e3 | read | C:/Data/b.csv | denied e4 | archive | C:/Temp/data.zip | success
show(db, 'SELECT destination,SUM(bytes) AS successful_bytes,COUNT(*) AS transfers FROM transfer WHERE result="success" GROUP BY destination ORDER BY destination')destination | successful_bytes | transfers backup-store | 800000 | 1 external-store | 800 | 1
演習完了