一覧SP-02-3 · EDR:端末の観測・検知・対応

EDRによる端末隔離

端末、中央記録、対応処理を照合し、記録から言える範囲を判断します。

説明

端末への対応は、要求を受け付けた後に端末へ伝わって実行されます。受付、処理中、成功、失敗を同じ完了として扱うと、接続できる端末を隔離済みと判断してしまいます。

MachineActionの状態名に沿った固定履歴を調べます。隔離、ファイルへの措置、証跡収集を別の要求IDで追い、接続記録と取得物も照合します。

端末、中央記録、対応処理を照合し、記録から言える範囲を判断します。

1要求IDごとの履歴を読む

a7が隔離、a8がファイルへの措置、a9が証跡収集です。

from sp02 import * db = connect() show要求IDごとの履歴を読む(db,"SELECT id,t,kind,status FROM response ORDER BY t")

a7だけでもPending、InProgress、Succeededという複数の行があります。途中の行を最終状態として使いません。

2受付直後の状態を取得する

12秒までに届いたa7の最新状態です。

show受付直後の状態を取得する(db,"SELECT id,t,status FROM response WHERE id='a7' AND t<=12 ORDER BY t DESC LIMIT 1")

Pendingです。この時点では完了を示す記録がありません。

3同じ時点の業務接続を確認する

端末側の独立した接続試験記録を調べます。

show同じ時点の業務接続を確認する(db,"SELECT t,target,result FROM probe WHERE t=12")

businessへの接続は成功しています。要求の受付だけで業務通信が遮断されたわけではありません。

4完了後の接続範囲を確認する

20秒の業務通信と管理通信を比較します。

show完了後の接続範囲を確認する(db,"SELECT t,target,result FROM probe WHERE t=20 ORDER BY target")

業務通信はtimeout、管理通信はconnectedです。業務通信の失敗はこの試験先の結果であり、全宛先の網羅確認ではありません。

5別の対応要求の失敗を見落とさない

各要求の最新行を取得します。

show別の対応要求の失敗を見落とさない(db,"SELECT r.id,r.kind,r.status FROM response r WHERE r.t=(SELECT MAX(x.t) FROM response x WHERE x.id=r.id) ORDER BY r.id")

a8はFailedです。隔離成功からプロセス停止やファイル隔離まで成功したと推測できません。

6収集物の内容とハッシュを確認する

取得した証跡を固定の公開バイト列として開きます。

bundle = b'host=ws7\naction=a9\nprocess=g1\n' expected = hashlib.sha256(bundle).hexdigest() print(bundle.decode収集物の内容とハッシュを確認する(),end='') print(expected)

hostとactionが対象に対応します。ハッシュは取得後の同一性確認に使います。収集対象を網羅した証明にはなりません。

7取得後の変更を検出する

一文字変えたコピーと取得直後のハッシュを比較します。

print(hashlib.sha256取得後の変更を検出する(bundle).hexdigest()==expected) print(hashlib.sha256(bundle.replace(b'ws7',b'ws8')).hexdigest()==expected)

元の収集物は一致し、変更コピーは一致しません。要求の完了、対象の一致、取得物の保存を別々に確認します。

まとめ

要求IDを使って最新状態を取得します。

隔離、停止、収集は個別に結果を確認します。

接続試験と証跡の内容も照合します。

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

Python 3.15 / SQLite / 固定の端末記録

1
from sp02 import * db = connect() show(db,"SELECT id,t,kind,status FROM response ORDER BY t")
id | t | kind | status
a7 | 10 | Isolate | Pending
a7 | 14 | Isolate | InProgress
a7 | 18 | Isolate | Succeeded
a8 | 19 | StopAndQuarantineFile | Failed
a9 | 21 | CollectInvestigationPackage | Succeeded
2
show(db,"SELECT id,t,status FROM response WHERE id='a7' AND t<=12 ORDER BY t DESC LIMIT 1")
id | t | status
a7 | 10 | Pending
3
show(db,"SELECT t,target,result FROM probe WHERE t=12")
t | target | result
12 | business | connected
4
show(db,"SELECT t,target,result FROM probe WHERE t=20 ORDER BY target")
t | target | result
20 | business | timeout
20 | management | connected
5
show(db,"SELECT r.id,r.kind,r.status FROM response r WHERE r.t=(SELECT MAX(x.t) FROM response x WHERE x.id=r.id) ORDER BY r.id")
id | kind | status
a7 | Isolate | Succeeded
a8 | StopAndQuarantineFile | Failed
a9 | CollectInvestigationPackage | Succeeded
6
bundle = b'host=ws7\naction=a9\nprocess=g1\n' expected = hashlib.sha256(bundle).hexdigest() print(bundle.decode(),end='') print(expected)
host=ws7
action=a9
process=g1
72a1e30abacb5433146c026997a6b1ddd9af8c4b8eb681f5373fb447d46fb931
7
print(hashlib.sha256(bundle).hexdigest()==expected) print(hashlib.sha256(bundle.replace(b'ws7',b'ws8')).hexdigest()==expected)
True
False

演習完了