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.
Files changed (47) hide show
  1. data/KNOWNISSUES.markdown +50 -0
  2. data/LICENSE +25 -0
  3. data/NEWS.markdown +112 -0
  4. data/README.markdown +126 -0
  5. data/Rakefile +37 -0
  6. data/TODO.markdown +69 -0
  7. data/bin/risu +12 -0
  8. data/lib/nessusdb.rb +38 -0
  9. data/lib/nessusdb/cli.rb +9 -0
  10. data/lib/nessusdb/cli/application.rb +402 -0
  11. data/lib/nessusdb/cli/banner.rb +25 -0
  12. data/lib/nessusdb/exceptions.rb +8 -0
  13. data/lib/nessusdb/exceptions/invaliddocument.rb +10 -0
  14. data/lib/nessusdb/listener.rb +274 -0
  15. data/lib/nessusdb/models.rb +18 -0
  16. data/lib/nessusdb/models/familyselection.rb +12 -0
  17. data/lib/nessusdb/models/host.rb +359 -0
  18. data/lib/nessusdb/models/individualpluginselection.rb +14 -0
  19. data/lib/nessusdb/models/item.rb +183 -0
  20. data/lib/nessusdb/models/plugin.rb +98 -0
  21. data/lib/nessusdb/models/pluginspreference.rb +12 -0
  22. data/lib/nessusdb/models/policy.rb +17 -0
  23. data/lib/nessusdb/models/reference.rb +13 -0
  24. data/lib/nessusdb/models/report.rb +26 -0
  25. data/lib/nessusdb/models/serverpreference.rb +13 -0
  26. data/lib/nessusdb/models/version.rb +12 -0
  27. data/lib/nessusdb/nessusdocument.rb +66 -0
  28. data/lib/nessusdb/parsers.rb +8 -0
  29. data/lib/nessusdb/prawn_templater.rb +38 -0
  30. data/lib/nessusdb/schema.rb +145 -0
  31. data/lib/nessusdb/templates/assets.rb +21 -0
  32. data/lib/nessusdb/templates/cover_sheet.rb +42 -0
  33. data/lib/nessusdb/templates/data/nessuslogo.jpg +0 -0
  34. data/lib/nessusdb/templates/exec_summary.rb +56 -0
  35. data/lib/nessusdb/templates/executive_summary.rb +182 -0
  36. data/lib/nessusdb/templates/finding_statistics.rb +23 -0
  37. data/lib/nessusdb/templates/findings_host.rb +49 -0
  38. data/lib/nessusdb/templates/findings_summary.rb +68 -0
  39. data/lib/nessusdb/templates/findings_summary_with_pluginid.rb +68 -0
  40. data/lib/nessusdb/templates/graphs.rb +33 -0
  41. data/lib/nessusdb/templates/host_summary.rb +40 -0
  42. data/lib/nessusdb/templates/ms_patch_summary.rb +37 -0
  43. data/lib/nessusdb/templates/ms_update_summary.rb +43 -0
  44. data/lib/nessusdb/templates/pci_compliance.rb +66 -0
  45. data/lib/nessusdb/templates/technical_findings.rb +116 -0
  46. data/risu.gemspec +44 -0
  47. 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,12 @@
1
+ # encoding: utf-8
2
+
3
+ module NessusDB
4
+ module Models
5
+ # FamilySelection Model
6
+ #
7
+ # @author Jacob Hammack
8
+ class FamilySelection < ActiveRecord::Base
9
+ belongs_to :policy
10
+ end
11
+ end
12
+ end
@@ -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