snort-rule 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 983c58cf46f3b4d8c65327fa4bedcc2e1edebe93
4
- data.tar.gz: 45fbd8510d45346efd45603d3b350b1034b556e3
3
+ metadata.gz: 29dd2030dcab15c7a79fe409f387f365833d6ef9
4
+ data.tar.gz: c000e78ab850620360e3cf169a6675081b43f067
5
5
  SHA512:
6
- metadata.gz: dca88327fc2206fe1f8067665815b535d9d2624ddcee0e4a4a4c6e03ffc276a0cc93a1a0b6177c8c73209abe099177abfe4aa888742345302391368fc3f34927
7
- data.tar.gz: c6eb769c685cddc3c6195fb27f9b1d40d7cb547083e0d5932c9179986216a90c9bc8d91a642f38d07d79f0fa2f69799c356a3951c5d63ad727afee125e7920ef
6
+ metadata.gz: 719fa4d1026c38c683d06364c16c930be551c3dca3fe4b67493e23d6f33d52125a5d74bd9e05cb0b2528469792cac3e3cdcd70dcd0a29eb38b15d566879b5d27
7
+ data.tar.gz: 9158d07dc87858e5179bb6355f8b3e285645db5c65e14bf2e8f1ec6bf82a46ce669abe9c38cc59f7ddcc1f7a125bbe282b10f788d1ecb50f11ba38c905910f81
data/README.md CHANGED
@@ -19,9 +19,9 @@ Or install it yourself as:
19
19
  ## Usage
20
20
 
21
21
  require 'snort/rule'
22
- rule = Snort::Rule.new({:enabled => true, :action => 'pass', :proto => 'udp', :src => '192.168.0.1', :sport => 'any', :dir => '<>', :dst => 'any', :dport => 53, :opts => {'sid' => 48, 'threshold' => 'type limit,track by_src,count 1,seconds 3600' }})
22
+ rule = Snort::Rule.new({:enabled => true, :action => 'pass', :proto => 'udp', :src => '192.168.0.1', :sport => 'any', :dir => '<>', :dst => 'any', :dport => 53, :options => {'sid' => 48, 'threshold' => 'type limit,track by_src,count 1,seconds 3600' }})
23
23
 
24
- rule.to_s => "pass udp 192.168.0.1 any <> any 53 ( sid:48; threshold:type limit,track by_src,count 1,seconds 3600; )"
24
+ rule.to_s # => "pass udp 192.168.0.1 any <> any 53 ( sid:48; threshold:type limit,track by_src,count 1,seconds 3600; )"
25
25
 
26
26
  rule = Snort::Rule.new
27
27
  rule.enabled = false
@@ -30,21 +30,22 @@ Or install it yourself as:
30
30
  rule.src = '192.168.0.1'
31
31
  rule.dir = '<>'
32
32
  rule.dport = 53
33
- rule.options << Snort::RuleOption.new('sid', 48)
34
- rule.options << Snort::RuleOption.new('threshold', 'type limit,track by_src,count 1,seconds 3600')
35
- rule.options << Snort::RuleOption.new('ref', 'ref1')
36
- rule.options << Snort::RuleOption.new('ref', 'ref2')
33
+ rule.add_option(Snort::RuleOption.new('sid', 48))
34
+ rule.add_option(Snort::RuleOption.new('threshold', 'type limit,track by_src,count 1,seconds 3600'))
35
+ rule.add_option(Snort::RuleOption.new('ref', 'ref1'))
36
+ rule.add_option(Snort::RuleOption.new('ref', ['ref2', 'nocase']))
37
37
  rule.options.each do |opt|
38
38
  puts opt
39
39
  end
40
- rule.options_hash["sid"] == 48
41
- rule.options_hash["ref"] == "ref2"
40
+ rule.options_hash["sid"][0].arguments[0] # => 48
41
+ rule.options_hash["ref"][1].arguments[0] # => "ref2"
42
+ rule.options_hash["ref"][1].arguments[1] # => "nocase"
42
43
 
