一覧SP-21-1 · デセプション:囮への接触の観測

囮ファイルによる検知と通知

囮への接触から通知までを識別子でたどり、根拠のない操作や人物像を補わずに説明します。

説明

デセプションでは、通常業務で使わない囮の資源や識別用トークンへの接触を観測します。接触の種類と通知の届き方を分けて調べると、単なる一覧表示とファイル読取りを取り違えずに追跡できます。

固定の囮台帳、接触記録、通知記録をSQLで結びます。通知URLに含めるトークンを解析し、通知元アドレスから分かる範囲も確認します。

囮への接触から通知までを識別子でたどり、根拠のない操作や人物像を補わずに説明します。

1囮の場所と種類を確認する

d7はファイル、d8はサービスです。

from sp21 import * from sp02 import show囮の場所と種類を確認する db=connect() show(db,"SELECT * FROM decoy ORDER BY id")

場所と種類が異なるため、同じ接触イベントとして一括りにしません。

2接触の種類を時系列で読む

listed、opened、callback、connectedを並べます。

show接触の種類を時系列で読む(db,"SELECT * FROM event ORDER BY t")

d7は一覧表示後に開かれ、その後トークンへのcallbackがあります。d8への接続はscanner7からです。

3ファイルを開いた記録へ対象を結ぶ

targetが囮IDに対応する行を取得します。

show(db,"SELECT e.id,e.source,d.location,e.kind FROM event e JOINファイルを開いた記録へ対象を結ぶ decoy d ON e.target=d.id WHERE e.kind='opened'")

e2はshare-aのd7です。listedだけで中身を読んだと判断せず、openedの根拠を使います。

4トークンを持つ通知URLを解析する

公開の固定トークンをURLのパラメーターへ入れます。

url='https://notify.example.test/event?'+urlencode({'token':'public-token-7'}) print(url) print(parse_qsトークンを持つ通知URLを解析する(urlsplit(url).query))

tokenが取り出せます。この値は囮を特定するもので、閲覧者の本人認証を行う資格情報ではありません。

5callbackを囮へ対応付ける

囮IDではなくtokenで結合します。

show(db,"SELECT e.id,e.source,d.id AS decoy,d.location FROM event e JOIN decoy d ON e.target=d.tokencallbackを囮へ対応付ける WHERE e.kind='callback'")

e3はd7に対応します。sourceはproxy7なので、実際に閲覧した端末や人物をこの値だけで確定できません。

6通知の待機と配送完了を分ける

接触記録と配送台帳を結びます。

show(db,"SELECT e.id,e.kind,n.queued,n.delivered FROM event e LEFT JOIN通知の待機と配送完了を分ける notification n ON n.event=e.id ORDER BY e.t")

e2はqueued=1でもdelivered=0です。接触を検知したことと、担当者へ通知が届いたことは別の状態です。

7未配送の通知を抽出する

配送の再確認が必要な行です。

show未配送の通知を抽出する(db,"SELECT event FROM notification WHERE queued=1 AND delivered=0")

e2が出ます。通知が届かなかった原因は転送先やキューなど追加資料で調べ、接触自体がなかったことにはしません。

まとめ

接触の種類と対象を対応付けます。

トークンと通知元から分かる範囲を確認します。

検知と通知配送の完了を分けます。

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

Python 3.15 / 固定パケット・SQLiteの接続資料

1
from sp21 import * from sp02 import show db=connect() show(db,"SELECT * FROM decoy ORDER BY id")
id | location | kind | token
d7 | share-a | file | public-token-7
d8 | segment-b | service | public-token-8
2
show(db,"SELECT * FROM event ORDER BY t")
id | t | source | target | kind
e1 | 10 | 192.0.2.7 | d7 | listed
e2 | 20 | 192.0.2.7 | d7 | opened
e3 | 21 | proxy7 | public-token-7 | callback
e4 | 30 | scanner7 | d8 | connected
3
show(db,"SELECT e.id,e.source,d.location,e.kind FROM event e JOIN decoy d ON e.target=d.id WHERE e.kind='opened'")
id | source | location | kind
e2 | 192.0.2.7 | share-a | opened
4
url='https://notify.example.test/event?'+urlencode({'token':'public-token-7'}) print(url) print(parse_qs(urlsplit(url).query))
https://notify.example.test/event?token=public-token-7
{'token': ['public-token-7']}
5
show(db,"SELECT e.id,e.source,d.id AS decoy,d.location FROM event e JOIN decoy d ON e.target=d.token WHERE e.kind='callback'")
id | source | decoy | location
e3 | proxy7 | d7 | share-a
6
show(db,"SELECT e.id,e.kind,n.queued,n.delivered FROM event e LEFT JOIN notification n ON n.event=e.id ORDER BY e.t")
id | kind | queued | delivered
e1 | listed | NULL | NULL
e2 | opened | 1 | 0
e3 | callback | 1 | 1
e4 | connected | 1 | 1
7
show(db,"SELECT event FROM notification WHERE queued=1 AND delivered=0")
event
e2

演習完了