ruby-nessus2 2.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.
- checksums.yaml +7 -0
- data/.drone.yml +51 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +124 -0
- data/.travis.yml +13 -0
- data/.yardopts +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +75 -0
- data/LICENSE.txt +20 -0
- data/README.md +181 -0
- data/Rakefile +21 -0
- data/bin/recess +10 -0
- data/examples/example.rb +46 -0
- data/examples/example_bid.rb +28 -0
- data/examples/example_cpe.rb +28 -0
- data/examples/example_cve.rb +36 -0
- data/examples/example_v1.nessus +1 -0
- data/examples/example_v2.nessus +2076 -0
- data/examples/example_v3.nessus +7449 -0
- data/lib/ruby-nessus.rb +5 -0
- data/lib/ruby-nessus/cli.rb +126 -0
- data/lib/ruby-nessus/log.rb +84 -0
- data/lib/ruby-nessus/parse.rb +46 -0
- data/lib/ruby-nessus/ruby-nessus.rb +6 -0
- data/lib/ruby-nessus/version.rb +5 -0
- data/lib/ruby-nessus/version1/event.rb +85 -0
- data/lib/ruby-nessus/version1/host.rb +267 -0
- data/lib/ruby-nessus/version1/port.rb +84 -0
- data/lib/ruby-nessus/version1/scan.rb +404 -0
- data/lib/ruby-nessus/version2/event.rb +410 -0
- data/lib/ruby-nessus/version2/host.rb +522 -0
- data/lib/ruby-nessus/version2/port.rb +75 -0
- data/lib/ruby-nessus/version2/scan.rb +393 -0
- data/ruby-nessus.gemspec +28 -0
- data/spec/ruby-nessus/parse_spec.rb +40 -0
- data/spec/ruby-nessus/version1/event_spec.rb +69 -0
- data/spec/ruby-nessus/version1/host_spec.rb +75 -0
- data/spec/ruby-nessus/version1/scan_spec.rb +97 -0
- data/spec/ruby-nessus/version2/event_spec.rb +225 -0
- data/spec/ruby-nessus/version2/host_spec.rb +148 -0
- data/spec/ruby-nessus/version2/scan_spec.rb +96 -0
- data/spec/ruby-nessus/version_spec.rb +11 -0
- data/spec/spec_fixtures/example_v1.nessus +1 -0
- data/spec/spec_fixtures/example_v2.nessus +2080 -0
- data/spec/spec_fixtures/example_v_wrong.nessus +3 -0
- data/spec/spec_fixtures/xml.rb +15 -0
- data/spec/spec_helper.rb +7 -0
- metadata +190 -0
data/lib/ruby-nessus.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'ruby-nessus/ruby-nessus'
|
5
|
+
require 'ruby-nessus/log'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
require 'pp'
|
9
|
+
|
10
|
+
module RubyNessus
|
11
|
+
class CLI
|
12
|
+
def initialize
|
13
|
+
@file = nil
|
14
|
+
@nessus_version = nil
|
15
|
+
@args = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.run
|
19
|
+
new.run(*ARGV)
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(*args)
|
23
|
+
optparse(*args)
|
24
|
+
|
25
|
+
Log.it 'Recess - Ruby-Nessus CLI'
|
26
|
+
Log.it "Version: #{RubyNessus::VERSION}"
|
27
|
+
Log.it
|
28
|
+
|
29
|
+
RubyNessus::Parse.new(@file.to_s) do |scan|
|
30
|
+
Log.h1 'SCAN Metadata'
|
31
|
+
Log.it
|
32
|
+
Log.h2 'Scan Title', scan.title
|
33
|
+
Log.h2 'Policy Title', scan.policy_title
|
34
|
+
Log.it
|
35
|
+
Log.h1 'SCAN Statistics'
|
36
|
+
Log.it
|
37
|
+
Log.h2 'Host Count', scan.host_count
|
38
|
+
Log.h2 'Open Port Count', scan.open_ports_count
|
39
|
+
|
40
|
+
unless scan.version == 1
|
41
|
+
Log.h2 'TCP Count', scan.tcp_count
|
42
|
+
Log.h2 'UDP Count', scan.udp_count
|
43
|
+
Log.h2 'ICMP Count', scan.icmp_count
|
44
|
+
end
|
45
|
+
|
46
|
+
Log.it
|
47
|
+
Log.h1 'EVENT Statistics'
|
48
|
+
Log.it
|
49
|
+
|
50
|
+
Log.informational 'Informational Severity Count', scan.informational_severity_count unless scan.version == 1
|
51
|
+
|
52
|
+
Log.low 'Low Severity Count', scan.low_severity_count
|
53
|
+
Log.medium 'Medium Severity Count', scan.medium_severity_count
|
54
|
+
Log.high 'High Severity Count', scan.high_severity_count
|
55
|
+
Log.h3 'Total Event Count', scan.total_event_count
|
56
|
+
Log.break
|
57
|
+
Log.it! "Low Event Percentage: #{scan.event_percentage_for('low', true)}"
|
58
|
+
Log.it! "Medium Event Percentage: #{scan.event_percentage_for('medium', true)}"
|
59
|
+
Log.it! "High Event Percentage: #{scan.event_percentage_for('high', true)}"
|
60
|
+
Log.it
|
61
|
+
|
62
|
+
Log.h1 'HOSTS'
|
63
|
+
Log.it
|
64
|
+
|
65
|
+
scan.each_host do |host|
|
66
|
+
Log.h2 'Hostname', host.hostname
|
67
|
+
Log.h5 'IP Address:', host.ip
|
68
|
+
|
69
|
+
unless scan.version == 1
|
70
|
+
Log.h5 'Informational Count', host.informational_severity_count
|
71
|
+
Log.h5 'Low Count', host.low_severity_count
|
72
|
+
Log.h5 'Medium Count', host.medium_severity_count
|
73
|
+
Log.h5 'High Count', host.high_severity_count
|
74
|
+
end
|
75
|
+
Log.it
|
76
|
+
end
|
77
|
+
|
78
|
+
Log.end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
def optparse(*args)
|
85
|
+
opts = OptionParser.new
|
86
|
+
opts.program_name = 'recess'
|
87
|
+
opts.banner = "Recess #{RubyNessus::VERSION}"
|
88
|
+
opts.separator 'usage: recess FILE [OPTIONS]'
|
89
|
+
|
90
|
+
opts.on('-f', '--file FILE', 'The .nessus file to parse.') do |file|
|
91
|
+
@file = file
|
92
|
+
end
|
93
|
+
|
94
|
+
opts.on('-f', '--file FILE', 'The .nessus file to parse.') do |file|
|
95
|
+
@file = file
|
96
|
+
end
|
97
|
+
|
98
|
+
opts.on('-h', '--help', 'This help summary page.') do |_help|
|
99
|
+
Log.it opts
|
100
|
+
Log.it
|
101
|
+
exit(-1)
|
102
|
+
end
|
103
|
+
|
104
|
+
opts.on('-v', '--version', 'Recess Version.') do |_version|
|
105
|
+
Log.it RubyNessus::VERSION
|
106
|
+
Log.it
|
107
|
+
exit(-1)
|
108
|
+
end
|
109
|
+
|
110
|
+
begin
|
111
|
+
@args = opts.parse!(args)
|
112
|
+
@file ||= @args[0]
|
113
|
+
if @file.nil?
|
114
|
+
Log.it opts
|
115
|
+
Log.it
|
116
|
+
exit(-1)
|
117
|
+
end
|
118
|
+
rescue => e
|
119
|
+
Log.error e.message
|
120
|
+
Log.it opts
|
121
|
+
Log.it
|
122
|
+
exit(-1)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rainbow'
|
4
|
+
|
5
|
+
module RubyNessus
|
6
|
+
class Log
|
7
|
+
#
|
8
|
+
# Formatting
|
9
|
+
#
|
10
|
+
def self.it(msg = nil)
|
11
|
+
STDERR.puts msg.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.it!(msg = nil)
|
15
|
+
STDERR.puts "\t#{msg}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.break
|
19
|
+
STDERR.puts "\t"
|
20
|
+
STDERR.puts ''
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.end
|
24
|
+
STDERR.puts "\n\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Headers
|
29
|
+
#
|
30
|
+
def self.h1(title, msg = nil)
|
31
|
+
STDERR.puts Rainbow("-> #{title}: ").foreground(:green).bright + msg.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.h2(title, msg = nil)
|
35
|
+
STDERR.puts Rainbow("\t#{title}: ").foreground(:blue).bright + msg.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.h3(title, msg = nil)
|
39
|
+
STDERR.puts "\t#{title}: " + Rainbow(msg.to_s).foreground(:blue).underline
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.h4(msg = nil)
|
43
|
+
STDERR.puts "\t\t- #{msg}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.h5(title, msg = nil)
|
47
|
+
STDERR.puts "\t\t- #{title}: #{msg}"
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Errors
|
52
|
+
#
|
53
|
+
def self.error(msg = nil)
|
54
|
+
STDERR.puts Rainbow('ERROR: ').foreground(:red).bright + msg.to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.warn(msg = nil)
|
58
|
+
STDERR.puts Rainbow('WARNING: ').foreground(:yellow).bright + msg.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.info(msg = nil)
|
62
|
+
STDERR.puts Rainbow('INFO: ').foreground(:green).bright + msg.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Event Severities
|
67
|
+
#
|
68
|
+
def self.informational(title, msg = nil)
|
69
|
+
STDERR.puts Rainbow("\t#{title}: ").foreground(:magenta).bright + msg.to_s
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.low(title, msg = nil)
|
73
|
+
STDERR.puts Rainbow("\t#{title}: ").foreground(:green) + msg.to_s
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.medium(title, msg = nil)
|
77
|
+
STDERR.puts Rainbow("\t#{title}: ").foreground(:yellow).bright + msg.to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.high(title, msg = nil)
|
81
|
+
STDERR.puts Rainbow("\t#{title}: ").foreground(:red).bright + msg.to_s
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ruby-nessus/log'
|
4
|
+
require 'ruby-nessus/version1/scan'
|
5
|
+
require 'ruby-nessus/version2/scan'
|
6
|
+
|
7
|
+
require 'nokogiri'
|
8
|
+
require 'date'
|
9
|
+
require 'time'
|
10
|
+
|
11
|
+
module RubyNessus
|
12
|
+
class Parse
|
13
|
+
def initialize(file = nil, options = {}, &block)
|
14
|
+
doc = file ? File.read(file) : options[:xml]
|
15
|
+
@xml = Nokogiri::XML.parse(doc)
|
16
|
+
@version = options[:version] || detect_version
|
17
|
+
|
18
|
+
@xml_parser = case @version
|
19
|
+
when 1
|
20
|
+
Version1::XML.new(@xml)
|
21
|
+
when 2
|
22
|
+
Version2::XML.new(@xml)
|
23
|
+
else
|
24
|
+
raise 'Error: Supported .Nessus Version are 1 and 2.'
|
25
|
+
end
|
26
|
+
|
27
|
+
yield(@xml_parser) if block
|
28
|
+
end
|
29
|
+
|
30
|
+
# Retrive scan from file
|
31
|
+
def scan
|
32
|
+
@xml_parser
|
33
|
+
end
|
34
|
+
|
35
|
+
# Try to detection version with the XML given
|
36
|
+
def detect_version
|
37
|
+
if @xml.at('NessusClientData')
|
38
|
+
1
|
39
|
+
elsif @xml.at('NessusClientData_v2')
|
40
|
+
2
|
41
|
+
else
|
42
|
+
raise 'Error: Supported .Nessus Version are 1 and 2.'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ruby-nessus/version1/port'
|
4
|
+
|
5
|
+
module RubyNessus
|
6
|
+
module Version1
|
7
|
+
class Event
|
8
|
+
# Return the total event count for a given host.
|
9
|
+
# @return [Integer]
|
10
|
+
# Return the total event count for a given host.
|
11
|
+
# @example
|
12
|
+
# host.event_count #=> 3456
|
13
|
+
def initialize(event)
|
14
|
+
@event = event
|
15
|
+
end
|
16
|
+
|
17
|
+
# Return the event port.
|
18
|
+
# @return [Object]
|
19
|
+
# Return the event port object or port string.
|
20
|
+
# @example
|
21
|
+
# event.port #=> "https (443/tcp)"
|
22
|
+
# event.port.number #=> 443
|
23
|
+
# event.port.service #=> "https"
|
24
|
+
# event.port.protocol #=> "tcp"
|
25
|
+
def port
|
26
|
+
@port ||= Port.parse(@event.at('port').inner_text)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Return the event severity.
|
30
|
+
# @return [String]
|
31
|
+
# Return the event severity.
|
32
|
+
# @example
|
33
|
+
# event.severity #=> 3
|
34
|
+
def severity
|
35
|
+
@severity ||= @event.at('severity').inner_text.to_i
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return the event object nessus plugin id
|
39
|
+
# @return [String]
|
40
|
+
# Return the event object nessus plugin id
|
41
|
+
# @example
|
42
|
+
# event.plugin_id #=> 3245
|
43
|
+
def plugin_id
|
44
|
+
@plugin_id ||= @event.at('pluginID').inner_text.to_i
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return the event name (plugin_name)
|
48
|
+
# @return [String]
|
49
|
+
# Return the event name (plugin_name)
|
50
|
+
# @example
|
51
|
+
# event.plugin_name #=> "PHP < 5.2.4 Multiple Vulnerabilities"
|
52
|
+
# event.name #=> "PHP < 5.2.4 Multiple Vulnerabilities"
|
53
|
+
def plugin_name
|
54
|
+
s = @event.at('pluginName').inner_text
|
55
|
+
|
56
|
+
@plugin_name ||= if s.empty?
|
57
|
+
false
|
58
|
+
else
|
59
|
+
@event.at('pluginName').inner_text || 'N/A'
|
60
|
+
end
|
61
|
+
|
62
|
+
@plugin_name
|
63
|
+
end
|
64
|
+
alias name plugin_name
|
65
|
+
|
66
|
+
# Return the event plugin output data
|
67
|
+
# @return [String]
|
68
|
+
# Return the event plugin output data
|
69
|
+
# @example
|
70
|
+
# event.output #=> "..."
|
71
|
+
# event.data #=> "..."
|
72
|
+
def data
|
73
|
+
d = @event.at('data').to_s || ''
|
74
|
+
|
75
|
+
@data ||= if d.empty?
|
76
|
+
false
|
77
|
+
else
|
78
|
+
@event.at('data').inner_text || 'N/A'
|
79
|
+
end
|
80
|
+
@data
|
81
|
+
end
|
82
|
+
alias output data
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,267 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyNessus
|
4
|
+
module Version1
|
5
|
+
class Host
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
# Creates A New Host Object
|
9
|
+
# @param [Object] Host Object
|
10
|
+
# @example
|
11
|
+
# Host.new(object)
|
12
|
+
def initialize(host)
|
13
|
+
@host = host
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
ip.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
# Return the Host Object hostname.
|
21
|
+
# @return [String]
|
22
|
+
# The Host Object Hostname
|
23
|
+
# @example
|
24
|
+
# host.hostname #=> "127.0.0.1"
|
25
|
+
def hostname
|
26
|
+
@hostname ||= @host.at('HostName').inner_text
|
27
|
+
end
|
28
|
+
alias ip hostname
|
29
|
+
|
30
|
+
# Return the host scan start time.
|
31
|
+
# @return [DateTime]
|
32
|
+
# The Host Scan Start Time
|
33
|
+
# @example
|
34
|
+
# scan.scan_start_time #=> 'Fri Nov 11 23:36:54 1985'
|
35
|
+
def scan_start_time
|
36
|
+
if @host.at('startTime').inner_text.empty?
|
37
|
+
false
|
38
|
+
else
|
39
|
+
@host_scan_time = DateTime.strptime(@host.at('startTime').inner_text, '%a %b %d %H:%M:%S %Y')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return the host scan stop time.
|
44
|
+
# @return [DateTime]
|
45
|
+
# The Host Scan Stop Time
|
46
|
+
# @example
|
47
|
+
# scan.scan_start_time #=> 'Fri Nov 11 23:36:54 1985'
|
48
|
+
def scan_stop_time
|
49
|
+
if @host.at('stopTime').inner_text.empty?
|
50
|
+
false
|
51
|
+
else
|
52
|
+
@host_scan_time = DateTime.strptime(@host.at('stopTime').inner_text, '%a %b %d %H:%M:%S %Y')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return the host run time.
|
57
|
+
# @return [String]
|
58
|
+
# The Host Scan Run Time
|
59
|
+
# @example
|
60
|
+
# scan.scan_run_time #=> '2 hours 5 minutes and 16 seconds'
|
61
|
+
def scan_runtime
|
62
|
+
get_runtime
|
63
|
+
end
|
64
|
+
alias runtime scan_runtime
|
65
|
+
|
66
|
+
# Return the Host Netbios Name.
|
67
|
+
# @return [String]
|
68
|
+
# The Host Netbios Name
|
69
|
+
# @example
|
70
|
+
# host.netbios_name #=> "SOMENAME4243"
|
71
|
+
def netbios_name
|
72
|
+
@netbios_name ||= @host.at('netbios_name').inner_text
|
73
|
+
end
|
74
|
+
|
75
|
+
# Return the Host Mac Address.
|
76
|
+
# @return [String]
|
77
|
+
# Return the Host Mac Address
|
78
|
+
# @example
|
79
|
+
# host.mac_addr #=> "00:11:22:33:44:55"
|
80
|
+
def mac_addr
|
81
|
+
@mac_addr ||= @host.at('mac_addr').inner_text
|
82
|
+
end
|
83
|
+
alias mac_address mac_addr
|
84
|
+
|
85
|
+
# Return the Host DNS Name.
|
86
|
+
# @return [String]
|
87
|
+
# Return the Host DNS Name
|
88
|
+
# @example
|
89
|
+
# host.dns_name #=> "snorby.org"
|
90
|
+
def dns_name
|
91
|
+
@dns_name ||= @host.at('dns_name').inner_text
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return the Host OS Name.
|
95
|
+
# @return [String]
|
96
|
+
# Return the Host OS Name
|
97
|
+
# @example
|
98
|
+
# host.dns_name #=> "Microsoft Windows 2000, Microsoft Windows Server 2003"
|
99
|
+
def os_name
|
100
|
+
@os_name ||= @host.at('os_name').inner_text
|
101
|
+
end
|
102
|
+
alias operating_system os_name
|
103
|
+
|
104
|
+
# Return the open ports for a given host object.
|
105
|
+
# @return [Integer]
|
106
|
+
# Return the open ports for a given host object.
|
107
|
+
# @example
|
108
|
+
# host.open_ports #=> 213
|
109
|
+
def open_ports
|
110
|
+
@scanned_ports ||= @host.at('num_ports').inner_text.to_i
|
111
|
+
end
|
112
|
+
|
113
|
+
# Returns All Informational Event Objects For A Given Host.
|
114
|
+
# @yield [prog] If a block is given, it will be passed the newly
|
115
|
+
# created Event object.
|
116
|
+
# @yieldparam [EVENT] prog The newly created Event object.
|
117
|
+
# @return [Integer]
|
118
|
+
# Return The Informational Event Count For A Given Host.
|
119
|
+
# @example
|
120
|
+
# host.informational_events do |info|
|
121
|
+
# puts info.port
|
122
|
+
# puts info.data if info.data
|
123
|
+
# end
|
124
|
+
def informational_events(&block)
|
125
|
+
unless @informational_events
|
126
|
+
@informational_events = []
|
127
|
+
@informational_event_count = 0
|
128
|
+
|
129
|
+
@host.xpath('ReportItem').each do |event|
|
130
|
+
next if event.at('severity').inner_text.to_i != 0
|
131
|
+
@informational_events << Event.new(event)
|
132
|
+
@informational_event_count += 1
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
@informational_events.each(&block)
|
138
|
+
@informational_event_count
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns All Low Event Objects For A Given Host.
|
142
|
+
# @yield [prog] If a block is given, it will be passed the newly
|
143
|
+
# created Event object.
|
144
|
+
# @yieldparam [EVENT] prog The newly created Event object.
|
145
|
+
# @return [Integer]
|
146
|
+
# Return The Low Event Count For A Given Host.
|
147
|
+
# @example
|
148
|
+
# host.low_severity_events do |low|
|
149
|
+
# puts low.name if low.name
|
150
|
+
# end
|
151
|
+
def low_severity_events(&block)
|
152
|
+
@low_severity_count = @host.at('num_lo').inner_text.to_i
|
153
|
+
|
154
|
+
unless @low_severity_events
|
155
|
+
@low_severity_events = []
|
156
|
+
|
157
|
+
@host.xpath('ReportItem').each do |event|
|
158
|
+
next if event.at('severity').inner_text.to_i != 1
|
159
|
+
@low_severity_events << Event.new(event)
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
@low_severity_events.each(&block)
|
165
|
+
@low_severity_count
|
166
|
+
end
|
167
|
+
|
168
|
+
# Returns All Medium Event Objects For A Given Host.
|
169
|
+
# @yield [prog] If a block is given, it will be passed the newly
|
170
|
+
# created Event object.
|
171
|
+
# @yieldparam [EVENT] prog The newly created Event object.
|
172
|
+
# @return [Integer]
|
173
|
+
# Return The Medium Event Count For A Given Host.
|
174
|
+
# @example
|
175
|
+
# host.medium_severity_events do |medium|
|
176
|
+
# puts medium.name if medium.name
|
177
|
+
# end
|
178
|
+
def medium_severity_events(&block)
|
179
|
+
@high_severity_count = @host.at('num_med').inner_text.to_i
|
180
|
+
|
181
|
+
unless @medium_severity_events
|
182
|
+
@medium_severity_events = []
|
183
|
+
|
184
|
+
@host.xpath('ReportItem').each do |event|
|
185
|
+
next if event.at('severity').inner_text.to_i != 2
|
186
|
+
@medium_severity_events << Event.new(event)
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
@medium_severity_events.each(&block)
|
192
|
+
@high_severity_count
|
193
|
+
end
|
194
|
+
|
195
|
+
# Returns All High Event Objects For A Given Host.
|
196
|
+
# @yield [prog] If a block is given, it will be passed the newly
|
197
|
+
# created Event object.
|
198
|
+
# @yieldparam [EVENT] prog The newly created Event object.
|
199
|
+
# @return [Integer]
|
200
|
+
# Return The High Event Count For A Given Host.
|
201
|
+
# @example
|
202
|
+
# host.high_severity_events do |high|
|
203
|
+
# puts high.name if high.name
|
204
|
+
# end
|
205
|
+
def high_severity_events(&block)
|
206
|
+
@high_severity_count = @host.at('num_hi').inner_text.to_i
|
207
|
+
|
208
|
+
unless @high_severity_events
|
209
|
+
@high_severity_events = []
|
210
|
+
|
211
|
+
@host.xpath('ReportItem').each do |event|
|
212
|
+
next if event.at('severity').inner_text.to_i != 3
|
213
|
+
@high_severity_events << Event.new(event)
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
@high_severity_events.each(&block)
|
219
|
+
@high_severity_count
|
220
|
+
end
|
221
|
+
|
222
|
+
# Return the total event count for a given host.
|
223
|
+
# @return [Integer]
|
224
|
+
# Return the total event count for a given host.
|
225
|
+
# @example
|
226
|
+
# host.event_count #=> 3456
|
227
|
+
def event_count
|
228
|
+
(low_severity_events.to_i + medium_severity_events.to_i + high_severity_events.to_i).to_i
|
229
|
+
end
|
230
|
+
|
231
|
+
# Creates a new Event object to be parser
|
232
|
+
# @yield [prog] If a block is given, it will be passed the newly
|
233
|
+
# created Event object.
|
234
|
+
# @yieldparam [EVENT] prog The newly created Event object.
|
235
|
+
# @example
|
236
|
+
# host.events do |event|
|
237
|
+
# puts event.name if event.name
|
238
|
+
# puts event.port
|
239
|
+
# end
|
240
|
+
def each_event(&block)
|
241
|
+
@host.xpath('ReportItem').each do |event|
|
242
|
+
yield(Event.new(event)) if block
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# Parses the events of the host.
|
247
|
+
# @return [Array<String>]
|
248
|
+
# The events of the host.
|
249
|
+
def events
|
250
|
+
to_enum(:each_event).to_a
|
251
|
+
end
|
252
|
+
|
253
|
+
private
|
254
|
+
|
255
|
+
def get_runtime
|
256
|
+
if scan_start_time && scan_stop_time
|
257
|
+
h = (Time.parse(scan_stop_time.to_s).strftime('%H').to_i - Time.parse(scan_start_time.to_s).strftime('%H').to_i).to_s.delete('-')
|
258
|
+
m = (Time.parse(scan_stop_time.to_s).strftime('%M').to_i - Time.parse(scan_start_time.to_s).strftime('%M').to_i).to_s.delete('-')
|
259
|
+
s = (Time.parse(scan_stop_time.to_s).strftime('%S').to_i - Time.parse(scan_start_time.to_s).strftime('%S').to_i).to_s.delete('-')
|
260
|
+
"#{h} hours #{m} minutes and #{s} seconds"
|
261
|
+
else
|
262
|
+
false
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|