43
44
  # if the rule is disabled, then it will begin with a #
44
- rule.to_s => "#pass udp 192.168.0.1 any <> any 53 ( sid:48; threshold:type limit,track by_src,count 1,seconds 3600; )"
45
+ rule.to_s # => #pass udp 192.168.0.1 any <> any 53 (sid:48; threshold:type limit,track by_src,count 1,seconds 3600; sid:48; threshold:type limit,track by_src,count 1,seconds 3600; ref:ref1; ref:ref2; nocase;)"
45
46
 
46
- 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; )")
47
- rule.to_s => "pass udp 192.168.0.1 any <> any 53 ( sid:48; threshold:type limit,track by_src,count 1,seconds 3600; )"
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
+ 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;)"
48
49
 
49
50
  ## Contributing
50
51
 
@@ -5,6 +5,7 @@ require "snort/rule/option"
5
5
  # Authors:: Chris Lee (mailto:rubygems@chrislee.dhs.org),
6
6
  # Will Green (will[ at ]hotgazpacho[ dot ]org),
7
7
  # Justin Knox (jknox[ at ]indexzero[ dot ]org)
8
+ # Ryan Barnett (rbarnett[ at ]modsecurity[ dot ]org)
8
9
  # Copyright:: Copyright (c) 2011 Chris Lee
9
10
  # License:: Distributes under the same terms as Ruby
10
11
  module Snort
@@ -13,7 +14,7 @@ module Snort
13
14
  class Rule
14
15
  attr_accessor :enabled, :action, :proto, :src, :sport, :dir, :dst, :dport, :options_hash
15
16
  attr_reader :options
16
-
17
+
17
18
  # Initializes the Rule
18
19
  # @param [Hash] kwargs The options to initialize the Rule with
19
20
  # @option kwargs [String] :enabled true or false
@@ -38,8 +39,13 @@ module Snort
38
39
  @dir = kwargs[:dir] || '->'
39
40
  @dst = kwargs[:dst] || 'any'
40
41
  @dport = kwargs[:dport] || 'any'
41
- @options = kwargs[:options] || []
42
- @options_hash = Hash[@options.map {|x| [x.keyword, x.arguments]}]
42
+ @options = []
43
+ @options_hash = {}
44
+ if kwargs[:options]
45
+ kwargs[:options].each do |opt|
46
+ add_option(opt)
47
+ end
48
+ end
43
49
  end
44
50
 
45
51
  # Output the current object into a snort rule
@@ -58,13 +64,21 @@ module Snort
58
64
  end
59
65
 
60
66
  def add_option(option)
67
+ if option.class == Array
68
+ option = Snort::RuleOption.new(option[0], option[1,100])
69
+ end
61
70
  @options << option
62
- @options_hash = Hash[@options.map {|x| [x.keyword, x.arguments]}]
71
+ unless @options_hash[option.keyword]
72
+ @options_hash[option.keyword] = []
73
+ end
74
+ @options_hash[option.keyword] << option
63
75
  end
64
76
 
65
77
  def del_option(option)
66
78
  @options.delete(option)
67
- @options_hash = Hash[@options.map {|x| [x.keyword, x.arguments]}]
79
+ if @options_hash[option.keyword]
80
+ @options_hash[option.keyword].delete(option)
81
+ end
68
82
  end
69
83
 
70
84
  def clear_options()
@@ -89,12 +103,17 @@ module Snort
89
103
  end
90
104
  optspart.gsub(/;\s*\).*$/,'').split(/\s*;\s*/).each do |x|
91
105
  if x =~ /(.*?):(.*)/
92
- rule.options << Snort::RuleOption.new(*x.split(/:/,2))
106
+ k, v = x.split(/:/, 2)
107
+ opt = Snort::RuleOption.new(k, v)
108
+ rule.options << opt
109
+ unless rule.options_hash[k]
110
+ rule.options_hash[k] = []
111
+ end
112
+ rule.options_hash[k] << opt
93
113
  else
