一覧SP-04-2 · IDS・IPS:通信内容の検知

IDS・IPSの通知条件と通信制御

パケット、解析したHTTP、通知、配送の証拠をそれぞれ照合します。

説明

通知件数は、条件への一致回数や破棄したパケット数と同じとは限りません。通知を抑制する設定、ルールのaction、実行モードを分けて確認する必要があります。

同じpcapをalert・drop・rejectと通知閾値付きルールで解析した結果を読みます。オフライン解析の結果から確認できることと、配送先での観測が必要なことを整理します。

パケット、解析したHTTP、通知、配送の証拠をそれぞれ照合します。

1比較するルールを表示する

URI条件は同じで、先頭のactionだけが異なります。

from sp04 import * for name in ('alert','drop','reject'): print((ROOT比較するルールを表示する/(name+'.rules')).read_text(),end='')

alertは通知、dropはIPSでの破棄、rejectは拒否応答を伴う措置を指定します。実際の効果には実行モードと経路が関わります。

2alertの通知結果を確認する

読み込んだpcapはすべて同じです。

print(alertsalertの通知結果を確認する('split-alert'))

actionはallowedです。検知したことと通信を止めたことを同一に扱いません。

3dropをオフライン解析で評価した結果を見る

この実行はpcapの読込みです。

print(alertsdropをオフライン解析で評価した結果を見る('split-drop'))

この条件ではallowedと出ています。dropという規則の文字だけで、実通信の配送を阻止したとは判断できません。

4rejectの結果と観測範囲を確認する

同じpcapにrejectを指定した出力です。

print(alertsrejectの結果と観測範囲を確認する('split-reject')) print(http('split-reject'))

actionはblockedですが、読み込んだファイル内のHTTP記録は残ります。オフラインのblocked表示は、端末に拒否応答が届いた証拠ではありません。

52回一致して通知する規則を開く

閾値は送信元ごと、60秒で2回です。

print((ROOT/'threshold.rules').read_text(),end='') print(alerts2回一致して通知する規則を開く('split-threshold'))

1回だけの試料では通知が出ません。これはthreshold type thresholdの条件です。遮断actionの実行回数をこの通知件数から数えることはできません。

6通知がなくてもHTTP解析が残ることを確認する

閾値付きルールのHTTP記録を調べます。

print(http通知がなくてもHTTP解析が残ることを確認する('split-threshold')) print([x['event_type'] for x in RESULTS['split-threshold']])

/lessonは解析されています。通知抑制を、通信を観測できなかったことと取り違えないようにします。

7配送の確認に必要な項目を洗い出す

今回のEVE記録に含まれる種類をまとめます。

print(sorted配送の確認に必要な項目を洗い出す({x['event_type'] for v in RESULTS.values() for x in v}))

alert、flow、httpの解析記録です。実経路での阻止を確かめるときは、送信側の結果、経路上のパケット、受信側への到達も同じ通信で照合します。

まとめ

通知閾値と通信への措置を別々に確認します。

ルールのactionと実行モードを照合します。

阻止の成否は配送先の観測も使って判断します。

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

Suricata 7.0.10のpcap解析結果 / Python 3.15

1
from sp04 import * for name in ('alert','drop','reject'): print((ROOT/(name+'.rules')).read_text(),end='')
alert http any any -> any any (msg:"Lbox lesson URI"; flow:established,to_server; http.uri; content:"/lesson"; sid:1000001; rev:1;)
drop http any any -> any any (msg:"Lbox lesson URI"; flow:established,to_server; http.uri; content:"/lesson"; sid:1000001; rev:1;)
reject http any any -> any any (msg:"Lbox lesson URI"; flow:established,to_server; http.uri; content:"/lesson"; sid:1000001; rev:1;)
2
print(alerts('split-alert'))
[(1000001, 'allowed')]
3
print(alerts('split-drop'))
[(1000001, 'allowed')]
4
print(alerts('split-reject')) print(http('split-reject'))
[(1000001, 'blocked')]
[('GET', 'demo.example.test', '/lesson')]
5
print((ROOT/'threshold.rules').read_text(),end='') print(alerts('split-threshold'))
alert http any any -> any any (msg:"Lbox lesson URI"; flow:established,to_server; http.uri; content:"/lesson"; threshold:type threshold, track by_src, count 2, seconds 60; sid:1000001; rev:1;)
[]
6
print(http('split-threshold')) print([x['event_type'] for x in RESULTS['split-threshold']])
[('GET', 'demo.example.test', '/lesson')]
['http', 'flow']
7
print(sorted({x['event_type'] for v in RESULTS.values() for x in v}))
['alert', 'flow', 'http']

演習完了