Skip to content
This repository was archived by the owner on Aug 28, 2024. It is now read-only.

Commit fa0ddd9

Browse files
authored
Merge pull request #62 from filipecunhaf/compliance_improvements
Compliance improvements
2 parents 8bc2367 + 3d8b418 commit fa0ddd9

File tree

5 files changed

+201
-8
lines changed

5 files changed

+201
-8
lines changed

Gemfile

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#Gemfile
12
# frozen_string_literal: true
23

34
source 'https://rubygems.org'

lib/ruby-nessus/version2/event.rb

+88-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,74 @@ def port
3737
def severity
3838
@severity ||= @event.at('@severity').inner_text.to_i
3939
end
40+
# New matches for Baseline
4041

42+
def compliance_info
43+
@event.xpath('.//*[name()="cm:compliance-info"]')
44+
end
45+
def item_id
46+
@item_id ||= @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/item_id: (.*)/).captures.first unless @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/item_id: (.*)/).nil?
47+
end
48+
def baseline
49+
@baseline ||= @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/baseline: (.*)/).captures.first unless @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/baseline: (.*)/).nil?
50+
end
51+
def item_description
52+
@item_description ||= @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/item_description: (.*)/).captures.first unless @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/item_description: (.*)/).nil?
53+
end
54+
def threats
55+
@threats ||= @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/threats: (.*)/).captures.first unless @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/threats: (.*)/).nil?
56+
end
57+
def impacts
58+
@impacts ||= @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/impacts: (.*)/).captures.first unless @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/impacts: (.*)/).nil?
59+
end
60+
def session
61+
@session ||= @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/session: (.*)/).captures.first unless @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/session: (.*)/).nil?
62+
end
63+
def manual_setup
64+
@manual_setup ||= @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/manual_setup: (.*\n)*/).to_s.gsub("manual_setup: ","") unless @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/manual_setup: (.*)/).nil?
65+
end
66+
def threat_level
67+
@threat_level ||= @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/threat_level: (.*)/).captures.first unless @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/threat_level: (.*)/).nil?
68+
end
69+
def impact_level
70+
@impact_level ||= @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/impact_level: (.*)/).captures.first unless @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/impact_level: (.*)/).nil?
71+
end
72+
def check_type
73+
@check_type ||= @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/expected_value: (.*)/).captures.first unless @event.xpath('.//*[name()="cm:compliance-info"]').text.match(/expected_value: (.*)/).nil?
74+
end
75+
def compliance_uname
76+
@compliance_uname ||= @event.xpath('.//*[name()="cm:compliance-uname"]').children.text
77+
end
78+
79+
def compliance_check_name
80+
@compliance_check_name ||= @event.xpath('.//*[name()="cm:compliance-check-name"]').children.text
81+
end
82+
83+
def compliance_result
84+
@compliance_result ||= @event.xpath('.//*[name()="cm:compliance-result"]').children.text
85+
end
86+
87+
def remote_value
88+
@remote_value ||= @event.xpath('.//*[name()="cm:compliance-actual-value"]').children.text
89+
end
90+
91+
def policy_value
92+
@policy_value ||= @event.xpath('.//*[name()="cm:compliance-policy-value"]').children.text
93+
end
94+
95+
def check_name
96+
@check_name ||= @event.xpath('.//*[name()="cm:compliance-check-name"]').children.text
97+
end
98+
99+
def compliance_solution
100+
@compliance_solution ||= @event.xpath('.//*[name()="cm:compliance-solution"]').children.text
101+
end
102+
103+
def compliance_benchmark_name
104+
@compliance_benchmark_name ||= @event.xpath('.//*[name()="cm:compliance-benchmark-name"]').children.text
105+
end
106+
107+
41108
#
42109
# Return true if event is of informational severity.
43110
#
@@ -130,7 +197,6 @@ def plugin_name
130197
@plugin_name ||= @event.at('@pluginName')&.inner_text unless @event.at('@pluginName').inner_text.empty?
131198
end
132199
alias name plugin_name
133-
134200
#
135201
# Return the event object plugin type (plugin_type)
136202
#
@@ -250,6 +316,9 @@ def cvss_base_score
250316
@cvss_base_score ||= @event.at('cvss_base_score')&.inner_text.to_f
251317
end
252318