94
- rule.options << Snort::RuleOption.new(x)
114
+ rule.options.last.arguments << x
95
115
  end
96
116
  end if optspart
97
- rule.options_hash = Hash[rule.options.map {|x| [x.keyword, x.arguments]}]
98
117
  rule
99
118
  end
100
119
  end
@@ -7,12 +7,24 @@ module Snort
7
7
  # @param [String] arguments
8
8
  def initialize(keyword, arguments=nil)
9
9
  @keyword = keyword.to_s
10
- @arguments = arguments.to_s
10
+ if arguments == nil
11
+ @arguments = []
12
+ elsif arguments.class == String or arguments.class == Fixnum
13
+ @arguments = [arguments]
14
+ elsif arguments.class == Array
15
+ @arguments = arguments
16
+ else
17
+ raise "I don't know what to do with an argument of class #{arguments.class}"
18
+ end
19
+ end
20
+
21
+ def add_argument(argument)
22
+ @arguments << argument
11
23
  end
12
24
 
13
25
  def to_s
14
- return "#{@keyword};" if @arguments.empty?
15
- "#{@keyword}:#{@arguments};"
26
+ return "#{@keyword};" if @arguments.length == 0
27
+ "#{@keyword}:#{@arguments.join("; ")};"
16
28
  end
17
29
 
18
30
  def ==(other)
@@ -1,5 +1,5 @@
1
1
  module Snort
2
2
  class Rule
3
- VERSION = "1.2.0"
3
+ VERSION = "1.3.0"
4
4
  end
5
5
  end
@@ -38,15 +38,24 @@ class TestSnortRuleOption < Minitest::Test
38
38
  end
39
39
 
40
40
  def test_options_hash
41
- strule = 'alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"test"; flow:to_server, established; content:"GET"; http_method; content:"/private.php?"; nocase; http_uri; content:"id="; nocase; http_uri; content:"UNITED"; nocase; http_uri; content:"SELECTED"; nocase; http_uri; pcre:"/UNITED.+SELECTED/Ui"; reference:ref1; reference:ref2; reference:ref3; classtype:test-attack; sid:1234; rev:442;)'
41
+ strule = 'alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"test"; ' +
42
+ 'flow:to_server, established; '+
43
+ 'content:"GET"; http_method; ' +
44
+ 'content:"/private.php?"; nocase; http_uri; ' +
45
+ 'content:"id="; nocase; http_uri; ' +
46
+ 'content:"UNITED"; nocase; http_uri; ' +
47
+ 'content:"SELECTED"; nocase; http_uri; ' +
48
+ 'pcre:"/UNITED.+SELECTED/Ui"; ' +
49
+ 'reference:ref1; reference:ref2; reference:ref3; ' +
50
+ 'classtype:test-attack; sid:1234; rev:442;)'
42
51
  rule = Snort::Rule.parse(strule)
43
- assert_equal "\"test\"", rule.options_hash["msg"]
44
- assert_equal "to_server, established", rule.options_hash["flow"]
45
- assert rule.options_hash["http_method"]
46
- assert rule.options_hash["http_method"].empty?
47
- assert_equal "ref3", rule.options_hash["reference"]
48
- assert rule.options_hash["nocase"]
49
- assert rule.options_hash["nocase"].empty?
52
+ assert_equal ["\"test\""], rule.options_hash["msg"][0].arguments
53
+ assert_equal ["to_server, established"], rule.options_hash["flow"][0].arguments
54
+ assert rule.options_hash["content"]
55
+ assert_equal 5, rule.options_hash["content"].length
56
+ assert_equal ['"/private.php?"', 'nocase', 'http_uri'], rule.options_hash["content"][1].arguments
57
+ assert_equal 3, rule.options_hash["reference"].length
58
+ assert_equal ["ref3"], rule.options_hash["reference"][2].arguments
50
59
  assert_nil rule.options_hash["xxxx"]
51
60
  end
52
61
 
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.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - chrislee35
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-25 00:00:00.000000000 Z
11
+ date: 2014-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler