snort-rule 1.4.1 → 1.5.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2eabb911b41cd33e776dd69cc3f50ba807ccaf8
4
- data.tar.gz: 7bfa5b2a310dc398d362991c6cecd7b1c72fb022
3
+ metadata.gz: b475f0c004d1ff722c739e102fc44b8de4ae57b0
4
+ data.tar.gz: 16ceb5394563f2d3c6cbde7ed83c7e5a733cfbaf
5
5
  SHA512:
6
- metadata.gz: dc95c1a7217f9d624cb887e53a7a1f8bcc0d710a617863f1d484259edec11423033005e4082547e823489bcd0fe4eb8d999dfce13236c6e566b59ca3d639095e
7
- data.tar.gz: fb1d93af758a6485bf2ae7a39509f4c117325c0b15c7820d891301450dd9c23223f325437993fd6a1d49c4b2c1098ea8b1c3ec38bfab466f249da99a4ca0c036
6
+ metadata.gz: d3d74558797835687eb71aa1cb662a89f3d634e063c977bfc9829fc1a28e378e6060b13b281de97069decfe3632e427d2be215d65e3694899d103817fbe70cde
7
+ data.tar.gz: e9a47d83b028989f5cb91900acad0fb10f162984b9e44fd6c5f3139885719cf358b53e4a97b0a993937e6314944d790bd362576f01d963e794b776e7154cc322
data/README.md CHANGED
@@ -47,6 +47,48 @@ Or install it yourself as:
47
47
  rule = Snort::Rule.parse("pass udp 192.168.0.1 any <> any 53 ( sid:48; threshold:type limit,track by_src,count 1,seconds 3600; ref:ref1; ref:ref2;)")
48
48
  rule.to_s # => "pass udp 192.168.0.1 any <> any 53 (sid:48; threshold:type limit,track by_src,count 1,seconds 3600; ref:ref1; ref:ref2;)"
49
49
 
