unified2 0.4.0 → 0.5.0
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.
- data/ChangeLog.rdoc +6 -0
- data/LICENSE.txt +1 -1
- data/README.md +72 -0
- data/example/{basic-example.rb → example.rb} +3 -2
- data/example/seeds/{unified2 → unified2.log} +0 -0
- data/gemspec.yml +2 -0
- data/lib/unified2/classification.rb +17 -3
- data/lib/unified2/config_file.rb +34 -10
- data/lib/unified2/constructor/construct.rb +83 -0
- data/lib/unified2/constructor/event_ip4.rb +47 -0
- data/lib/unified2/constructor/event_ip6.rb +44 -0
- data/lib/unified2/constructor/packet.rb +30 -0
- data/lib/unified2/constructor/primitive/ipv4.rb +31 -0
- data/lib/unified2/{primitive.rb → constructor/primitive.rb} +0 -0
- data/lib/unified2/constructor/record_header.rb +17 -0
- data/lib/unified2/constructor.rb +1 -0
- data/lib/unified2/core_ext/string.rb +10 -2
- data/lib/unified2/event.rb +250 -100
- data/lib/unified2/exceptions/file_not_found.rb +6 -3
- data/lib/unified2/exceptions/file_not_readable.rb +6 -3
- data/lib/unified2/exceptions/unknown_load_type.rb +6 -3
- data/lib/unified2/payload.rb +82 -13
- data/lib/unified2/protocol.rb +141 -0
- data/lib/unified2/sensor.rb +22 -0
- data/lib/unified2/signature.rb +28 -4
- data/lib/unified2/version.rb +2 -2
- data/lib/unified2.rb +84 -13
- data/spec/event_spec.rb +112 -0
- data/spec/spec_helper.rb +45 -1
- data/spec/unified2_spec.rb +87 -1
- metadata +45 -25
- data/README.rdoc +0 -60
- data/Rakefile.compiled.rbc +0 -775
- data/example/connect.rb +0 -20
- data/example/models.rb +0 -194
- data/example/mysql-example.rb +0 -73
- data/example/search.rb +0 -14
- data/example/untitled.rb +0 -31
- data/lib/unified2/construct.rb +0 -54
- data/lib/unified2/event_ip4.rb +0 -26
- data/lib/unified2/event_ip6.rb +0 -23
- data/lib/unified2/packet.rb +0 -16
- data/lib/unified2/primitive/ipv4.rb +0 -19
- data/lib/unified2/record_header.rb +0 -10
@@ -0,0 +1,141 @@
|
|
1
|
+
module Unified2
|
2
|
+
#
|
3
|
+
# Protocol
|
4
|
+
#
|
5
|
+
class Protocol
|
6
|
+
|
7
|
+
#
|
8
|
+
# Initialize protocol object
|
9
|
+
#
|
10
|
+
# @param [String] protocol Event protocol
|
11
|
+
#
|
12
|
+
# @param [Event#packet] packet PacketFu object
|
13
|
+
#
|
14
|
+
def initialize(protocol, packet=nil)
|
15
|
+
@protocol = protocol
|
16
|
+
@packet = packet
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Protocol Header
|
21
|
+
#
|
22
|
+
# @return [Object, nil] Protocol header object
|
23
|
+
#
|
24
|
+
def header
|
25
|
+
if @packet.has_data?
|
26
|
+
if @packet.send(:"is_#{@protocol.downcase}?")
|
27
|
+
@packet.send(:"#{@protocol.downcase}_header")
|
28
|
+
end
|
29
|
+
else
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# ICMP?
|
36
|
+
#
|
37
|
+
# @return [true, false] Check is protocol is icmp
|
38
|
+
#
|
39
|
+
def icmp?
|
40
|
+
return true if @protocol == :ICMP
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# TCP?
|
46
|
+
#
|
47
|
+
# @return [true, false] Check is protocol is tcp
|
48
|
+
#
|
49
|
+
def tcp?
|
50
|
+
return true if @protocol == :TCP
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# UDP?
|
56
|
+
#
|
57
|
+
# @return [true, false] Check is protocol is udp
|
58
|
+
#
|
59
|
+
def udp?
|
60
|
+
return true if @protocol == :UDP
|
61
|
+
false
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Convert To String
|
66
|
+
#
|
67
|
+
# @return [String] Protocol
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# event.protocol #=> 'TCP'
|
71
|
+
#
|
72
|
+
def to_s
|
73
|
+
@protocol.to_s
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Convert To Hash
|
78
|
+
#
|
79
|
+
# @return [Hash] Protocol header hash object
|
80
|
+
#
|
81
|
+
# @example
|
82
|
+
# event.protocol.to_h #=> {:length=>379, :seq=>3934511163, :ack=>1584708129 ... }
|
83
|
+
#
|
84
|
+
def to_h
|
85
|
+
if send(:"#{@protocol.downcase}?")
|
86
|
+
self.send(:"#{@protocol.downcase}")
|
87
|
+
else
|
88
|
+
{}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def icmp(include_body=false)
|
95
|
+
@icmp = {
|
96
|
+
:length => header.len,
|
97
|
+
:type => header.icmp_type,
|
98
|
+
:csum => header.icmp_sum,
|
99
|
+
:code => header.icmp_code
|
100
|
+
}
|
101
|
+
|
102
|
+
@icmp[:body] = header.body if include_body
|
103
|
+
|
104
|
+
@icmp
|
105
|
+
end
|
106
|
+
|
107
|
+
def udp(include_body=false)
|
108
|
+
@udp = {
|
109
|
+
:length => header.len,
|
110
|
+
:sum => header.udp_sum,
|
111
|
+
}
|
112
|
+
|
113
|
+
@udp[:body] = header.body if include_body
|
114
|
+
|
115
|
+
@udp
|
116
|
+
end
|
117
|
+
|
118
|
+
def tcp(include_body=false)
|
119
|
+
@tcp = {
|
120
|
+
:length => header.len,
|
121
|
+
:seq => header.tcp_seq,
|
122
|
+
:ack => header.tcp_ack,
|
123
|
+
:win => header.tcp_win,
|
124
|
+
:sum => header.tcp_sum,
|
125
|
+
:urg => header.tcp_urg,
|
126
|
+
:hlen => header.tcp_hlen,
|
127
|
+
:reserved => header.tcp_reserved,
|
128
|
+
:ecn => header.tcp_ecn,
|
129
|
+
:opts => header.tcp_opts,
|
130
|
+
:opts_len => header.tcp_opts_len,
|
131
|
+
:rand_port => header.rand_port,
|
132
|
+
:options => header.tcp_options
|
133
|
+
}
|
134
|
+
|
135
|
+
@tcp[:body] = header.body if include_body
|
136
|
+
|
137
|
+
@tcp
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
data/lib/unified2/sensor.rb
CHANGED
@@ -1,8 +1,20 @@
|
|
1
1
|
module Unified2
|
2
|
+
#
|
3
|
+
# Sensor
|
4
|
+
#
|
2
5
|
class Sensor
|
3
6
|
|
4
7
|
attr_accessor :id, :hostname, :interface, :name, :checksum
|
5
8
|
|
9
|
+
#
|
10
|
+
# Initialize sensor object
|
11
|
+
#
|
12
|
+
# @param [Hash] options Sensor hash attributes
|
13
|
+
#
|
14
|
+
# @option options [Integer] :id Sensor id
|
15
|
+
# @option options [String] :name Sensor name
|
16
|
+
# @option options [String] :interface Sensor interface
|
17
|
+
#
|
6
18
|
def initialize(options={})
|
7
19
|
@id = options[:id] || 0
|
8
20
|
@name = options[:name] || ""
|
@@ -11,6 +23,16 @@ module Unified2
|
|
11
23
|
@checksum = nil
|
12
24
|
end
|
13
25
|
|
26
|
+
#
|
27
|
+
# Update
|
28
|
+
#
|
29
|
+
# @param [Hash] attributes Sensor attributes
|
30
|
+
#
|
31
|
+
# @option attributes [Integer] :id Sensor id
|
32
|
+
# @option attributes [String] :hostname Sensor hostname
|
33
|
+
# @option attributes [String] :name Sensor name
|
34
|
+
# @option attributes [String] :interface Sensor interface
|
35
|
+
#
|
14
36
|
def update(attributes={})
|
15
37
|
return self if attributes.empty?
|
16
38
|
|
data/lib/unified2/signature.rb
CHANGED
@@ -1,21 +1,45 @@
|
|
1
1
|
module Unified2
|
2
|
-
|
2
|
+
#
|
3
|
+
# Signature
|
4
|
+
#
|
3
5
|
class Signature
|
6
|
+
|
7
|
+
attr_accessor :id, :generator, :revision, :name, :blank
|
4
8
|
|
5
|
-
|
6
|
-
|
9
|
+
#
|
10
|
+
# Initialize signature object
|
11
|
+
#
|
12
|
+
# @param [Hash] signature Signature hash attributes
|
13
|
+
#
|
14
|
+
# @option signature [Integer] :signature_id Signature id
|
15
|
+
# @option signature [Integer] :generator_id Generator id
|
16
|
+
# @option signature [Integer] :revision Signature revision
|
17
|
+
# @option signature [Integer] :name Signature name
|
18
|
+
# @option signature [true, false] :blank Signature exists
|
19
|
+
#
|
7
20
|
def initialize(signature={})
|
8
21
|
@id = signature[:signature_id] || 0
|
9
22
|
@generator = signature[:generator_id]
|
10
23
|
@revision = signature[:revision]
|
11
24
|
@name = signature[:name].strip
|
12
|
-
@blank = signature[:blank]
|
25
|
+
@blank = signature[:blank] || false
|
13
26
|
end
|
14
27
|
|
28
|
+
#
|
29
|
+
# Blank?
|
30
|
+
#
|
31
|
+
# @return [true, false]
|
32
|
+
# Return true if signature exists
|
33
|
+
#
|
15
34
|
def blank?
|
16
35
|
@blank
|
17
36
|
end
|
18
37
|
|
38
|
+
#
|
39
|
+
# References
|
40
|
+
#
|
41
|
+
# @return [Array<String,String>] Signature references
|
42
|
+
#
|
19
43
|
def references
|
20
44
|
@references
|
21
45
|
end
|
data/lib/unified2/version.rb
CHANGED
data/lib/unified2.rb
CHANGED
@@ -1,34 +1,67 @@
|
|
1
1
|
require 'bindata'
|
2
2
|
require 'digest'
|
3
3
|
require 'socket'
|
4
|
-
# http://cvs.snort.org/viewcvs.cgi/snort/src/output-plugins/spo_unified2.c?rev=1.3&content-type=text/vnd.viewcvs-markup
|
5
4
|
|
6
|
-
require 'unified2/
|
5
|
+
require 'unified2/constructor'
|
7
6
|
require 'unified2/config_file'
|
8
7
|
require 'unified2/core_ext'
|
9
8
|
require 'unified2/event'
|
10
9
|
require 'unified2/exceptions'
|
11
10
|
require 'unified2/version'
|
12
11
|
|
12
|
+
#
|
13
|
+
# Unified2 Namespace
|
14
|
+
#
|
13
15
|
module Unified2
|
14
|
-
|
16
|
+
|
17
|
+
#
|
18
|
+
# Configuration File Types
|
19
|
+
#
|
20
|
+
# Holds the available configuration
|
21
|
+
# file types current supported.
|
22
|
+
#
|
15
23
|
TYPES = [
|
16
24
|
:signatures,
|
17
25
|
:generators,
|
18
26
|
:classifications
|
19
27
|
]
|
20
|
-
|
28
|
+
|
21
29
|
class << self
|
22
30
|
attr_accessor :signatures, :generators,
|
23
31
|
:sensor, :hostname, :interface,
|
24
32
|
:classifications
|
25
33
|
end
|
26
34
|
|
35
|
+
#
|
36
|
+
# Configuration
|
37
|
+
#
|
38
|
+
# @param [Hash] options Sensor Configuration
|
39
|
+
# @yield [ConfigFile] block Configurations
|
40
|
+
#
|
41
|
+
# @option options [Integer] :id Sensor id
|
42
|
+
# @option options [String] :name Sensor name
|
43
|
+
# @option options [String] :interface Sensor interface
|
44
|
+
#
|
45
|
+
# @return [nil]
|
46
|
+
#
|
27
47
|
def self.configuration(options={}, &block)
|
28
|
-
@sensor ||= Sensor.new
|
48
|
+
@sensor ||= Sensor.new(options)
|
29
49
|
self.instance_eval(&block)
|
30
50
|
end
|
31
|
-
|
51
|
+
|
52
|
+
#
|
53
|
+
# Sensor
|
54
|
+
#
|
55
|
+
# @param [Hash] options Sensor Configuration
|
56
|
+
# @yield [Sensor] block Sensor attributes
|
57
|
+
#
|
58
|
+
# @option options [Integer] :id Sensor id
|
59
|
+
# @option options [String] :hostname Sensor hostname
|
60
|
+
# @option options [String] :name Sensor name
|
61
|
+
# @option options [String] :interface Sensor interface
|
62
|
+
#
|
63
|
+
# @return [nil]
|
64
|
+
#
|
32
65
|
def self.sensor(options={}, &block)
|
33
66
|
if block
|
34
67
|
@sensor.instance_eval(&block)
|
@@ -36,6 +69,17 @@ module Unified2
|
|
36
69
|
@sensor.update(options)
|
37
70
|
end
|
38
71
|
|
72
|
+
#
|
73
|
+
# Load
|
74
|
+
#
|
75
|
+
# @param [String] type Configuration type
|
76
|
+
# @param [String] path Configuration path
|
77
|
+
#
|
78
|
+
# @return [nil]
|
79
|
+
#
|
80
|
+
# @raise [FileNotReadable] Path not readable
|
81
|
+
# @raise [FileNotFound] File not found
|
82
|
+
#
|
39
83
|
def self.load(type, path)
|
40
84
|
unless TYPES.include?(type.to_sym)
|
41
85
|
raise UnknownLoadType, "Error - #{@type} is unknown."
|
@@ -52,6 +96,20 @@ module Unified2
|
|
52
96
|
end
|
53
97
|
end
|
54
98
|
|
99
|
+
#
|
100
|
+
# Watch
|
101
|
+
#
|
102
|
+
# Monitor the unified2 file for events and process.
|
103
|
+
#
|
104
|
+
# @param [String] path Unified2 file path
|
105
|
+
# @param [String,Symbol,Integer] position IO position
|
106
|
+
# @yield [Event] block Event object
|
107
|
+
#
|
108
|
+
# @raise [FileNotReadable] Path not readable
|
109
|
+
# @raise [FileNotFound] File not found
|
110
|
+
#
|
111
|
+
# @return [nil]
|
112
|
+
#
|
55
113
|
def self.watch(path, position=:first, &block)
|
56
114
|
|
57
115
|
unless File.exists?(path)
|
@@ -73,7 +131,7 @@ module Unified2
|
|
73
131
|
when :last
|
74
132
|
|
75
133
|
until io.eof?
|
76
|
-
event = Unified2::Construct.read(io)
|
134
|
+
event = Unified2::Constructor::Construct.read(io)
|
77
135
|
event_id = event.data.event_id if event
|
78
136
|
end
|
79
137
|
|
@@ -86,7 +144,7 @@ module Unified2
|
|
86
144
|
when :first
|
87
145
|
|
88
146
|
first_open = File.open(path)
|
89
|
-
first_event = Unified2::Construct.read(first_open)
|
147
|
+
first_event = Unified2::Constructor::Construct.read(first_open)
|
90
148
|
first_open.close
|
91
149
|
event_id = first_event.data.event_id
|
92
150
|
@event = Event.new(event_id)
|
@@ -96,7 +154,7 @@ module Unified2
|
|
96
154
|
|
97
155
|
loop do
|
98
156
|
begin
|
99
|
-
event = Unified2::Construct.read(io)
|
157
|
+
event = Unified2::Constructor::Construct.read(io)
|
100
158
|
|
101
159
|
if event_id
|
102
160
|
if event.data.event_id.to_i > (event_id - 1)
|
@@ -116,7 +174,21 @@ module Unified2
|
|
116
174
|
raise FileNotReadable, "Error - #{path} not readable."
|
117
175
|
end
|
118
176
|
end
|
119
|
-
|
177
|
+
|
178
|
+
#
|
179
|
+
# Read
|
180
|
+
#
|
181
|
+
# Read the unified2 log until EOF and process
|
182
|
+
# events.
|
183
|
+
#
|
184
|
+
# @param [String] path Unified2 file path
|
185
|
+
# @yield [Event] block Event object
|
186
|
+
#
|
187
|
+
# @raise [FileNotReadable] Path not readable
|
188
|
+
# @raise [FileNotFound] File not found
|
189
|
+
#
|
190
|
+
# @return [nil]
|
191
|
+
#
|
120
192
|
def self.read(path, &block)
|
121
193
|
|
122
194
|
unless File.exists?(path)
|
@@ -127,13 +199,13 @@ module Unified2
|
|
127
199
|
io = File.open(path)
|
128
200
|
|
129
201
|
first_open = File.open(path)
|
130
|
-
first_event = Unified2::Construct.read(first_open)
|
202
|
+
first_event = Unified2::Constructor::Construct.read(first_open)
|
131
203
|
first_open.close
|
132
204
|
|
133
205
|
@event = Event.new(first_event.data.event_id)
|
134
206
|
|
135
207
|
until io.eof?
|
136
|
-
event = Unified2::Construct.read(io)
|
208
|
+
event = Unified2::Constructor::Construct.read(io)
|
137
209
|
check_event(event, block)
|
138
210
|
end
|
139
211
|
|
@@ -142,7 +214,6 @@ module Unified2
|
|
142
214
|
end
|
143
215
|
end
|
144
216
|
|
145
|
-
|
146
217
|
private
|
147
218
|
|
148
219
|
def self.check_event(event, block)
|
data/spec/event_spec.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'unified2'
|
3
|
+
|
4
|
+
describe Event do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
@event = Unified2.first('example/seeds/unified2.log')
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have an event_id" do
|
11
|
+
@event.to_i.should == 1
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have an event time" do
|
15
|
+
@event.timestamp.to_s.should == '2010-10-05 22:50:18 -0400'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should have a sensor id" do
|
19
|
+
@event.sensor.id.should == 50000000000
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should have a sensor name" do
|
23
|
+
@event.sensor.name.should == "Example Sensor"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should have a sensor interface" do
|
27
|
+
@event.sensor.interface.should == "en1"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have a sensor hostname" do
|
31
|
+
@event.sensor.hostname.should == "W0ots.local"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should have a source address" do
|
35
|
+
@event.source_ip.should == "24.19.7.110"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should have a source port" do
|
39
|
+
@event.source_port.should == 0
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should have a destination address" do
|
43
|
+
@event.destination_ip.should == "10.0.1.6"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should have a destination port" do
|
47
|
+
@event.destination_port.should == 0
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should have a protocol" do
|
51
|
+
@event.protocol.to_s.should == 'ICMP'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should have a severity" do
|
55
|
+
@event.severity.should == 3
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should have an event checksum" do
|
59
|
+
@event.checksum.should == "6e96db6e8fe649c939711400ea4625eb"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have a signature id" do
|
63
|
+
@event.signature.id.should == 485
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have a signature generator id" do
|
67
|
+
@event.signature.generator.should == 1
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should have a signature revision" do
|
71
|
+
@event.signature.revision.should == 5
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should have a signature thats not blank" do
|
75
|
+
@event.signature.blank.should == false
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should have a signature name" do
|
79
|
+
@event.signature.name.should == "DELETED ICMP Destination Unreachable" \
|
80
|
+
" Communication Administratively Prohibited"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should have a classification id" do
|
84
|
+
@event.classification.id.should == 29
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should have a classification short name" do
|
88
|
+
@event.classification.short.should == "misc-activity"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should have a classification severity" do
|
92
|
+
@event.classification.severity.should == 3
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should have a classification name" do
|
96
|
+
@event.classification.name.should == "Misc activity"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should have a payload thats not blank" do
|
100
|
+
@event.payload.blank?.should == false
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should have a hex payload" do
|
104
|
+
p = "000000004520008323bc000032113a080a0001061813076e90c84fac006fe498"
|
105
|
+
@event.payload.hex.should == p
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should have a payload length" do
|
109
|
+
@event.payload.length.should == 70
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,49 @@
|
|
1
1
|
gem 'rspec', '~> 2.4'
|
2
2
|
require 'rspec'
|
3
|
-
require 'unified2/version'
|
4
3
|
|
4
|
+
require 'unified2'
|
5
5
|
include Unified2
|
6
|
+
|
7
|
+
module Unified2
|
8
|
+
|
9
|
+
def self.first(path)
|
10
|
+
unless File.exists?(path)
|
11
|
+
raise FileNotFound, "Error - #{path} not found."
|
12
|
+
end
|
13
|
+
|
14
|
+
if File.readable?(path)
|
15
|
+
io = File.open(path)
|
16
|
+
|
17
|
+
first_open = File.open(path)
|
18
|
+
first_event = Unified2::Constructor::Construct.read(first_open)
|
19
|
+
first_open.close
|
20
|
+
|
21
|
+
@event = Event.new(first_event.data.event_id)
|
22
|
+
|
23
|
+
loop do
|
24
|
+
event = Unified2::Constructor::Construct.read(io)
|
25
|
+
|
26
|
+
if event.data.event_id.to_i == @event.id.to_i
|
27
|
+
@event.load(event)
|
28
|
+
else
|
29
|
+
return @event
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
else
|
34
|
+
raise FileNotReadable, "Error - #{path} not readable."
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
Unified2.configuration do
|
41
|
+
sensor :interface => 'en1',
|
42
|
+
:name => 'Example Sensor',
|
43
|
+
:hostname => 'W0ots.local',
|
44
|
+
:id => 50000000000
|
45
|
+
|
46
|
+
load :signatures, 'example/seeds/sid-msg.map'
|
47
|
+
load :generators, 'example/seeds/gen-msg.map'
|
48
|
+
load :classifications, 'example/seeds/classification.config'
|
49
|
+
end
|
data/spec/unified2_spec.rb
CHANGED
@@ -2,7 +2,93 @@ require 'spec_helper'
|
|
2
2
|
require 'unified2'
|
3
3
|
|
4
4
|
describe Unified2 do
|
5
|
+
|
5
6
|
it "should have a VERSION constant" do
|
6
7
|
subject.const_get('VERSION').should_not be_empty
|
7
8
|
end
|
8
|
-
|
9
|
+
|
10
|
+
it "should have a TYPES constant" do
|
11
|
+
subject.const_get('TYPES').should_not be_empty
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have the correct signature size" do
|
15
|
+
Unified2.signatures.size.should == 16710
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should have the correct signature name" do
|
19
|
+
signature_name = "EXPLOIT Oracle BEA Weblogic server " \
|
20
|
+
"console-help.portal cross-site scripting attempt"
|
21
|
+
|
22
|
+
Unified2.signatures.data['16710'][:name].should == signature_name
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have the correct signature id" do
|
26
|
+
Unified2.signatures.data['16710'][:signature_id].should == 16710
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have the correct signature generator id" do
|
30
|
+
Unified2.signatures.data['16710'][:generator_id].should == 1
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have the correct classification size" do
|
34
|
+
Unified2.classifications.size.should == 35
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have the correct classification id" do
|
38
|
+
Unified2.classifications.data['35'][:severity_id].should == 2
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have the correct classification name" do
|
42
|
+
classification_name = "Sensitive Data was Transmitted Across the Network"
|
43
|
+
Unified2.classifications.data['35'][:name].should == classification_name
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should have the correct classification short name" do
|
47
|
+
Unified2.classifications.data['35'][:short].should == "sdf"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should have the correct generator size" do
|
51
|
+
Unified2.generators.size.should == 388
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should have the correct generator id" do
|
55
|
+
Unified2.generators.data["138.6"][:generator_id].should == 138
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should have the correct generator name" do
|
59
|
+
generator_name = "sensitive_data: sensitive data - U.S. phone numbers"
|
60
|
+
Unified2.generators.data["138.6"][:name].should == generator_name
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should have the correct generator signature id" do
|
64
|
+
Unified2.generators.data["138.6"][:signature_id].should == 6
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should have a sensor name" do
|
68
|
+
Unified2.sensor.name.should == "Example Sensor"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should have a sensor interface" do
|
72
|
+
Unified2.sensor.interface.should == 'en1'
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should have a sensor hostname" do
|
76
|
+
Unified2.sensor.hostname.should == 'W0ots.local'
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should have a new sensor hostname if set" do
|
80
|
+
Unified2.sensor.hostname = 'OMG.stuff.local'
|
81
|
+
Unified2.sensor.hostname.should == 'OMG.stuff.local'
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should have a new sensor interface if set" do
|
85
|
+
Unified2.sensor.interface = 'eth1'
|
86
|
+
Unified2.sensor.interface.should == 'eth1'
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should have a new sensor name if set" do
|
90
|
+
Unified2.sensor.name = 'Mephux FTW!'
|
91
|
+
Unified2.sensor.name.should == "Mephux FTW!"
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|