319+
def cvss3_base_score
320+
@cvss3_base_score ||= @event.at('cvss3_base_score')&.inner_text.to_f
321+
end
253322
#
254323
# Return the event cvss temporal score.
255324
#
@@ -260,6 +329,10 @@ def cvss_temporal_score
260329
@cvss_temporal_score ||= @event.at('cvss_temporal_score')&.inner_text.to_f
261330
end
262331

332+
def cvss3_temporal_score
333+
@cvss_temporal_score ||= @event.at('cvss3_temporal_score')&.inner_text.to_f
334+
end
335+
263336
#
264337
# Return the event cve.
265338
#
@@ -320,17 +393,29 @@ def cvss_vector
320393
@cvss_vector ||= @event.at('cvss_vector')&.inner_text
321394
end
322395

396+
def cvss3_vector
397+
@cvss3_vector ||= @event.at('cvss3_vector')&.inner_text#.gsub("CVSS:3.0/","")
398+
end
399+
400+
def cvss_temporal_vector
401+
@cvss_temporal_vector ||= @event.at('cvss_temporal_vector')&.inner_text
402+
end
403+
404+
def cvss3_temporal_vector
405+
@cvss3_temporal_vector ||= @event.at('cvss3_temporal_vector')&.inner_text#.gsub("CVSS:3.0/","")
406+
end
407+
323408
#
324409
# Return the event cpe.
325410
#
326411
# @return [Array<String>]
327412
# Return the event cpe.
328-
#
413+
#
329414
def cpe
330415
unless @cpe
331416
@cpe = []
332417
@event.xpath('cpe').each do |cpe|
333-
@cpe << cpe.inner_text
418+
@cpe |= cpe.inner_text.split("\n")
334419
end
335420
end
336421
@cpe

lib/ruby-nessus/version2/host.rb

+82-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# frozen_string_literal: true
2-
32
module RubyNessus
43
module Version2
54
class Host
@@ -35,7 +34,9 @@ def name
3534
# host.hostname #=> "example.com"
3635
#
3736
def hostname
38-
@host.at('tag[name=host-fqdn]')&.inner_text
37+
hostname ||= @host.at('tag[name=host-fqdn]')&.inner_text
38+
hostname ||= @host.css("ReportItem[pluginID=55472]").xpath("./plugin_output").text.match(/Hostname : (.*)/)[1]
39+
return hostname
3940
end
4041
alias fqdn hostname
4142
alias dns_name hostname
@@ -151,6 +152,65 @@ def os_name
151152
# @example
152153
# host.open_ports #=> 213
153154
#
155+
#57033
156+
def patch_checked?
157+
if @host.css("ReportItem[pluginID=57033]").empty?
158+
return false
159+
else
160+
return true
161+
end#.xpath('.//plugin_output').inner_text.split(" - ")
162+
end
163+
#TODO
164+
#Add more OS
165+
def os_unsupported?
166+
if @host.css("ReportItem[pluginID=33850]").empty?
167+
return false
168+
else
169+
return true
170+
end#.xpath('.//plugin_output').inner_text.split(" - ")
171+
end
172+
173+
def rhel_missing_patchs
174+
count = 0
175+
@rhel_missing_patches = @host.css("ReportItem[pluginFamily='Red Hat Local Security Checks']").map do |event|
176+
plugin_name ||= event.at('@pluginName')&.inner_text unless event.at('@pluginName').inner_text.empty?
177+
if event['severity'] != 0 and !(plugin_name.match(/(RHEL \d) : (.*) (\(RHSA-\d{4}:\d{1,4}\))/)).nil?
178+
count +=1
179+
Event.new(event)
180+
end
181+
end
182+
@rhel_missing_patches.compact
183+
end
184+
185+
#TODO
186+
def win_missing_patches
187+
count = 0
188+
@missing_patches = @host.css("ReportItem[pluginFamily='Windows : Microsoft Bulletins']").map do |event|
189+
if event['severity'] != 0
190+
count +=1
191+
Event.new(event)
192+
end
193+
end
194+
@missing_patches#.xpath('.//plugin_output').inner_text.split(" - ")
195+
end
196+
197+
def trd_party_software
198+
@host.css("ReportItem[pluginID=38153]").xpath('.//plugin_output').inner_text.split(" - ")
199+
end
200+
201+
def ms_compliance_itens_total
202+
#" asdf"
203+
pp @host.css("ReportItem[pluginID=21156]")#.size
204+
end
205+
206+
def unix_compliance_itens_total
207+
@host.css("ReportItem[pluginID=21157]").size
208+
end
209+
210+
def vcenter_compliance_itens_total
211+
@host.css("ReportItem[pluginID=64455]").size
212+
end
213+
154214
def open_ports
155215
@scanned_ports ||= host_stats[:open_ports].to_i
156216
end
@@ -264,6 +324,7 @@ def critical_severity_events
264324
end
265325
@critical_events
266326
end
327+
267328