50
+ ## Snort::RuleSet Usage
51
+
52
+ require 'snort/ruleset'
53
+ ruleset = Snort::RuleSet::from_file("community.rules")
54
+ ruleset.length # => 3127
55
+ rules.length
56
+ rules.count{|r| ! r.enabled} # => 2522
57
+ rules.count{|r| r.enabled} # => 605
58
+ rules.disable_all
59
+ rules.count{|r| r.enabled} # => 0
60
+ rules.count{|r| ! r.enabled} # => 3127
61
+ rules.enable_all
62
+ rules.count{|r| r.enabled} # => 3127
63
+ rules.count{|r| ! r.enabled} # => 0
64
+ rules.disable do |r|
65
+ r.get_option_first("msg").match(/^"MALWARE\-CNC/)
66
+ end
67
+ rules.count{|r| ! r.enabled} # => 392
68
+ rules.count{|r| r.enabled} # => 2735
69
+ rules.delete do |r|
70
+ options = r.get_options("content")
71
+ if options
72
+ options.find { |o|
73
+ o.arguments.find { |a|
74
+ a.match(/"POST"/)
75
+ }
76
+ }
77
+ else
78
+ nil
79
+ end
80
+ end
81
+ rules.count{|r| ! r.enabled} # => 343
82
+ rules.count{|r| r.enabled} # 2726
83
+ rules.delete_all
84
+ rules.length # => 0
85
+ rules.count{|r| r.enabled} # => 0
86
+ rules.count{|r| ! r.enabled} # => 0
87
+
88
+ ruleset = Snort::RuleSet::from_file("community.rules")
89
+ ruleset.to_file("new_community.rules")
90
+
91
+
50
92
  ## Contributing
51
93
 
52
94
  1. Fork it
@@ -1,6 +1,5 @@
1
1
  require "snort/rule/version"
2
2
  require "snort/rule/option"
3
- require 'pp'
4
3
  # Generates and parses snort rules
5
4
  #
6
5
  # Authors:: Chris Lee (mailto:rubygems@chrislee.dhs.org),
@@ -10,6 +9,22 @@ require 'pp'
10
9
  # Copyright:: Copyright (c) 2011 Chris Lee
11
10
  # License:: Distributes under the same terms as Ruby
12
11
  module Snort
12
+
13
+ class Comment
14
+ def initialize(comment)
15
+ @comment = comment
16
+ end
17
+
18
+ def to_s
19
+ @comment
20
+ end
21
+
22
+ def enable
23
+ end
24
+
25
+ def disable
26
+ end
27
+ end
13
28
 
14
29
  # This class stores and generates the features of a snort rule
15
30
  class Rule
@@ -64,6 +79,14 @@ module Snort
64
79
  rule
65
80
  end
66
81
 
82
+ def enable
83
+ @enabled = true
84
+ end
85
+
86
+ def disable
87
+ @enabled = false
88
+ end
89
+
67
90
  def add_option(option)
68
91
  if option.class == Array
69
92
  option = Snort::RuleOption.new(option[0], option[1,100])
@@ -97,6 +120,10 @@ module Snort
97
120
  end
98
121
  nil
99
122
  end
123
+
124
+ def get_options(option_name)
125
+ @options_hash[option_name]
126
+ end
100
127
 
101
128
  def get_option_first(option_name)
102
129
  if @options_hash[option_name]
@@ -1,5 +1,5 @@
1
1
  module Snort
2
2
  class Rule
3
- VERSION = "1.4.1"
3
+ VERSION = "1.5.2"
4
4
  end
5
5
  end
@@ -0,0 +1,165 @@
1
+ require "snort/rule/version"
2
+ require "open-uri"
3
+
4
+ # Generates and parses snort rules
5
+ #
6
+ # Authors:: Chris Lee (mailto:rubygems@chrislee.dhs.org),
7
+ # Will Green (will[ at ]hotgazpacho[ dot ]org),
8
+ # Justin Knox (jknox[ at ]indexzero[ dot ]org)
9
+ # Ryan Barnett (rbarnett[ at ]modsecurity[ dot ]org)
10
+ # Copyright:: Copyright (c) 2011 Chris Lee
11
+ # License:: Distributes under the same terms as Ruby
12
+ module Snort
13
+ # This class stores a set of rules and allows actions against them
14
+ class RuleSet
15
+
16
+ def RuleSet::from_file(file)
17
+ if file.class == File
18
+ fh = file
19
+ else
20
+ fh = open(file.to_s, 'r')
21
+ end
22
+ RuleSet::from_filehandle(fh)
23
+ end
24
+
25
+ def RuleSet::from_url(url)
26
+ RuleSet::from_file(url)
27
+ end
28
+
29
+ def RuleSet::from_filehandle(fh)
30
+ rules = RuleSet.new
31
+ fh.each_line do |line|
32
+ if line =~ /(alert|drop|pass|reject|activate|dynamic|activate|sdrop)/
33
+ begin
34
+ rule = Snort::Rule.parse(line)
35
+ if rule
36
+ rules << rule
37
+ else
38
+ rules << Snort::Comment.new(line.strip)
39
+ end
40
+ rescue ArgumentError => e
41
+ rescue NoMethodError => e
42
+ end
43
+ else
44
+ rules << Snort::Comment.new(line.strip)
45
+ end
46
+ end
47
+ rules
48
+ end
49
+
50
+ def to_filehandle(fh)
51
+ @ruleset.each do |rule|
52
+ fh.puts rule.to_s
53
+ end
54
+ end
55
+
56
+ def to_file(file)
57
+ i_opened_it = false
58
+ if file.class == File
59
+ fh = file
60
+ else
61
+ i_opened_it = true
62
+ fh = open(file.to_s, 'w')
63
+ end
64
+ to_filehandle(fh)
65
+ if i_opened_it
66
+ fh.close
67
+ end
68
+ end
69
+
70
+ def initialize(ruleset=[])
71
+ @ruleset = ruleset
72
+ end
73
+
74
+ def <<(rule)
75
+ @ruleset << rule
76
+ end
77
+
78
+ def -(rule)
79
+ @ruleset -= rule
80
+ end
81
+
82
+ def length
83
+ @ruleset.find_all {|r| r.class == Snort::Rule}.length
84
+ end
85
+
86
+ def count(&block)
87
+ @ruleset.find_all {|r| r.class == Snort::Rule}.count(&block)
88
+ end
89
+
90
+ def enable(&block)
91
+ count = 0
92
+ @ruleset.find_all {|r| r.class == Snort::Rule}.each do |rule|
93
+ if block.call(rule)
94
+ rule.enable
95
+ count += 1
96
+ end
97
+ end
98
+ count
99
+ end
100
+
101
+ def disable(&block)
102
+ count = 0
103
+ @ruleset.find_all {|r| r.class == Snort::Rule}.each do |rule|
104
+ if block.call(rule)
105
+ rule.disable
106
+ count += 1
107
+ end
108
+ end
109
+ count
110
+ end
111
+
112
+ def delete(&block)
113
+ len = @ruleset.length
114
+ @ruleset.each do |rule|
115
+ next if rule.class == Snort::Comment
116
+ if block.call(rule)
117
+ @ruleset -= [rule]
118
+ end
119
+ end
120
+ len - @ruleset.length
121
+ end
122
+
123
+ def enable_all
124
+ enable do |r|
125
+ true
126
+ end
127
+ end
128
+
129
+ def disable_all
130
+ disable do |r|
131
+ true
132
+ end
133
+ end
134
+
135
+ def delete_all
136
+ delete do |r|
137
+ true
138
+ end
139
+ end
140
+
141
+ def enable_by_name(name)
142
+ enable do |r|
143
+ if r.name =~ name
144
+ true
145
+ end
146
+ end
147
+ end
148
+
149
+ def disable_by_name(name)
150
+ disable do |r|
151
+ if r.name =~ name
152
+ true
153
+ end
154
+ end
155
+ end
156
+
157
+ def delete_by_name(name)
158
+ delete do |r|
159
+ if r.name =~ name
160
+ true
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -3,3 +3,4 @@ gem 'minitest'
3
3
  require 'minitest/autorun'
4
4
  require 'minitest/pride'
5
5
  require File.expand_path('../../lib/snort/rule.rb', __FILE__)
6
+ require File.expand_path('../../lib/snort/ruleset.rb', __FILE__)
@@ -7,6 +7,7 @@ unless Kernel.respond_to?(:require_relative)
7
7
  end
8
8
 
9
9
  require_relative 'helper'
10
+ require 'pp'
10
11
 
11
12
  class TestSnortCommunityRules < Minitest::Test
12
13
  def setup
@@ -45,20 +46,69 @@ class TestSnortCommunityRules < Minitest::Test
45
46
  end
46
47
 
47
48
  def test_complete_rules_file
48
- rules = []
49
- File.open("test/community-rules/community.rules").each_line do |line|
50
- next unless line =~ /alert/
51
- begin
52
- rule = Snort::Rule.parse(line)
53
- if rule
54
- rules << rule
55
- end
56
- rescue ArgumentError => e
57
- rescue NoMethodError => e
49
+ rules = Snort::RuleSet::from_file("test/community-rules/community.rules")
50
+ assert_equal 3127, rules.length
51
+ assert_equal 2522, rules.count{|r| ! r.enabled}
52
+ assert_equal 605, rules.count{|r| r.enabled}
53
+ rules.disable_all
54
+ assert_equal 0, rules.count{|r| r.enabled}
55
+ assert_equal 3127, rules.count{|r| ! r.enabled}
56
+ rules.enable_all
57
+ assert_equal 3127, rules.count{|r| r.enabled}
58
+ assert_equal 0, rules.count{|r| ! r.enabled}
59
+ rules.disable do |r|
60
+ r.get_option_first("msg").match(/^"MALWARE\-CNC/)
61
+ end
62
+ assert_equal 392, rules.count{|r| ! r.enabled}
63
+ assert_equal 2735, rules.count{|r| r.enabled}
64
+ rules.delete do |r|
65
+ options = r.get_options("content")
66
+ if options
67
+ options.find { |o|
68
+ o.arguments.find { |a|
69
+ a.match(/"POST"/)
70
+ }
71
+ }
72
+ else
73
+ nil
58
74
  end
59
75
  end
76
+ assert_equal 343, rules.count{|r| ! r.enabled}
77
+ assert_equal 2726, rules.count{|r| r.enabled}
78
+ rules.delete_all
79
+ assert_equal 0, rules.length
80
+ assert_equal 0, rules.count{|r| r.enabled}
81
+ assert_equal 0, rules.count{|r| ! r.enabled}
82
+ end
83
+
84
+ # def test_ruleset_load_from_url
85
+ # rules = Snort::RuleSet::from_file("http://test.com/community.rules")
86
+ # assert_equal 3127, rules.length
87
+ # assert_equal 2522, rules.count{|r| ! r.enabled}
88
+ # assert_equal 605, rules.count{|r| r.enabled}
89
+ # end
90
+
91
+ def test_writing_file
92
+ rules = Snort::RuleSet::from_file("test/community-rules/community.rules")
60
93
  assert_equal 3127, rules.length
61
94
  assert_equal 2522, rules.count{|r| ! r.enabled}
62
95
  assert_equal 605, rules.count{|r| r.enabled}
96
+ rules.to_file("test/community-rules/community.rules.test")
97
+ assert File.exist?("test/community-rules/community.rules.test")
98
+ total = enabled = disabled = 0
99
+ open("test/community-rules/community.rules.test", 'r').each_line do |l|
100
+ if l =~ /^(#)?\s*(alert|drop|pass|reject|activate|dynamic|activate|sdrop)/
101
+ total += 1
102
+ if l =~ /^#/
103
+ disabled += 1
104
+ else
105
+ enabled += 1
106
+ end
107
+ end
108
+ end
109
+ assert_equal 3127, total
110
+ assert_equal 2522, disabled
111
+ assert_equal 605, enabled
63
112
  end
113
+
64
114
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snort-rule
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - chrislee35
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-22 00:00:00.000000000 Z
11
+ date: 2014-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -84,6 +84,7 @@ files:
84
84
  - lib/snort/rule.rb
85
85
  - lib/snort/rule/option.rb
86
86
  - lib/snort/rule/version.rb
87
+ - lib/snort/ruleset.rb
87
88
  - snort-rule.gemspec
88
89
  - test/helper.rb
89
90
  - test/test_snort-community-rules.rb