logstash-filter-empowclassifier 0.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,88 @@
1
+ require_relative '../spec_helper'
2
+ require "logstash/filters/center-client"
3
+ require "logstash/filters/response"
4
+ require 'webmock/rspec'
5
+
6
+ describe LogStash::Filters::Empow::ClassificationCenterClient do
7
+
8
+ # before(:each) do
9
+ # local_classifier = instance_double(LogStash::Filters::Empow::LocalClassifier)
10
+ # allow(LogStash::Filters::Empow::LocalClassifier).to receive(:new).and_return(local_classifier)
11
+ # end
12
+
13
+ let(:url_base) { 'http://localhost:5000' }
14
+ let(:username) { 'myuser' }
15
+ let(:password) { 'mypassword' }
16
+ let(:pool_id) { 'mypassword' }
17
+
18
+ describe "classification center api" do
19
+ before(:each) do
20
+ WebMock.disable_net_connect!
21
+
22
+ stub_request(:post, "#{url_base}/login").
23
+ to_return(:body => "", :status => 200,
24
+ :headers => { 'authorization' => 'Bearer my-token' })
25
+
26
+ mocked_cognito = double(LogStash::Filters::Empow::CognitoClient)
27
+ allow(LogStash::Filters::Empow::CognitoClient).to receive(:new).and_return(mocked_cognito)
28
+ allow(mocked_cognito).to receive(:authenticate).and_return("dummy token")
29
+ end
30
+
31
+ after(:each) do
32
+ WebMock.reset!
33
+ WebMock.allow_net_connect!
34
+
35
+ allow(LogStash::Filters::Empow::CognitoClient).to receive(:new).and_call_original
36
+ end
37
+
38
+
39
+ it "test missing ids request" do
40
+ stub_request(:post, "#{url_base}/classification/intent").
41
+ to_return(:body => "", :status => 204,
42
+ :headers => { 'Content-Length' => 0 })
43
+
44
+ client = described_class.new(username, password, pool_id, url_base)
45
+
46
+ client.authenticate
47
+
48
+ res = client.classify(["req1"])
49
+
50
+ expect(res["req1"]).to be_kind_of(LogStash::Filters::Empow::FailureReponse)
51
+ end
52
+
53
+ it "test existing ids request" do
54
+
55
+ response = '{"some":"data"}'
56
+
57
+ stub_request(:post, "#{url_base}/classification/intent").
58
+ to_return(:body => response, :status => 200)
59
+
60
+ client = described_class.new(username, password, pool_id, url_base)
61
+
62
+ client.authenticate
63
+
64
+ k1 = "req1"
65
+ response_map = client.classify([k1])
66
+
67
+ res = response_map[k1].response
68
+
69
+ p "res: #{res}"
70
+
71
+ expect(res["some"]).to eq("data")
72
+ end
73
+
74
+ it "test http status 500 during request" do
75
+
76
+ stub_request(:post, "#{url_base}/classification/intent").
77
+ to_return(:body => "", :status => 500)
78
+
79
+ client = described_class.new(username, password, pool_id, url_base)
80
+
81
+ client.authenticate
82
+
83
+ res = client.classify("ids", "Snort", "1:2", nil)
84
+
85
+ expect(res).to be_nil
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,44 @@
1
+ require_relative '../spec_helper'
2
+ require 'timecop'
3
+ require "logstash/filters/classifier-cache"
4
+
5
+ describe LogStash::Filters::Empow::ClassifierCache do
6
+
7
+ describe "initialize signaure test" do
8
+ it "test expiration by cache default ttl" do
9
+ cache = described_class.new(5, 60)
10
+
11
+ expect(cache.classify("k")).to be_nil
12
+
13
+ Timecop.freeze(Time.now)
14
+
15
+ cache.put("k", "v", Time.now + 24*60*60)
16
+
17
+ Timecop.freeze(Time.now + 59)
18
+
19
+ expect(cache.classify("k")).to eq("v")
20
+
21
+ Timecop.freeze(Time.now + 61)
22
+
23
+ expect(cache.classify("k")).to be_nil
24
+ end
25
+
26
+ it "test expiration by entry ttl" do
27
+ cache = described_class.new(5, 60)
28
+
29
+ expect(cache.classify("k")).to be_nil
30
+
31
+ Timecop.freeze(Time.now)
32
+
33
+ cache.put("k", "v", Time.now + 30)
34
+
35
+ Timecop.freeze(Time.now + 29)
36
+
37
+ expect(cache.classify("k")).to eq("v")
38
+
39
+ Timecop.freeze(Time.now + 31)
40
+
41
+ expect(cache.classify("k")).to be_nil
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,78 @@
1
+ require_relative '../spec_helper'
2
+ require "logstash/filters/classifier"
3
+ require "logstash/filters/local-classifier"
4
+ require "logstash/filters/classification-request"
5
+ require "logstash/filters/center-client"
6
+
7
+ describe LogStash::Filters::Empow::Classifier do
8
+ #empow_user, empow_password, cache_size, ttl, async_local_db, elastic_hosts, elastic_index, elastic_username, elastic_password
9
+ describe "test with mocked classifiers" do
10
+ it "log with no result" do
11
+
12
+ local_classifier = instance_double(LogStash::Filters::Empow::LocalClassifier)
13
+ allow(local_classifier).to receive(:classify).and_return(nil)
14
+ allow(local_classifier).to receive(:close)
15
+
16
+ online_classifer = instance_double(LogStash::Filters::Empow::ClassificationCenterClient)
17
+ allow(online_classifer).to receive(:classify).and_return(nil)
18
+
19
+ req = "request-1"
20
+
21
+ classifier = described_class.new(online_classifer, local_classifier)
22
+
23
+ expect(local_classifier).to receive(:classify).with(req)
24
+
25
+ expect(online_classifer).to receive(:classify)
26
+
27
+ res = classifier.classify(req)
28
+
29
+ sleep 10
30
+
31
+ expect(res).to be_nil
32
+
33
+ classifier.close
34
+ end
35
+
36
+
37
+ it "log w/o results locally, online classification arrives later" do
38
+
39
+ # local_classifier = instance_double(LogStash::Filters::Empow::LocalClassifier)
40
+ # allow(local_classifier).to receive(:classify).and_return(nil)
41
+ # allow(local_classifier).to receive(:close)
42
+
43
+ # online_classifer = instance_double(LogStash::Filters::Empow::ClassificationCenterClient)
44
+ # allow(online_classifer).to receive(:classify).and_return(nil)
45
+
46
+ # req = LogStash::Filters::Empow::ClassificationRequest.new('anti-malware', 'lastline', 'assaf.clicker', nil)
47
+
48
+ # #online_classifer, local_classifier, local_db_cache, async_local_db, online_classifier_threads
49
+ # classifier = described_class.new(online_classifer, local_classifier, nil, true, 1)
50
+
51
+ # expect(local_classifier).to receive(:classify).with(req.get_key_by_term())
52
+ # expect(local_classifier).not_to receive(:classify).with(req.get_key_by_hash())
53
+
54
+ # expect(online_classifer).to receive(:classify)
55
+
56
+ # res = classifier.classify(req)
57
+
58
+ # #allow(Time).to receive(:now).and_return(5555555)
59
+
60
+ # expect(res).to be_nil
61
+
62
+ # sleep 60
63
+
64
+ # i = 20
65
+
66
+ # while i < 0 do
67
+
68
+ # result = classifier.classify(req)
69
+ # p "i: #{i} result: #{result}"
70
+
71
+ # sleep 5
72
+ # i = i - 1
73
+ # end
74
+
75
+ # classifier.close
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,20 @@
1
+ require 'aws-sdk'
2
+ require_relative '../spec_helper'
3
+ require "logstash/filters/cognito-client"
4
+
5
+ describe LogStash::Filters::Empow::CognitoClient do
6
+
7
+ describe "cognito test" do
8
+ skip "test authenticate" do
9
+
10
+ aws_region = 'us-east-2'
11
+ aws_client_id = '8dljcvt4jfif762le0ald6j'
12
+ username = 'bad'
13
+ password = 'request'
14
+
15
+ client = described_class.new(username, password, aws_region, aws_client_id)
16
+
17
+ expect{ client.authenticate }.to raise_error(Aws::CognitoIdentityProvider::Errors::UserNotFoundException)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,44 @@
1
+ # require_relative '../spec_helper'
2
+ # require "logstash/filters/elastic-db"
3
+
4
+ # describe LogStash::Filters::Empow::PersistentKeyValueDB do
5
+
6
+ # let(:user) { 'user' }
7
+ # let(:indexName) { 'key-val-8' }
8
+ # let(:password) { 'pass' }
9
+ # let(:elastic) { '192.168.3.24:9200' }
10
+
11
+ # subject { described_class.new(elastic, user, password, indexName) }
12
+
13
+ # after do
14
+ # subject.close
15
+ # end
16
+
17
+ # describe "initialization" do
18
+ # it "should be successful" do
19
+ # expect { subject }.not_to raise_error
20
+ # end
21
+ # end
22
+
23
+ # describe "read a value that doesn't exists" do
24
+ # it "should return nil" do
25
+ # res = subject.query "ids", "snort", "123:456:789"
26
+ # expect(res).to be_nil
27
+ # end
28
+ # end
29
+
30
+ # describe "write a value then read" do
31
+ # let(:data) { "blob" }
32
+
33
+ # it "write should be successful" do
34
+ # expect { subject.save 1234, "am", "my-product", "not-my-name", 'something else' }.not_to raise_error
35
+ # expect { subject.save 12345, "am", "my-product", "my-name", data }.not_to raise_error
36
+ # sleep(2)
37
+ # end
38
+
39
+ # it "read the new value should succeed" do
40
+ # res = subject.query "am", "my-product", "my-name"
41
+ # expect(res).to eq(data)
42
+ # end
43
+ # end
44
+ # end
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+ require_relative '../spec_helper'
3
+ require "logstash/filters/empowclassifier"
4
+ require "logstash/event"
5
+
6
+ describe LogStash::Filters::EmpowClassifier do
7
+
8
+ before(:each) do
9
+ allow(LogStash::Filters::Empow::LocalClassifier).to receive(:new).and_return(nil)
10
+ allow(LogStash::Filters::Empow::ClassificationCenterClient).to receive(:new).and_return(nil)
11
+ allow(LogStash::Filters::Empow::Classifier).to receive(:new).and_return(nil)
12
+ end
13
+
14
+ describe "config w/o local db and with mocks for online classifier" do
15
+
16
+ it "test empty flush" do
17
+
18
+ plugin_core = instance_double(LogStash::Filters::Empow::PluginLogic)
19
+ allow(LogStash::Filters::Empow::PluginLogic).to receive(:new).and_return(plugin_core)
20
+ allow(plugin_core).to receive(:classify).and_return(nil)
21
+ allow(plugin_core).to receive(:flush).and_return([])
22
+
23
+ empty_config = {}
24
+ subject = described_class.new(empty_config)
25
+ subject.register
26
+
27
+ event = LogStash::Event.new({"data" => "empty"})
28
+
29
+ res = subject.flush({})
30
+
31
+ expect(res).to eq([])
32
+ end
33
+
34
+
35
+ it "2 events filtered w/o an answer on receive, correct event is flushed out" do
36
+
37
+ event = LogStash::Event.new({"data" => 1})
38
+
39
+ plugin_core = instance_double(LogStash::Filters::Empow::PluginLogic)
40
+ allow(LogStash::Filters::Empow::PluginLogic).to receive(:new).and_return(plugin_core)
41
+ allow(plugin_core).to receive(:classify).and_return(nil)
42
+ allow(plugin_core).to receive(:flush).and_return([event])
43
+
44
+ empty_config = {}
45
+ subject = described_class.new(empty_config)
46
+ subject.register
47
+
48
+ expect(plugin_core).to receive(:classify)
49
+
50
+ res = subject.filter(event)
51
+
52
+ expect(res).to be_nil
53
+
54
+ res = subject.flush({})
55
+
56
+ expect(res.length).to eq(1)
57
+ expect(res[0].get("data")).to eq(event.get("data"))
58
+ end
59
+
60
+ it "test answer on filter" do
61
+
62
+ event = LogStash::Event.new({"data" => "empty"})
63
+
64
+ plugin_core = instance_double(LogStash::Filters::Empow::PluginLogic)
65
+ allow(plugin_core).to receive(:classify).and_return(event)
66
+ allow(LogStash::Filters::Empow::PluginLogic).to receive(:new).and_return(plugin_core)
67
+
68
+ empty_config = {}
69
+ subject = described_class.new(empty_config)
70
+ subject.register
71
+
72
+ expect(plugin_core).to receive(:classify)
73
+ expect(subject).to receive(:filter_matched)
74
+
75
+ subject.filter(event)
76
+ end
77
+
78
+ it "test tag on error" do
79
+
80
+ event = instance_double(LogStash::Event)
81
+ allow(event).to receive(:cancel).and_raise("exception")
82
+ allow(event).to receive(:tag)
83
+
84
+ # event = .new({"data" => "empty"})
85
+
86
+ plugin_core = instance_double(LogStash::Filters::Empow::PluginLogic)
87
+ allow(plugin_core).to receive(:classify).and_return(nil)
88
+ allow(LogStash::Filters::Empow::PluginLogic).to receive(:new).and_return(plugin_core)
89
+
90
+ empty_config = {}
91
+ subject = described_class.new(empty_config)
92
+ subject.register
93
+
94
+ expect(plugin_core).to receive(:classify)
95
+ expect(event).to receive(:cancel)
96
+ expect(event).to receive(:tag).with('_empow_classifer_error')
97
+
98
+ res = subject.filter(event)
99
+
100
+ expect(res).to be_nil
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,101 @@
1
+ require_relative '../spec_helper'
2
+ require "logstash/filters/field-handler"
3
+ require "logstash/event"
4
+
5
+ describe LogStash::Filters::Empow::FieldHandler do
6
+
7
+ let(:handler) { described_class.new("product_type", "product", "term", "is_src_internal", "is_dst_internal") }
8
+
9
+ describe "init" do
10
+ it "src internal field empty" do
11
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1"})
12
+ res = handler.event_to_classification_request(event)
13
+ expect(res).not_to be_nil
14
+ expect(res['term']['is_src_internal']).to be true
15
+ expect(event.get("empow_warnings")).to include("src_internal_wrong_value")
16
+ end
17
+
18
+ it "dst internal field empty" do
19
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1"})
20
+ res = handler.event_to_classification_request(event)
21
+ expect(res.nil?).to be false
22
+ expect(res['term']['is_dst_internal']).to be true
23
+ expect(event.get("empow_warnings")).to include("dst_internal_wrong_value")
24
+ end
25
+
26
+ it "src internal field numeric value" do
27
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1", "is_src_internal" => 1})
28
+ res = handler.event_to_classification_request(event)
29
+ expect(res.nil?).to be false
30
+ expect(res['term']['is_src_internal']).to be true
31
+ expect(event.get("empow_warnings")).not_to include("src_internal_wrong_value")
32
+ end
33
+
34
+ it "src internal field wrong value" do
35
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1"}, "is_src_internal" => 11)
36
+ res = handler.event_to_classification_request(event)
37
+ expect(res.nil?).to be false
38
+ expect(res['term']['is_src_internal']).to be true
39
+ expect(event.get("empow_warnings")).to include("src_internal_wrong_value")
40
+ end
41
+
42
+ it "dst internal field numeric value" do
43
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1", "is_dst_internal" => 1})
44
+ res = handler.event_to_classification_request(event)
45
+ expect(res.nil?).to be false
46
+ expect(res['term']['is_dst_internal']).to be true
47
+ expect(event.get("empow_warnings")).not_to include("dst_internal_wrong_value")
48
+ end
49
+
50
+ it "dst internal field wrong numeric value" do
51
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1"}, "is_dst_internal" => 11)
52
+ res = handler.event_to_classification_request(event)
53
+ expect(res.nil?).to be false
54
+ expect(res['term']['is_dst_internal']).to be true
55
+ expect(event.get("empow_warnings")).to include("dst_internal_wrong_value")
56
+ end
57
+
58
+ it "dst internal field wrong value" do
59
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1"}, "is_dst_internal" => [])
60
+ res = handler.event_to_classification_request(event)
61
+ expect(res.nil?).to be false
62
+ expect(res['term']['is_dst_internal']).to be true
63
+ expect(event.get("empow_warnings")).to include("dst_internal_wrong_value")
64
+ end
65
+
66
+ it "src internal field valid values" do
67
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1", "is_src_internal" => true})
68
+ res = handler.event_to_classification_request(event)
69
+ expect(res.nil?).to be false
70
+ expect(res['term']['is_src_internal']).to be true
71
+ expect(event.get("empow_warnings")).not_to include("src_internal_wrong_value")
72
+
73
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1", "is_src_internal" => false})
74
+ res = handler.event_to_classification_request(event)
75
+ expect(res.nil?).to be false
76
+ expect(res['term']['is_src_internal']).to be false
77
+ expect(event.get("empow_warnings")).not_to include("src_internal_wrong_value")
78
+ end
79
+
80
+ it "dst internal field valid values" do
81
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1", "is_dst_internal" => true})
82
+ res = handler.event_to_classification_request(event)
83
+ expect(res.nil?).to be false
84
+ expect(res['term']['is_dst_internal']).to be true
85
+ expect(event.get("empow_warnings")).not_to include("dst_internal_wrong_value")
86
+
87
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "some_av", "term" => {"signature" => "name1", "is_dst_internal" => false})
88
+ res = handler.event_to_classification_request(event)
89
+ expect(res.nil?).to be false
90
+ expect(res['term']['is_dst_internal']).to be false
91
+ expect(event.get("empow_warnings")).not_to include("dst_internal_wrong_value")
92
+ end
93
+
94
+ it "test nested threat structure" do
95
+ my_handler = described_class.new("product_type", "product", 'threat', "is_src_internal", "is_dst_internal")
96
+ event = LogStash::Event.new("product_type" => "IDS", "product" => "snort", "threat" => {"signature" => "name1"})
97
+ res = my_handler.event_to_classification_request(event)
98
+ expect(res['term']['signature']).to eq('name1')
99
+ end
100
+ end
101
+ end