268329
#
269330
# Return the total event count for a given host.
@@ -443,6 +504,25 @@ def total_event_count(count_informational = nil)
443504
end
444505
end
445506

507+
508+
#
509+
# Return the List of ESXi hosts that were scanned
510+
#
511+
# @return [Integer]
512+
# The Total Severity Count
513+
#
514+
# @example
515+
# scan.total_event_count #=> 1561
516+
#
517+
def esxi_scanned_hosts
518+
report_items = @host.css("ReportItem[pluginID=12053]")
519+
unless report_items.nil?
520+
reportItem.each do |report_item|
521+
report_item.xpath("./plugin_output").text.strip.gsub(" resolves as ",",")[0..-2].split(",")
522+
end
523+
end
524+
end
525+
446526
#
447527
# Return the Total severity count.
448528
#

lib/ruby-nessus/version2/scan.rb

+27
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,33 @@ def target_hosts
8282
nil
8383
end
8484

85+
#
86+
# Return the hosts the were targeted for the initial scan.
87+
# These are the hosts that were inputed when creating the scan.
88+
#
89+
# @return [Array<String>]
90+
# Array of hosts
91+
#
92+
def report_hosts
93+
hosts = Hash.new()
94+
@xml.xpath('//ReportHost').each do |report_host|
95+
#binding.pry
96+
ip_address = ""
97+
asset_name = ""
98+
operating_system = ""
99+
unless report_host.nil?
100+
report_host.xpath('.//tag').each do |tag|
101+
ip_address = tag.text if tag.attribute_nodes.first.value == "host-ip"
102+
asset_name = tag.text if tag.attribute_nodes.first.value == "host-fqdn"
103+
operating_system = tag.text if tag.attribute_nodes.first.value == "operating-system"
104+
end
105+
#binding.pry
106+
hosts[ip_address] = {"asset_name"=> "#{asset_name}", "operating_system" => operating_system}
107+
end
108+
end
109+
return hosts
110+
end
111+
85112
#
86113
# Creates a new Host object to be parser
87114
#

ruby-nessus.gemspec

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ $LOAD_PATH.push File.expand_path('lib', __dir__)
44

55
Gem::Specification.new do |gem|
66
gem.name = 'ruby-nessus'
7-
gem.version = '2.0.beta'
7+
gem.version = '2.0.1'
88
gem.summary = 'Ruby-Nessus is a ruby interface for the popular Nessus vulnerability scanner.'
99
gem.description = 'Ruby-Nessus aims to deliver an easy yet powerful interface for interacting and manipulating Nessus scan results and configurations.'
1010
gem.licenses = ['MIT']
@@ -18,8 +18,8 @@ Gem::Specification.new do |gem|
1818
gem.require_paths = ['lib']
1919
gem.required_ruby_version = '>= 2.3'
2020

21-
gem.add_dependency 'nokogiri', '~> 1.4'
22-
gem.add_dependency 'rainbow', '>= 2.0'
21+
gem.add_dependency 'nokogiri', '>= 1.10.10'
22+
gem.add_dependency 'rainbow', '>= 3.0'
2323

2424
gem.add_development_dependency 'rspec', '~> 3.7'
2525
gem.add_development_dependency 'rubocop', '~> 0.51'

0 commit comments

Comments
 (0)