risu 1.4.3
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/KNOWNISSUES.markdown +50 -0
- data/LICENSE +25 -0
- data/NEWS.markdown +112 -0
- data/README.markdown +126 -0
- data/Rakefile +37 -0
- data/TODO.markdown +69 -0
- data/bin/risu +12 -0
- data/lib/nessusdb.rb +38 -0
- data/lib/nessusdb/cli.rb +9 -0
- data/lib/nessusdb/cli/application.rb +402 -0
- data/lib/nessusdb/cli/banner.rb +25 -0
- data/lib/nessusdb/exceptions.rb +8 -0
- data/lib/nessusdb/exceptions/invaliddocument.rb +10 -0
- data/lib/nessusdb/listener.rb +274 -0
- data/lib/nessusdb/models.rb +18 -0
- data/lib/nessusdb/models/familyselection.rb +12 -0
- data/lib/nessusdb/models/host.rb +359 -0
- data/lib/nessusdb/models/individualpluginselection.rb +14 -0
- data/lib/nessusdb/models/item.rb +183 -0
- data/lib/nessusdb/models/plugin.rb +98 -0
- data/lib/nessusdb/models/pluginspreference.rb +12 -0
- data/lib/nessusdb/models/policy.rb +17 -0
- data/lib/nessusdb/models/reference.rb +13 -0
- data/lib/nessusdb/models/report.rb +26 -0
- data/lib/nessusdb/models/serverpreference.rb +13 -0
- data/lib/nessusdb/models/version.rb +12 -0
- data/lib/nessusdb/nessusdocument.rb +66 -0
- data/lib/nessusdb/parsers.rb +8 -0
- data/lib/nessusdb/prawn_templater.rb +38 -0
- data/lib/nessusdb/schema.rb +145 -0
- data/lib/nessusdb/templates/assets.rb +21 -0
- data/lib/nessusdb/templates/cover_sheet.rb +42 -0
- data/lib/nessusdb/templates/data/nessuslogo.jpg +0 -0
- data/lib/nessusdb/templates/exec_summary.rb +56 -0
- data/lib/nessusdb/templates/executive_summary.rb +182 -0
- data/lib/nessusdb/templates/finding_statistics.rb +23 -0
- data/lib/nessusdb/templates/findings_host.rb +49 -0
- data/lib/nessusdb/templates/findings_summary.rb +68 -0
- data/lib/nessusdb/templates/findings_summary_with_pluginid.rb +68 -0
- data/lib/nessusdb/templates/graphs.rb +33 -0
- data/lib/nessusdb/templates/host_summary.rb +40 -0
- data/lib/nessusdb/templates/ms_patch_summary.rb +37 -0
- data/lib/nessusdb/templates/ms_update_summary.rb +43 -0
- data/lib/nessusdb/templates/pci_compliance.rb +66 -0
- data/lib/nessusdb/templates/technical_findings.rb +116 -0
- data/risu.gemspec +44 -0
- metadata +247 -0
@@ -0,0 +1,274 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "nessusdb"
|
4
|
+
|
5
|
+
module NessusDB
|
6
|
+
|
7
|
+
# NessusSaxListener
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# @author Jacob Hammack <jacob.hammack@hammackj.com>
|
11
|
+
class NessusSaxListener
|
12
|
+
include LibXML::XML::SaxParser::Callbacks
|
13
|
+
|
14
|
+
# Sets up a array of all valid xml fields
|
15
|
+
#
|
16
|
+
#
|
17
|
+
def initialize
|
18
|
+
@vals = Hash.new
|
19
|
+
|
20
|
+
@valid_elements = Array["see_also", "cve", "ReportItem", "xref", "bid", "plugin_version", "risk_factor",
|
21
|
+
"description", "cvss_base_score", "solution", "item", "plugin_output", "tag", "synopsis", "plugin_modification_date",
|
22
|
+
"FamilyName", "FamilyItem", "Status", "vuln_publication_date", "ReportHost", "HostProperties", "preferenceName",
|
23
|
+
"preferenceValues", "preferenceType", "fullName", "pluginId", "pluginName", "selectedValue", "selectedValue",
|
24
|
+
"name", "value", "preference", "plugin_publication_date", "cvss_vector", "patch_publication_date",
|
25
|
+
"NessusClientData_v2", "Policy", "PluginName", "ServerPreferences", "policyComments", "policyName", "PluginItem",
|
26
|
+
"Report", "Family", "Preferences", "PluginsPreferences", "FamilySelection", "IndividualPluginSelection", "PluginId",
|
27
|
+
"pci-dss-compliance", "exploitability_ease", "cvss_temporal_vector", "exploit_framework_core", "cvss_temporal_score",
|
28
|
+
"exploit_available", "metasploit_name", "exploit_framework_canvas", "canvas_package", "exploit_framework_metasploit",
|
29
|
+
"plugin_type", "cpe"]
|
30
|
+
|
31
|
+
# This makes adding new host properties really easy.
|
32
|
+
@valid_host_properties = {
|
33
|
+
"HOST_END" => :end ,
|
34
|
+
"mac-address" => :mac ,
|
35
|
+
"HOST_START" => :start ,
|
36
|
+
"operating-system" => :os,
|
37
|
+
"host-ip" => :ip ,
|
38
|
+
"host-fqdn" => :fqdn ,
|
39
|
+
"netbios-name" => :netbios ,
|
40
|
+
"local-checks-proto" => :local_checks_proto ,
|
41
|
+
"smb-login-used" => :smb_login_used ,
|
42
|
+
"ssh-auth-meth" => :ssh_auth_meth ,
|
43
|
+
"ssh-login-used" => :ssh_login_used ,
|
44
|
+
"pci-dss-compliance" => :pci_dss_compliance ,
|
45
|
+
"pci-dss-compliance:" => :pci_dss_compliance_ ,
|
46
|
+
"pcidss:compliance:failed" => :pcidss_compliance_failed,
|
47
|
+
"pcidss:compliance:passed" => :pcidss_compliance_passed,
|
48
|
+
"pcidss:deprecated_ssl" => :pcidss_deprecated_ssl,
|
49
|
+
"pcidss:expired_ssl_certificate" => :pcidss_expired_ssl_certificate,
|
50
|
+
"pcidss:high_risk_flaw" => :pcidss_high_risk_flaw,
|
51
|
+
"pcidss:medium_risk_flaw" => :pcidss_medium_risk_flaw,
|
52
|
+
"pcidss:reachable_db" => :pcidss_reachable_db,
|
53
|
+
"pcidss:www:xss" => :pcidss_www_xss
|
54
|
+
}
|
55
|
+
|
56
|
+
@valid_ms_patches = {
|
57
|
+
"MS11-030" => :ms11_030,
|
58
|
+
"MS11-026" => :ms11_026,
|
59
|
+
"MS11-034" => :ms11_034,
|
60
|
+
"MS11-021" => :ms11_021,
|
61
|
+
"MS11-029" => :ms11_029,
|
62
|
+
"MS11-023" => :ms11_023,
|
63
|
+
"MS11-022" => :ms11_022,
|
64
|
+
"MS09-027" => :ms09_027,
|
65
|
+
"MS11-033" => :ms11_033,
|
66
|
+
"MS11-019" => :ms11_019,
|
67
|
+
"MS11-024" => :ms11_024,
|
68
|
+
"MS11-031" => :ms11_031,
|
69
|
+
"MS11-020" => :ms11_020,
|
70
|
+
"MS11-018" => :ms11_018,
|
71
|
+
"MS11-028" => :ms11_028,
|
72
|
+
"MS11-032" => :ms11_032
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Callback for when the start of a xml element is reached
|
77
|
+
#
|
78
|
+
# @param element
|
79
|
+
# @param attributes
|
80
|
+
def on_start_element(element, attributes)
|
81
|
+
@tag = element
|
82
|
+
@vals[@tag] = ""
|
83
|
+
|
84
|
+
if !@valid_elements.include?(element)
|
85
|
+
puts "New XML element detected: #{element}. Please report this to #{NessusDB::EMAIL}"
|
86
|
+
end
|
87
|
+
|
88
|
+
case element
|
89
|
+
when "Policy"
|
90
|
+
@policy = NessusDB::Models::Policy.create
|
91
|
+
@policy.save
|
92
|
+
when "preference"
|
93
|
+
@sp = @policy.server_preferences.create
|
94
|
+
@sp.save
|
95
|
+
when "item"
|
96
|
+
@item = @policy.plugins_preferences.create
|
97
|
+
@item.save
|
98
|
+
when "FamilyItem"
|
99
|
+
@family = @policy.family_selections.create
|
100
|
+
@family.save
|
101
|
+
when "PluginItem"
|
102
|
+
@plugin_selection = @policy.individual_plugin_selections.create
|
103
|
+
@plugin_selection.save
|
104
|
+
when "Report"
|
105
|
+
@report = @policy.reports.create
|
106
|
+
@report.name = attributes["name"]
|
107
|
+
@report.save
|
108
|
+
when "ReportHost"
|
109
|
+
@rh = @report.hosts.create
|
110
|
+
@rh.name = attributes["name"]
|
111
|
+
@rh.save
|
112
|
+
when "tag"
|
113
|
+
unless attributes["name"] =~ /(MS\d\d-\d\d\d)/
|
114
|
+
@attr = if @valid_host_properties.keys.include?(attributes["name"])
|
115
|
+
attributes["name"]
|
116
|
+
else
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
puts "New HostProperties attribute: #{attributes["name"]}. Please report this to jacob.hammack@hammackj.com\n" if @attr.nil?
|
120
|
+
end
|
121
|
+
when "ReportItem"
|
122
|
+
@vals = Hash.new # have to clear this out or everything has the same references
|
123
|
+
@ri = @rh.items.create
|
124
|
+
if attributes["pluginID"] == "0"
|
125
|
+
@plugin = NessusDB::Models::Plugin.find_or_create_by_id(1)
|
126
|
+
else
|
127
|
+
@plugin = NessusDB::Models::Plugin.find_or_create_by_id(attributes["pluginID"])
|
128
|
+
end
|
129
|
+
|
130
|
+
@ri.port = attributes["port"]
|
131
|
+
@ri.svc_name = attributes["svc_name"]
|
132
|
+
@ri.protocol = attributes["protocol"]
|
133
|
+
@ri.severity = attributes["severity"]
|
134
|
+
|
135
|
+
@ri.plugin_id = @plugin.id
|
136
|
+
@plugin.plugin_name = attributes["pluginName"]
|
137
|
+
@plugin.family_name = attributes["pluginFamily"]
|
138
|
+
@plugin.save
|
139
|
+
@ri.save
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Called when the inner text of a element is reached
|
144
|
+
#
|
145
|
+
# @param text
|
146
|
+
def on_characters(text)
|
147
|
+
if @vals[@tag] == nil then
|
148
|
+
@vals[@tag] = text
|
149
|
+
else
|
150
|
+
@vals[@tag] << text
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Called when the end of the xml element is reached
|
155
|
+
#
|
156
|
+
# @param element
|
157
|
+
def on_end_element(element)
|
158
|
+
@tag = nil
|
159
|
+
case element
|
160
|
+
when "policyName"
|
161
|
+
@policy.attributes = {
|
162
|
+
:name => @vals["policyName"]
|
163
|
+
}
|
164
|
+
|
165
|
+
@policy.save
|
166
|
+
when "policyComments"
|
167
|
+
@policy.attributes = {
|
168
|
+
:comments => @vals["policyComments"]
|
169
|
+
}
|
170
|
+
|
171
|
+
@policy.save
|
172
|
+
when "preference"
|
173
|
+
@sp.attributes = {
|
174
|
+
:name => @vals["name"],
|
175
|
+
:value => @vals["value"]
|
176
|
+
}
|
177
|
+
@sp.save
|
178
|
+
|
179
|
+
#This takes a really long time, there is about 34,000 pluginIDs in this
|
180
|
+
#field and it takes about 36 minutes to parse just this info =\
|
181
|
+
#lets prepopulate the plugins table with the known pluginid's
|
182
|
+
#if @vals["name"] == "plugin_set"
|
183
|
+
# @all_plugins = @vals["value"].split(";")
|
184
|
+
#
|
185
|
+
# @all_plugins.each { |p|
|
186
|
+
# @plug = Plugin.find_or_create_by_id(p)
|
187
|
+
# @plug.save
|
188
|
+
# }
|
189
|
+
#end
|
190
|
+
when "item"
|
191
|
+
@item.attributes = {
|
192
|
+
:plugin_name => @vals["pluginName"],
|
193
|
+
:plugin_id => @vals["pluginId"],
|
194
|
+
:fullname => @vals["fullName"],
|
195
|
+
:preference_name => @vals["preferenceName"],
|
196
|
+
:preference_type => @vals["preferenceType"],
|
197
|
+
:preference_values => @vals["preferenceValues"],
|
198
|
+
:selected_values => @vals["selectedValue"]
|
199
|
+
}
|
200
|
+
|
201
|
+
@item.save
|
202
|
+
when "FamilyItem"
|
203
|
+
@family.attributes = {
|
204
|
+
:family_name => @vals["FamilyName"],
|
205
|
+
:status => @vals["Status"]
|
206
|
+
}
|
207
|
+
|
208
|
+
@family.save
|
209
|
+
when "PluginItem"
|
210
|
+
@plugin_selection.attributes = {
|
211
|
+
:plugin_id => @vals["PluginId"],
|
212
|
+
:plugin_name => @vals["PluginName"],
|
213
|
+
:family => @vals["Family"],
|
214
|
+
:status => @vals["Status"]
|
215
|
+
}
|
216
|
+
|
217
|
+
@plugin_selection.save
|
218
|
+
when "tag"
|
219
|
+
@rh.attributes = {@valid_host_properties[@attr] => @vals["tag"].gsub("\n", ",") } if @valid_host_properties.keys.include?(@attr)
|
220
|
+
@rh.save
|
221
|
+
#We cannot handle the references in the same block as the rest of the ReportItem tag because
|
222
|
+
#there tends to be more than of the different types of reference per ReportItem, this causes issue for a sax
|
223
|
+
#parser. To solve this we do the references before the final plugin data
|
224
|
+
when "cve"
|
225
|
+
@cve = @plugin.references.create
|
226
|
+
@cve.reference_name = "cve"
|
227
|
+
@cve.value = @vals["cve"]
|
228
|
+
@cve.save
|
229
|
+
when "bid"
|
230
|
+
@bid = @plugin.references.create
|
231
|
+
@bid.reference_name = "bid"
|
232
|
+
@bid.value = @vals["bid"]
|
233
|
+
@bid.save
|
234
|
+
when "see_also"
|
235
|
+
@see_also = @plugin.references.create
|
236
|
+
@see_also.reference_name = "see_also"
|
237
|
+
@see_also.value = @vals["see_also"]
|
238
|
+
@see_also.save
|
239
|
+
when "xref"
|
240
|
+
@xref = @plugin.references.create
|
241
|
+
@xref.reference_name = "xref"
|
242
|
+
@xref.value = @vals["xref"]
|
243
|
+
@xref.save
|
244
|
+
when "ReportItem"
|
245
|
+
@ri.plugin_output = @vals["plugin_output"]
|
246
|
+
@ri.save
|
247
|
+
|
248
|
+
@plugin.attributes = {
|
249
|
+
:solution => @vals["solution"],
|
250
|
+
:risk_factor => @vals["risk_factor"],
|
251
|
+
:description => @vals["description"],
|
252
|
+
:plugin_publication_date => @vals["plugin_publication_date"],
|
253
|
+
:synopsis => @vals["synopsis"],
|
254
|
+
:plugin_type => @vals["plugin_type"],
|
255
|
+
:cvss_vector => @vals["cvss_vector"],
|
256
|
+
:cvss_base_score => @vals["cvss_base_score"],
|
257
|
+
:vuln_publication_date => @vals["vuln_publication_date"],
|
258
|
+
:plugin_version => @vals["plugin_version"],
|
259
|
+
:cvss_temporal_score => @vals["cvss_temporal_score"],
|
260
|
+
:cvss_temporal_vector => @vals["cvss_temporal_vector"],
|
261
|
+
:exploitability_ease => @vals["exploitability_ease"],
|
262
|
+
:exploit_framework_core => @vals["exploit_framework_core"],
|
263
|
+
:exploit_available => @vals["exploit_available"],
|
264
|
+
:exploit_framework_metasploit => @vals["exploit_framework_metasploit"],
|
265
|
+
:metasploit_name => @vals["metasploit_name"],
|
266
|
+
:exploit_framework_canvas => @vals["exploit_framework_canvas"],
|
267
|
+
:canvas_package => @vals["canvas_package"],
|
268
|
+
:cpe => @vals["cpe"]
|
269
|
+
}
|
270
|
+
@plugin.save
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module NessusDB
|
4
|
+
module Models
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'nessusdb/models/host'
|
9
|
+
require 'nessusdb/models/familyselection'
|
10
|
+
require 'nessusdb/models/item'
|
11
|
+
require 'nessusdb/models/individualpluginselection'
|
12
|
+
require 'nessusdb/models/plugin'
|
13
|
+
require 'nessusdb/models/pluginspreference'
|
14
|
+
require 'nessusdb/models/serverpreference'
|
15
|
+
require 'nessusdb/models/report'
|
16
|
+
require 'nessusdb/models/reference'
|
17
|
+
require 'nessusdb/models/policy'
|
18
|
+
require 'nessusdb/models/version'
|
@@ -0,0 +1,359 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module NessusDB
|
4
|
+
module Models
|
5
|
+
# Host Model
|
6
|
+
#
|
7
|
+
# @author Jacob Hammack <jacob.hammack@hammackj.com>
|
8
|
+
class Host < ActiveRecord::Base
|
9
|
+
belongs_to :report
|
10
|
+
has_many :items
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
#
|
15
|
+
#
|
16
|
+
#
|
17
|
+
#def hosts_with_blacklist blacklist_hosts_id
|
18
|
+
# if blacklist_host_id == nil
|
19
|
+
# where("id != ?", blacklist_host_id).count
|
20
|
+
# else
|
21
|
+
# count
|
22
|
+
# end
|
23
|
+
#end
|
24
|
+
|
25
|
+
# Sorts all of the hosts where the ip address is not null
|
26
|
+
#
|
27
|
+
# @return [Array] With all the Ip's in sorted order
|
28
|
+
def sorted
|
29
|
+
hosts = Host.where("ip is not NULL").order("ip").all
|
30
|
+
|
31
|
+
#Sort the ips in natural order.
|
32
|
+
hosts.sort! do |a,b|
|
33
|
+
ip1 = IPAddr.new a.ip
|
34
|
+
ip2 = IPAddr.new b.ip
|
35
|
+
|
36
|
+
ip1 <=> ip2
|
37
|
+
end
|
38
|
+
|
39
|
+
return hosts
|
40
|
+
end
|
41
|
+
|
42
|
+
# Queries for hosts with a Windows based Operating System
|
43
|
+
#
|
44
|
+
# @return [ActiveRecord::Relation] with the query results
|
45
|
+
def os_windows
|
46
|
+
where("os LIKE '%Windows%'")#.group(:os)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Negation query for all hosts with a Windows based Operating system
|
50
|
+
#
|
51
|
+
# @return [ActiveRecord::Relation] with the query results
|
52
|
+
def not_os_windows
|
53
|
+
where("os NOT LIKE '%Windows%'")
|
54
|
+
end
|
55
|
+
|
56
|
+
# Queries for hosts with a Windows NT based Operating System
|
57
|
+
#
|
58
|
+
# @return [ActiveRecord::Relation] with the query results
|
59
|
+
def os_windows_nt
|
60
|
+
where("os LIKE '%Windows NT%'")
|
61
|
+
end
|
62
|
+
|
63
|
+
# Negation query for all hosts with a Windows NT based Operating system
|
64
|
+
#
|
65
|
+
# @return [ActiveRecord::Relation] with the query results
|
66
|
+
def not_os_windows_nt
|
67
|
+
where("os NOT LIKE '%Windows NT%'")
|
68
|
+
end
|
69
|
+
|
70
|
+
# Queries for hosts with a Windows 2000 based Operating System
|
71
|
+
#
|
72
|
+
# @return [ActiveRecord::Relation] with the query results
|
73
|
+
def os_windows_2k
|
74
|
+
where("os LIKE '%Windows 2000%'")
|
75
|
+
end
|
76
|
+
|
77
|
+
# Negation query for all hosts with a Windows 2000 based Operating system
|
78
|
+
#
|
79
|
+
# @return [ActiveRecord::Relation] with the query results
|
80
|
+
def not_os_windows_2k
|
81
|
+
where("os NOT LIKE '%Windows 2000%'")
|
82
|
+
end
|
83
|
+
|
84
|
+
# Queries for hosts with a Windows XP based Operating System
|
85
|
+
#
|
86
|
+
# @return [ActiveRecord::Relation] with the query results
|
87
|
+
def os_windows_xp
|
88
|
+
where("os LIKE '%Windows XP%'")
|
89
|
+
end
|
90
|
+
|
91
|
+
# Negation query for all hosts with a Windows XP based Operating system
|
92
|
+
#
|
93
|
+
# @return [ActiveRecord::Relation] with the query results
|
94
|
+
def not_os_windows_xp
|
95
|
+
where("os NOT LIKE '%Windows XP%'")
|
96
|
+
end
|
97
|
+
|
98
|
+
# Queries for hosts with a Windows Server 2003 based Operating System
|
99
|
+
#
|
100
|
+
# @return [ActiveRecord::Relation] with the query results
|
101
|
+
def os_windows_2k3
|
102
|
+
where("os LIKE '%Windows Server 2003%'")
|
103
|
+
end
|
104
|
+
|
105
|
+
# Negation query for all hosts with a Windows Server 2003 based Operating system
|
106
|
+
#
|
107
|
+
# @return [ActiveRecord::Relation] with the query results
|
108
|
+
def not_os_windows_2k3
|
109
|
+
where("os NOT LIKE '%Windows Server 2003%'")
|
110
|
+
end
|
111
|
+
|
112
|
+
# Queries for hosts with a Windows Vista based Operating System
|
113
|
+
#
|
114
|
+
# @return [ActiveRecord::Relation] with the query results
|
115
|
+
def os_windows_vista
|
116
|
+
where("os LIKE '%Windows Vista%'")
|
117
|
+
end
|
118
|
+
|
119
|
+
# Negation query for all hosts with a Windows Vista based Operating system
|
120
|
+
#
|
121
|
+
# @return [ActiveRecord::Relation] with the query results
|
122
|
+
def not_os_windows_vista
|
123
|
+
where("os NOT LIKE '%Windows Vista%'")
|
124
|
+
end
|
125
|
+
|
126
|
+
# Queries for hosts with a Windows Server 2008 based Operating System
|
127
|
+
#
|
128
|
+
# @return [ActiveRecord::Relation] with the query results
|
129
|
+
def os_windows_2k8
|
130
|
+
where("os LIKE '%Windows Server 2008%'")
|
131
|
+
end
|
132
|
+
|
133
|
+
def not_os_windows_2k8
|
134
|
+
where("os NOT LIKE '%Windows Server 2008%'")
|
135
|
+
end
|
136
|
+
|
137
|
+
# Queries for hosts with a Windows 7 based Operating System
|
138
|
+
#
|
139
|
+
# @return [ActiveRecord::Relation] with the query results
|
140
|
+
def os_windows_7
|
141
|
+
where("os LIKE '%Windows 7%'")
|
142
|
+
end
|
143
|
+
|
144
|
+
# Negation query for all hosts with a Windows 7 based Operating system
|
145
|
+
#
|
146
|
+
# @return [ActiveRecord::Relation] with the query results
|
147
|
+
def not_os_windows_7
|
148
|
+
where("os NOT LIKE '%Windows 7%'")
|
149
|
+
end
|
150
|
+
|
151
|
+
# Queries for hosts with a Windows Operating System that are not 2000,
|
152
|
+
# XP, 2003, Vista, 2008 or 7
|
153
|
+
#
|
154
|
+
# @return [ActiveRecord::Relation] with the query results
|
155
|
+
def os_windows_other
|
156
|
+
not_os_windows_7.not_os_windows_2k8.not_os_windows_vista.not_os_windows_2k3.not_os_windows_xp.not_os_windows_2k.not_os_windows_nt
|
157
|
+
end
|
158
|
+
|
159
|
+
# Queries for all hosts with a Linux based Operating system
|
160
|
+
#
|
161
|
+
# @return [ActiveRecord::Relation] with the query results
|
162
|
+
def os_linux
|
163
|
+
where("os LIKE '%Linux%'")
|
164
|
+
end
|
165
|
+
|
166
|
+
# Negation query for all hosts with a Linux based Operating system
|
167
|
+
#
|
168
|
+
# @return [ActiveRecord::Relation] with the query results
|
169
|
+
def not_os_linux
|
170
|
+
where("os NOT LIKE '%Linux%'")
|
171
|
+
end
|
172
|
+
|
173
|
+
# Queries for all hosts with a FreeBSD based Operating system
|
174
|
+
#
|
175
|
+
# @return [ActiveRecord::Relation] with the query results
|
176
|
+
def os_freebsd
|
177
|
+
where("os LIKE '%FreeBSD%'")
|
178
|
+
end
|
179
|
+
|
180
|
+
# Negation query for all hosts with a FreeBSD based Operating system
|
181
|
+
#
|
182
|
+
# @return [ActiveRecord::Relation] with the query results
|
183
|
+
def not_os_freebsd
|
184
|
+
where("os NOT LIKE '%FreeBSD%'")
|
185
|
+
end
|
186
|
+
|
187
|
+
# Queries for all hosts with a NetBSD based Operating system
|
188
|
+
#
|
189
|
+
# @return [ActiveRecord::Relation] with the query results
|
190
|
+
def os_netbsd
|
191
|
+
where("os LIKE '%NetBsd%'")
|
192
|
+
end
|
193
|
+
|
194
|
+
# Negation query for all hosts with a NETbsd based Operating system
|
195
|
+
#
|
196
|
+
# @return [ActiveRecord::Relation] with the query results
|
197
|
+
def not_os_netbsd
|
198
|
+
where("os NOT LIKE '%NetBsd%'")
|
199
|
+
end
|
200
|
+
|
201
|
+
# Queries for all hosts with a Cisco IOS based Operating system
|
202
|
+
#
|
203
|
+
# @return [ActiveRecord::Relation] with the query results
|
204
|
+
def os_cisco
|
205
|
+
where("os LIKE '%CISCO%'")
|
206
|
+
end
|
207
|
+
|
208
|
+
# Negation query for all hosts with a Cisco based Operating system
|
209
|
+
#
|
210
|
+
# @return [ActiveRecord::Relation] with the query results
|
211
|
+
def not_os_cisco
|
212
|
+
where("os NOT LIKE '%CISCO%'")
|
213
|
+
end
|
214
|
+
|
215
|
+
# Queries for all hosts with a VXWorks based Operating system
|
216
|
+
#
|
217
|
+
# @return [ActiveRecord::Relation] with the query results
|
218
|
+
def os_vxworks
|
219
|
+
where("os LIKE '%VxWorks%'")
|
220
|
+
end
|
221
|
+
|
222
|
+
# Negation query for all hosts with a VXWorks based Operating system
|
223
|
+
#
|
224
|
+
# @return [ActiveRecord::Relation] with the query results
|
225
|
+
def not_os_vxworks
|
226
|
+
where("os NOT LIKE '%VxWorks%'")
|
227
|
+
end
|
228
|
+
|
229
|
+
# Queries for all hosts with a VMware ESX based Operating system
|
230
|
+
#
|
231
|
+
# @return [ActiveRecord::Relation] with the query results
|
232
|
+
def os_vmware_esx
|
233
|
+
where("os LIKE '%VMware ESX%'")
|
234
|
+
end
|
235
|
+
|
236
|
+
# Negation query for all hosts with a VMware ESX based Operating system
|
237
|
+
#
|
238
|
+
# @return [ActiveRecord::Relation] with the query results
|
239
|
+
def not_os_vmware_esx
|
240
|
+
where("os NOT LIKE '%VMware ESX%'")
|
241
|
+
end
|
242
|
+
|
243
|
+
# Queries for all hosts with a Mac OSX based Operating system
|
244
|
+
#
|
245
|
+
# @return [ActiveRecord::Relation] with the query results
|
246
|
+
def os_osx
|
247
|
+
where("os LIKE '%Mac OS X%'")
|
248
|
+
end
|
249
|
+
|
250
|
+
# Negation query for all hosts with a Mac OSX based Operating system
|
251
|
+
#
|
252
|
+
# @return [ActiveRecord::Relation] with the query results
|
253
|
+
def not_os_osx
|
254
|
+
where("os NOT LIKE '%Mac OS X%'")
|
255
|
+
end
|
256
|
+
|
257
|
+
# Queries for all hosts with a Unknown Operating system
|
258
|
+
#
|
259
|
+
# @return [ActiveRecord::Relation] with the query results
|
260
|
+
def os_other
|
261
|
+
not_os_osx.not_os_linux.not_os_netbsd.not_os_freebsd.not_os_cisco.not_os_vxworks.not_os_vmware_esx.not_os_windows
|
262
|
+
end
|
263
|
+
|
264
|
+
# Generates a graph of the high and medium findings count per host
|
265
|
+
#
|
266
|
+
# @return [StringIO] Binary image object of the results
|
267
|
+
def top_vuln_graph(limit=10)
|
268
|
+
g = Gruff::Bar.new(GRAPH_WIDTH)
|
269
|
+
g.title = sprintf "Top %d High/Medium Finding Count Per Host ", Item.risks_by_host(limit).all.count
|
270
|
+
g.sort = false
|
271
|
+
g.theme = {
|
272
|
+
:colors => %w(red green blue orange yellow purple black grey brown pink),
|
273
|
+
:background_colors => %w(white white)
|
274
|
+
}
|
275
|
+
|
276
|
+
Item.risks_by_host(limit).all.each do |item|
|
277
|
+
ip = Host.find_by_id(item.host_id).name
|
278
|
+
count = Item.where(:host_id => item.host_id).where("severity IN (?)", [2,3]).count
|
279
|
+
|
280
|
+
g.data(ip, count)
|
281
|
+
end
|
282
|
+
|
283
|
+
StringIO.new(g.to_blob)
|
284
|
+
end
|
285
|
+
|
286
|
+
# Graphs the percentage of other "non Windows" Operating Systems
|
287
|
+
#
|
288
|
+
# @return [StringIO] Binary image object of the results
|
289
|
+
def other_os_graph
|
290
|
+
g = Gruff::Pie.new(GRAPH_WIDTH)
|
291
|
+
g.title = "Other Operating Systems Percentage"
|
292
|
+
g.sort = false
|
293
|
+
g.theme = {
|
294
|
+
:colors => %w(red green blue orange yellow purple black grey brown pink),
|
295
|
+
:background_colors => %w(white white)
|
296
|
+
}
|
297
|
+
|
298
|
+
linux = Host.os_linux.all.count
|
299
|
+
osx = Host.os_osx.all.count
|
300
|
+
freebsd = Host.os_freebsd.all.count
|
301
|
+
netbsd = Host.os_netbsd.all.count
|
302
|
+
cisco = Host.os_cisco.all.count
|
303
|
+
vxworks = Host.os_vxworks.all.count
|
304
|
+
esx = Host.os_vmware_esx.all.count
|
305
|
+
other = Host.os_other.all.count
|
306
|
+
|
307
|
+
g.data("Linux", linux) unless linux == 0
|
308
|
+
g.data("OSX", osx) unless osx == 0
|
309
|
+
g.data("FreeBSD", freebsd) unless freebsd == 0
|
310
|
+
g.data("NetBSD", netbsd) unless netbsd == 0
|
311
|
+
g.data("Cisco ISO", cisco) unless cisco == 0
|
312
|
+
g.data("VxWorks", vxworks) unless vxworks == 0
|
313
|
+
g.data("VMware", esx) unless esx == 0
|
314
|
+
g.data("Other", other) unless other == 0
|
315
|
+
|
316
|
+
#Creates very odd graphs
|
317
|
+
#Host.os_other.each do |host|
|
318
|
+
# g.data(host.os, Host.where(:os => host.os).count) unless host.os == nil
|
319
|
+
#end
|
320
|
+
|
321
|
+
StringIO.new(g.to_blob)
|
322
|
+
end
|
323
|
+
|
324
|
+
# Graphs the percentage of Windows Operating Systems
|
325
|
+
#
|
326
|
+
# @return [StringIO] Binary image object of the results
|
327
|
+
def windows_os_graph
|
328
|
+
g = Gruff::Pie.new(GRAPH_WIDTH)
|
329
|
+
g.title = "Windows Operating Systems By Percentage"
|
330
|
+
g.sort = false
|
331
|
+
g.theme = {
|
332
|
+
:colors => %w(red green blue orange yellow purple black grey brown pink),
|
333
|
+
:background_colors => %w(white white)
|
334
|
+
}
|
335
|
+
|
336
|
+
nt = Host.os_windows_nt.all.count
|
337
|
+
w2k = Host.os_windows_2k.all.count
|
338
|
+
xp = Host.os_windows_xp.all.count
|
339
|
+
w2k3 = Host.os_windows_2k3.all.count
|
340
|
+
vista = Host.os_windows_vista.all.count
|
341
|
+
w2k8 = Host.os_windows_2k8.all.count
|
342
|
+
w7 = Host.os_windows_7.all.count
|
343
|
+
other = (Host.os_windows.os_windows_other).all.count
|
344
|
+
|
345
|
+
g.data("NT", nt) unless nt == 0
|
346
|
+
g.data("2000", w2k) unless w2k == 0
|
347
|
+
g.data("XP", xp) unless xp == 0
|
348
|
+
g.data("Server 2003", w2k3) unless w2k3 == 0
|
349
|
+
g.data("Vista", vista) unless vista == 0
|
350
|
+
g.data("Server 2008", w2k8) unless w2k8 == 0
|
351
|
+
g.data("7", w7) unless w7 == 0
|
352
|
+
g.data("Other Windows", other) unless other == 0
|
353
|
+
|
354
|
+
StringIO.new(g.to_blob)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|