IOCの種類と照合方法
同じIPを複数の名前が使う固定資料で、文字列の一致から期間を含む照合へ進みます。期限を過ぎた指標や同じ共有基盤の別サービスを、確定した侵害と扱わない方法を学びます。
説明
IOCは調査の手掛かりとなる指標です。IPアドレス、ドメイン、ファイルハッシュでは一致の意味が異なり、情報源が指標を有効とした期間も確認する必要があります。
同じIPを複数の名前が使う固定資料で、文字列の一致から期間を含む照合へ進みます。期限を過ぎた指標や同じ共有基盤の別サービスを、確定した侵害と扱わない方法を学びます。
1指標の種類と期間を読む
start以上end未満をこの指標一覧の有効期間とします。confidenceは提供元の評価で、確率とは限りません。
from oplab import *
db=connect(9)
show(db, 'SELECT指標の種類と期間を読む * FROM ioc ORDER BY id')IP、ドメイン、ハッシュの指標があり、期間と評価も異なります。h7は説明用に短縮したハッシュ識別子です。
2値だけの一致を検索する
種類も合わせて、文字列として一致する観測を出します。
show(db, 'SELECT値だけの一致を検索する s.id,i.id,s.t,i.start,i.end FROM seen s JOIN ioc i ON s.type=i.type AND s.value=i.value ORDER BY s.id')5件が一致しますが、e2とe5は有効期間外です。古い指標を現在の評価にそのまま使うと意味が変わります。
3有効期間を条件に加える
観測時刻が指標の期間に入るものを残します。
show(db, 'SELECT有効期間を条件に加える s.id,i.id,s.type,s.host FROM seen s JOIN ioc i ON s.type=i.type AND s.value=i.value AND s.t>=i.start AND s.t<i.end ORDER BY s.id')e1、e3、e4の3件です。期間内の一致でも、それぞれの指標が何を示すかを確認します。
4同じIPを共有する名前を調べる
IPの一致を、そのまま一つのドメインへの接続と解釈しないための確認です。
show(db, 'SELECT同じIPを共有する名前を調べる * FROM hosting WHERE ip="203.0.113.7" ORDER BY name')二つの名前が同じIPを使っています。IP単独の一致は、接続先サービスを特定する根拠としては不足します。
5同じ端末の別種の指標を確認する
ws7で観測したドメインとファイルも並べます。
show(db, 'SELECT同じ端末の別種の指標を確認する id,type,value FROM seen WHERE host="ws7" ORDER BY id')IPだけでなく名前とハッシュが一致しています。ただし、ファイルが存在したことと実行されたことは別の事実です。
6情報源の根拠をたどる
指標提供元の説明を対応付けます。
show(db, 'SELECT情報源の根拠をたどる i.id,i.type,i.confidence,s.kind,s.basis FROM ioc i JOIN sources s ON i.source=s.id ORDER BY i.id')観測済みの基盤、未確認報告、ファイル解析では根拠が違います。一致件数を足すだけで確信度を数値化しないようにします。
まとめ
観測済みの基盤、未確認報告、ファイル解析では根拠が違います。一致件数を足すだけで確信度を数値化しないようにします。
表示された証拠IDと検索条件を残すと、調査結果を元の記録までたどれます。
操作履歴と解説を振り返れます。
Python 3.15 / SQLite・固定の調査記録
from oplab import *
db=connect(9)
show(db, 'SELECT * FROM ioc ORDER BY id')id | type | value | start | end | source | confidence i1 | ip | 203.0.113.7 | 10 | 30 | feed-a | 60 i2 | domain | files.example.test | 10 | 30 | feed-a | 70 i3 | sha256 | h7 | 10 | 100 | sample-analysis | 90 i4 | ip | 203.0.113.8 | 0 | 10 | feed-b | 40
show(db, 'SELECT s.id,i.id,s.t,i.start,i.end FROM seen s JOIN ioc i ON s.type=i.type AND s.value=i.value ORDER BY s.id')id | id | t | start | end e1 | i1 | 20 | 10 | 30 e2 | i1 | 40 | 10 | 30 e3 | i2 | 20 | 10 | 30 e4 | i3 | 20 | 10 | 100 e5 | i4 | 20 | 0 | 10
show(db, 'SELECT s.id,i.id,s.type,s.host FROM seen s JOIN ioc i ON s.type=i.type AND s.value=i.value AND s.t>=i.start AND s.t<i.end ORDER BY s.id')id | id | type | host e1 | i1 | ip | ws7 e3 | i2 | domain | ws7 e4 | i3 | sha256 | ws7
show(db, 'SELECT * FROM hosting WHERE ip="203.0.113.7" ORDER BY name')ip | name 203.0.113.7 | files.example.test 203.0.113.7 | other.example.test
show(db, 'SELECT id,type,value FROM seen WHERE host="ws7" ORDER BY id')id | type | value e1 | ip | 203.0.113.7 e3 | domain | files.example.test e4 | sha256 | h7
show(db, 'SELECT i.id,i.type,i.confidence,s.kind,s.basis FROM ioc i JOIN sources s ON i.source=s.id ORDER BY i.id')id | type | confidence | kind | basis i1 | ip | 60 | external | observed infrastructure i2 | domain | 70 | external | observed infrastructure i3 | sha256 | 90 | internal | file hash calculation i4 | ip | 40 | external | unconfirmed report
演習完了