risu 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/Gemfile.ci +2 -5
  2. data/KNOWNISSUES.markdown +12 -11
  3. data/LICENSE +11 -11
  4. data/NEWS.markdown +43 -8
  5. data/README.markdown +36 -32
  6. data/Rakefile +29 -9
  7. data/TODO.markdown +150 -77
  8. data/bin/risu +26 -0
  9. data/lib/risu.rb +27 -1
  10. data/lib/risu/base.rb +26 -0
  11. data/lib/risu/base/prawn_templater.rb +36 -8
  12. data/lib/risu/base/schema.rb +199 -163
  13. data/lib/risu/base/template_base.rb +34 -7
  14. data/lib/risu/base/template_manager.rb +37 -37
  15. data/lib/risu/base/templater.rb +36 -9
  16. data/lib/risu/cli.rb +26 -0
  17. data/lib/risu/cli/application.rb +72 -39
  18. data/lib/risu/cli/banner.rb +47 -21
  19. data/lib/risu/exceptions.rb +26 -0
  20. data/lib/risu/exceptions/invaliddocument.rb +30 -1
  21. data/lib/risu/models.rb +26 -0
  22. data/lib/risu/models/familyselection.rb +28 -2
  23. data/lib/risu/models/host.rb +59 -2
  24. data/lib/risu/models/individualpluginselection.rb +26 -1
  25. data/lib/risu/models/item.rb +132 -79
  26. data/lib/risu/models/patch.rb +26 -1
  27. data/lib/risu/models/plugin.rb +28 -2
  28. data/lib/risu/models/pluginspreference.rb +26 -2
  29. data/lib/risu/models/policy.rb +27 -2
  30. data/lib/risu/models/reference.rb +81 -20
  31. data/lib/risu/models/report.rb +33 -8
  32. data/lib/risu/models/serverpreference.rb +26 -1
  33. data/lib/risu/models/servicedescription.rb +26 -1
  34. data/lib/risu/models/version.rb +26 -1
  35. data/lib/risu/parsers.rb +29 -0
  36. data/lib/risu/parsers/nessus/nessus_document.rb +47 -14
  37. data/lib/risu/parsers/nessus/nessus_sax_listener.rb +45 -16
  38. data/lib/risu/parsers/nexpose/nexpose_document.rb +91 -0
  39. data/lib/risu/parsers/nexpose/simple_nexpose.rb +108 -0
  40. data/lib/risu/renderers.rb +26 -0
  41. data/lib/risu/renderers/nilrenderer.rb +30 -4
  42. data/lib/risu/templates/assets.rb +36 -10
  43. data/lib/risu/templates/cover_sheet.rb +34 -8
  44. data/lib/risu/templates/exec_summary.rb +45 -19
  45. data/lib/risu/templates/executive_summary.rb +37 -11
  46. data/lib/risu/templates/finding_statistics.rb +33 -7
  47. data/lib/risu/templates/findings_host.rb +44 -18
  48. data/lib/risu/templates/findings_summary.rb +43 -17
  49. data/lib/risu/templates/findings_summary_with_pluginid.rb +60 -18
  50. data/lib/risu/templates/graphs.rb +30 -0
  51. data/lib/risu/templates/host_summary.rb +34 -8
  52. data/lib/risu/templates/ms_patch_summary.rb +35 -9
  53. data/lib/risu/templates/ms_update_summary.rb +34 -8
  54. data/lib/risu/templates/ms_wsus_findings.rb +99 -0
  55. data/lib/risu/templates/notable.rb +39 -13
  56. data/lib/risu/templates/notable_detailed.rb +42 -16
  57. data/lib/risu/templates/pci_compliance.rb +40 -14
  58. data/lib/risu/templates/stig_findings_summary.rb +62 -36
  59. data/lib/risu/templates/technical_findings.rb +29 -3
  60. data/lib/risu/templates/template.rb +35 -9
  61. data/risu.gemspec +28 -7
  62. metadata +94 -101
@@ -1,4 +1,30 @@
1
- #Cool random banner stuff for the cli, based on the metasploit random banner stuff
1
+ # Copyright (c) 2010-2012 Arxopia LLC.
2
+ # All rights reserved.
3
+
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+
7
+ # * Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright
10
+ # notice, this list of conditions and the following disclaimer in the
11
+ # documentation and/or other materials provided with the distribution.
12
+ # * Neither the name of the Arxopia LLC nor the names of its contributors
13
+ # may be used to endorse or promote products derived from this software
14
+ # without specific prior written permission.
15
+
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL ARXOPIA LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22
+ # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24
+ #OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25
+ #OF THE POSSIBILITY OF SUCH DAMAGE.
26
+
27
+ #Cool random banner stuff for the cli, based on the Metasploit random banner concept
2
28
 
3
29
  module Risu
4
30
  module CLI
@@ -6,47 +32,47 @@ module Risu
6
32
  Banners =
7
33
  [
8
34
  '
9
- _
10
- _ __(_)___ _ _
35
+ _
36
+ _ __(_)___ _ _
11
37
  | \'__| / __| | | |
12
38
  | | | \__ \ |_| |
13
39
  |_| |_|___/\__,_|
14
-
40
+
15
41
 
16
42
  ',
17
43
  '
18
- _
19
- (_)
20
- _ __ _ ___ _ _
44
+ _
45
+ (_)
46
+ _ __ _ ___ _ _
21
47
  | \'__| / __| | | |
22
48
  | | | \__ \ |_| |
23
49
  |_| |_|___/\__,_|
24
-
50
+
25
51
 
26
52
  ',
27
53
  '
28
- _/
29
- _/ _/_/ _/_/_/ _/ _/
30
- _/_/ _/ _/_/ _/ _/
31
- _/ _/ _/_/ _/ _/
32
- _/ _/ _/_/_/ _/_/_/
54
+ _/
55
+ _/ _/_/ _/_/_/ _/ _/
56
+ _/_/ _/ _/_/ _/ _/
57
+ _/ _/ _/_/ _/ _/
58
+ _/ _/ _/_/_/ _/_/_/
33
59
 
34
60
 
35
61
  ',
36
62
  '
37
- o
38
- ,_ ,
39
- / | | / \_| |
63
+ o
64
+ ,_ ,
65
+ / | | / \_| |
40
66
  |_/|_/ \/ \_/|_/
41
-
67
+
42
68
 
43
69
  ',
44
70
  '
45
- _
71
+ _
46
72
  ____(_)__ __ __
47
73
  / __/ (_-</ // /
48
- /_/ /_/___/\_,_/
49
-
74
+ /_/ /_/___/\_,_/
75
+
50
76
 
51
77
  '
52
78
  ]
@@ -56,4 +82,4 @@ _/ _/ _/_/_/ _/_/_/
56
82
  end
57
83
  end
58
84
  end
59
- end
85
+ end
@@ -1,3 +1,29 @@
1
+ # Copyright (c) 2010-2012 Arxopia LLC.
2
+ # All rights reserved.
3
+
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+
7
+ # * Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright
10
+ # notice, this list of conditions and the following disclaimer in the
11
+ # documentation and/or other materials provided with the distribution.
12
+ # * Neither the name of the Arxopia LLC nor the names of its contributors
13
+ # may be used to endorse or promote products derived from this software
14
+ # without specific prior written permission.
15
+
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL ARXOPIA LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22
+ # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24
+ #OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25
+ #OF THE POSSIBILITY OF SUCH DAMAGE.
26
+
1
27
  module Risu
2
28
  module Exceptions
3
29
  end
@@ -1,7 +1,36 @@
1
+ # Copyright (c) 2010-2012 Arxopia LLC.
2
+ # All rights reserved.
3
+
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+
7
+ # * Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright
10
+ # notice, this list of conditions and the following disclaimer in the
11
+ # documentation and/or other materials provided with the distribution.
12
+ # * Neither the name of the Arxopia LLC nor the names of its contributors
13
+ # may be used to endorse or promote products derived from this software
14
+ # without specific prior written permission.
15
+
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL ARXOPIA LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22
+ # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24
+ #OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25
+ #OF THE POSSIBILITY OF SUCH DAMAGE.
26
+
1
27
  module Risu
2
28
  module Exceptions
29
+
30
+ # Exception class for an invalid document
31
+ #
3
32
  class InvalidDocument < StandardError
4
-
33
+
5
34
  end
6
35
  end
7
36
  end
data/lib/risu/models.rb CHANGED
@@ -1,3 +1,29 @@
1
+ # Copyright (c) 2010-2012 Arxopia LLC.
2
+ # All rights reserved.
3
+
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+
7
+ # * Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright
10
+ # notice, this list of conditions and the following disclaimer in the
11
+ # documentation and/or other materials provided with the distribution.
12
+ # * Neither the name of the Arxopia LLC nor the names of its contributors
13
+ # may be used to endorse or promote products derived from this software
14
+ # without specific prior written permission.
15
+
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL ARXOPIA LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22
+ # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24
+ #OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25
+ #OF THE POSSIBILITY OF SUCH DAMAGE.
26
+
1
27
  module Risu
2
28
  module Models
3
29
  end
@@ -1,8 +1,34 @@
1
+ # Copyright (c) 2010-2012 Arxopia LLC.
2
+ # All rights reserved.
3
+
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+
7
+ # * Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright
10
+ # notice, this list of conditions and the following disclaimer in the
11
+ # documentation and/or other materials provided with the distribution.
12
+ # * Neither the name of the Arxopia LLC nor the names of its contributors
13
+ # may be used to endorse or promote products derived from this software
14
+ # without specific prior written permission.
15
+
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL ARXOPIA LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22
+ # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24
+ #OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25
+ #OF THE POSSIBILITY OF SUCH DAMAGE.
26
+
1
27
  module Risu
2
- module Models
28
+ module Models
29
+
3
30
  # FamilySelection Model
4
31
  #
5
- # @author Jacob Hammack
6
32
  class FamilySelection < ActiveRecord::Base
7
33
  belongs_to :policy
8
34
  end
@@ -1,8 +1,34 @@
1
+ # Copyright (c) 2010-2012 Arxopia LLC.
2
+ # All rights reserved.
3
+
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+
7
+ # * Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright
10
+ # notice, this list of conditions and the following disclaimer in the
11
+ # documentation and/or other materials provided with the distribution.
12
+ # * Neither the name of the Arxopia LLC nor the names of its contributors
13
+ # may be used to endorse or promote products derived from this software
14
+ # without specific prior written permission.
15
+
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL ARXOPIA LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22
+ # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24
+ #OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25
+ #OF THE POSSIBILITY OF SUCH DAMAGE.
26
+
1
27
  module Risu
2
28
  module Models
29
+
3
30
  # Host Model
4
31
  #
5
- # @author Jacob Hammack <jacob.hammack@hammackj.com>
6
32
  class Host < ActiveRecord::Base
7
33
  belongs_to :report
8
34
  has_many :items
@@ -275,6 +301,7 @@ module Risu
275
301
  g = Gruff::Bar.new(GRAPH_WIDTH)
276
302
  g.title = sprintf "Top 10 Hosts with Notable Findings Count"
277
303
  g.sort = false
304
+ g.marker_count = 1
278
305
  g.y_axis_increment = 1
279
306
  g.theme = {
280
307
  :colors => %w(red orange yellow blue green purple black grey brown pink),
@@ -284,7 +311,7 @@ module Risu
284
311
  Item.risks_by_host(limit).all.each do |item|
285
312
  ip = Host.find_by_id(item.host_id).name
286
313
  # count = Item.where(:host_id => item.host_id).where("severity IN (?)", [2,3]).count
287
- count = Item.where(:host_id => item.host_id).where(:severity => 3).count
314
+ count = Item.where(:host_id => item.host_id).where(:severity => 4).count
288
315
  if count > 0
289
316
  g.data(ip, count)
290
317
  end
@@ -300,6 +327,7 @@ module Risu
300
327
  g = Gruff::Pie.new(GRAPH_WIDTH)
301
328
  g.title = "Other Operating Systems Percentage"
302
329
  g.sort = false
330
+ g.marker_count = 1
303
331
  g.theme = {
304
332
  :colors => %w(red orange yellow blue green purple black grey brown pink),
305
333
  :background_colors => %w(white white)
@@ -340,6 +368,7 @@ module Risu
340
368
  g = Gruff::Pie.new(GRAPH_WIDTH)
341
369
  g.title = "Windows Operating Systems By Percentage"
342
370
  g.sort = false
371
+ g.marker_count = 1
343
372
  g.theme = {
344
373
  :colors => %w(red orange yellow blue green purple black grey brown pink),
345
374
  :background_colors => %w(white white)
@@ -501,6 +530,34 @@ module Risu
501
530
 
502
531
  return text
503
532
  end
533
+
534
+ #
535
+ #
536
+ def top_n_vulnerable(n)
537
+ hosts = Item.risks_by_host(Host.all.count).count
538
+ hosts = hosts.sort_by {|k, v| v}
539
+ hosts.reverse!
540
+
541
+ i = 0
542
+ hosts[0...n].each do |host_id, count|
543
+ hosts[i] = Host.where(:id => host_id)
544
+ i = i + 1
545
+ end
546
+
547
+ hosts[0...n]
548
+ end
549
+
550
+ def unique_hosts_with_critical
551
+ hosts = Item.critical_risks_by_host(Host.all.count).count
552
+ hosts = hosts.sort_by {|k, v| v}
553
+ hosts.reverse!
554
+ end
555
+
556
+ def unique_hosts_with_high
557
+ hosts = Item.high_risks_by_host(Host.all.count).count
558
+ hosts = hosts.sort_by {|k, v| v}
559
+ hosts.reverse!
560
+ end
504
561
  end
505
562
  end
506
563
  end
@@ -1,9 +1,34 @@
1
+ # Copyright (c) 2010-2012 Arxopia LLC.
2
+ # All rights reserved.
3
+
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+
7
+ # * Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright
10
+ # notice, this list of conditions and the following disclaimer in the
11
+ # documentation and/or other materials provided with the distribution.
12
+ # * Neither the name of the Arxopia LLC nor the names of its contributors
13
+ # may be used to endorse or promote products derived from this software
14
+ # without specific prior written permission.
15
+
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL ARXOPIA LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22
+ # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24
+ #OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25
+ #OF THE POSSIBILITY OF SUCH DAMAGE.
26
+
1
27
  module Risu
2
28
  module Models
3
29
 
4
30
  # IndividualPluginSelection Model
5
31
  #
6
- # @author Jacob Hammack
7
32
  class IndividualPluginSelection < ActiveRecord::Base
8
33
  belongs_to :policy
9
34
  has_many :plugins
@@ -1,9 +1,34 @@
1
+ # Copyright (c) 2010-2012 Arxopia LLC.
2
+ # All rights reserved.
3
+
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+
7
+ # * Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright
10
+ # notice, this list of conditions and the following disclaimer in the
11
+ # documentation and/or other materials provided with the distribution.
12
+ # * Neither the name of the Arxopia LLC nor the names of its contributors
13
+ # may be used to endorse or promote products derived from this software
14
+ # without specific prior written permission.
15
+
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL ARXOPIA LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22
+ # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24
+ #OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25
+ #OF THE POSSIBILITY OF SUCH DAMAGE.
26
+
1
27
  module Risu
2
28
  module Models
3
29
 
4
30
  # Item Model
5
31
  #
6
- # @author Jacob Hammack <jacob.hammack@hammackj.com>
7
32
  class Item < ActiveRecord::Base
8
33
  belongs_to :host
9
34
  belongs_to :plugin
@@ -22,8 +47,8 @@ module Risu
22
47
  # @return [ActiveRecord::Relation] with the query results
23
48
  def critical_risks
24
49
  where(:severity => 4)
25
- end
26
-
50
+ end
51
+
27
52
  # Queries for all the high risks in the database
28
53
  #
29
54
  # @return [ActiveRecord::Relation] with the query results
@@ -122,7 +147,7 @@ module Risu
122
147
  select("items.*").select("count(*) as count_all").where(:severity => 0).group(:plugin_id).order("count_all DESC")
123
148
  end
124
149
 
125
- # Queries for all the risks grouped by service type, used for the Vulnerbilities by Service graph
150
+ # Queries for all the risks grouped by service type, used for the Vulnerabilities by Service graph
126
151
  #
127
152
  # @return [ActiveRecord::Relation] with the query results
128
153
  def risks_by_service(limit=10)
@@ -142,13 +167,29 @@ module Risu
142
167
  #
143
168
  # @param limit Limits the result to a specific number, default 10
144
169
  #
145
- # @todo add high/med/low_risks_by_host functions
146
- #
147
170
  # @return [ActiveRecord::Relation] with the query results
148
171
  def risks_by_host(limit=10)
149
172
  select("items.*").select("count(*) as count_all").joins(:host).where("plugin_id != 1").where(:severity => 4).group(:host_id).order("count_all DESC").limit(limit)
150
173
  end
151
174
 
175
+ # Queries for all the Critical risks by host
176
+ #
177
+ # @param limit Limits the result to a specific number, default 10
178
+ #
179
+ # @return [ActiveRecord::Relation] with the query results
180
+ def critical_risks_by_host(limit=10)
181
+ select("items.*").select("count(*) as count_all").joins(:host).where("plugin_id != 1").where(:severity => 4).group(:host_id).order("count_all DESC").limit(limit)
182
+ end
183
+
184
+ # Queries for all the High risks by host
185
+ #
186
+ # @param limit Limits the result to a specific number, default 10
187
+ #
188
+ # @return [ActiveRecord::Relation] with the query results
189
+ def high_risks_by_host(limit=10)
190
+ select("items.*").select("count(*) as count_all").joins(:host).where("plugin_id != 1").where(:severity => 3).group(:host_id).order("count_all DESC").limit(limit)
191
+ end
192
+
152
193
  # Queries for all the hosts with the Microsoft patch summary plugin (38153)
153
194
  #
154
195
  # @return [ActiveRecord::Relation] with the query results
@@ -172,6 +213,7 @@ module Risu
172
213
  g = Gruff::Pie.new(GRAPH_WIDTH)
173
214
  g.title = sprintf "Top %d Services By Vulnerability", Item.risks_by_service(limit).all.count
174
215
  g.sort = false
216
+ g.marker_count = 1
175
217
  g.theme = {
176
218
  :colors => %w(red orange yellow blue green purple black grey brown pink),
177
219
  :background_colors => %w(white white)
@@ -183,14 +225,16 @@ module Risu
183
225
 
184
226
  StringIO.new(g.to_blob)
185
227
  end
186
-
187
- #@todo comment
228
+
229
+ # Generates text for the Risks by Service graph
230
+ #
231
+ # @return [String] Text based on the Risks by Service graph
188
232
  def risks_by_service_graph_text
189
233
  "This graph is a representation of the findings found by service. This graph can help " +
190
234
  "understand what services are running on the network and if they are vulnerable, where " +
191
- "the risks are and how they should be protected.\n\n"
235
+ "the risks are and how they should be protected.\n\n"
192
236
  end
193
-
237
+
194
238
  # Generates a Graph of all the risks by severity
195
239
  #
196
240
  # @return [StringIO] Object containing the generated PNG image
@@ -198,6 +242,7 @@ module Risu
198
242
  g = Gruff::Bar.new(GRAPH_WIDTH)
199
243
  g.title = "Risks By Severity"
200
244
  g.sort = false
245
+ g.marker_count = 1
201
246
  g.theme = {
202
247
  :colors => %w(red orange yellow blue green purple black grey brown pink),
203
248
  :background_colors => %w(white white)
@@ -208,28 +253,31 @@ module Risu
208
253
  medium = Item.medium_risks.count
209
254
  low = Item.low_risks.count
210
255
  info = Item.info_risks.count
211
-
256
+
212
257
  if crit == nil then crit = 0 end
213
258
  if high == nil then high = 0 end
214
259
  if medium == nil then medium = 0 end
215
- if low == nil then low = 0 end
260
+ if low == nil then low = 0 end
216
261
  if info == nil then info = 0 end
217
262
 
218
263
  g.data("Critical", crit, "purple")
219
264
  g.data("High", high, "red")
220
265
  g.data("Medium", medium, "orange")
221
266
  g.data("Low", low, "yellow")
222
- g.data("Open Ports", info, "blue")
267
+ g.data("Informational", info, "blue")
223
268
 
224
269
  StringIO.new(g.to_blob)
225
270
  end
226
-
271
+
272
+ # Queries for all DISA Stig findings by category
227
273
  #
274
+ # @param category The DISA Stig category I, II, III
228
275
  #
229
- def stig_findings(categeory="I")
230
- where('plugin_id IN (:plugins)', :plugins => Plugin.where(:stig_severity => categeory).select(:id)).order("severity DESC")
276
+ # @return [ActiveRecord::Relation] with the query results
277
+ def stig_findings(category="I")
278
+ where('plugin_id IN (:plugins)', :plugins => Plugin.where(:stig_severity => category).select(:id)).order("severity DESC")
231
279
  end
232
-
280
+
233
281
  # Generates a Graph of all the risks by severity
234
282
  #
235
283
  # @return [StringIO] Object containing the generated PNG image
@@ -237,6 +285,7 @@ module Risu
237
285
  g = Gruff::Bar.new(GRAPH_WIDTH)
238
286
  g.title = "Stigs By Severity"
239
287
  g.sort = false
288
+ g.marker_count = 1
240
289
  g.theme = {
241
290
  :colors => %w(purple red orange yellow blue green black grey brown pink),
242
291
  :background_colors => %w(white white)
@@ -245,7 +294,7 @@ module Risu
245
294
  i = Item.stig_findings("I").count
246
295
  ii = Item.stig_findings("II").count
247
296
  iii = Item.stig_findings("III").count
248
-
297
+
249
298
  if i == nil then i = 0 end
250
299
  if ii == nil then ii = 0 end
251
300
  if iii == nil then iii = 0 end
@@ -255,94 +304,98 @@ module Risu
255
304
  g.data("Cat III", iii, "orange")
256
305
 
257
306
  StringIO.new(g.to_blob)
258
- end
307
+ end
259
308
 
260
- # @todo change Report.title to a real variable
261
- # @todo rewite this
262
- def risks_by_severity_graph_text
263
- #crit = Item.crit_risks.count
264
- #high = Item.high_risks.count
265
- #medium = Item.medium_risks.count
266
-
267
- #if crit == nil then crit = 0 end
268
- #if high == nil then high = 0 end
269
- #if medium == nil then medium = 0 end
270
-
271
- #percentage = high
272
-
309
+ # @todo comment
310
+ #
311
+ def calculate_vulnerable_host_percent
273
312
  hosts_with_critical = Hash.new
274
-
275
- Item.critical_risks.all.each do |item|
313
+
314
+ (Item.critical_risks.all + Item.high_risks.all).each do |item|
276
315
  ip = Host.find_by_id(item.host_id).name
277
316
  if hosts_with_critical[ip] == nil
278
317
  hosts_with_critical[ip] = 1
279
318
  end
280
-
319
+
281
320
  hosts_with_critical[ip] = hosts_with_critical[ip] + 1
282
321
  end
283
-
322
+
284
323
  host_percent = (hosts_with_critical.count.to_f / Host.all.count.to_f) * 100
285
-
286
- adjective = case host_percent
324
+ end
325
+
326
+ # @todo comments
327
+ #
328
+ def ajective_for_risk_text risk_percent
329
+ adjective = case risk_percent
287
330
  when 0..5
288
331
  "excellent"
289
- #when 6..10
290
- # "great"
291
332
  when 6..10
292
- "very good"
293
- when 15..25
333
+ "great"
334
+ when 11..15
294
335
  "good"
295
- when 25..35
336
+ when 16..20
296
337
  "fair"
297
338
  else
298
339
  "poor"
299
340
  end
300
-
301
- percent_text = case host_percent
302
- when 0..5
341
+ end
342
+
343
+ # @todo comments
344
+ #
345
+ def risk_text risk_percent
346
+ percent_text = case risk_percent
347
+ when 0..5.99
303
348
  "This implies that only a handful of computers are missing patches, and the current patch management is working well."
304
- when 6..9
349
+ when 6..10.99
305
350
  "This implies that there is a minor patch management issue. If there is a patch management system, it should be checked for problems. " +
306
- "Each host should also be inspected to be certain it can receive patches."
307
- when 10..15
351
+ "Each host should also be inspected to be certain it can receive patches."
352
+ when 11..15.99
308
353
  "This implies that there is a substantial patch management issue. If there is a patch management system, it should be checked for problems. " +
309
354
  "Each host should also be inspected to be certain it can receive patches."
310
355
  when 16..20
311
356
  "This implies that there is a significant patch management issue. If there is a patch management system, it should be checked for problems. " +
312
357
  "Each host should also be inspected to be certain it can receive patches."
313
358
  else
314
- "This implies that there is a major patch management problem on the network. Any patch management solutions should " +
359
+ "This implies that there is a critical patch management problem on the network. Any patch management solutions should " +
315
360
  "be inspected for issues and they should be corrected as soon as possible. Each host should also be inspected to be certain it can receive patches."
316
361
  end
317
-
318
- #graph_text = "This bar graph is a representation of the findings by severity; the " +
319
- #"graph shows that, overall, #{Report.title} has a #{adjective} handle on the patch " +
320
- #"management of the network. "
321
-
362
+ end
363
+
364
+ # @todo change Report.title to a real variable
365
+ # @todo rewrite this
366
+ def risks_by_severity_graph_text
367
+ host_percent = calculate_vulnerable_host_percent()
368
+ adjective = ajective_for_risk_text(host_percent)
369
+ risk_text = risk_text(host_percent)
370
+
322
371
  graph_text = "This bar graph is a representation of the findings by severity; the " +
323
- "graph shows that, Overall #{Report.title} needs to implement patch management and configuration management as a priority."
324
-
372
+ "graph shows that, overall, #{Report.title} has a #{adjective} handle on the patch " +
373
+ "management of the network. "
374
+
375
+ #graph_text = "This bar graph is a representation of the findings by severity; the " +
376
+ #{}"graph shows that, Overall #{Report.title} needs to implement patch management and configuration management as a priority."
377
+
325
378
  #if adjective == "good" or adjective == "fair"
326
379
  # graph_text << "But improvements in patch management could be made to ensure an excellent rating."
327
380
  #end
328
-
381
+
329
382
  graph_text << "\n\n"
330
-
331
- graph_text << "The majority of the high findings were found on #{host_percent.round}% of the total assessed computers. #{percent_text}\n\n"
332
-
333
- graph_text << "The systems with high vulnerabilities represent the largest threat to the network, " +
383
+
384
+ graph_text << "The majority of the critical findings were found on #{host_percent.round}% of the total assessed computers. #{risk_text}\n\n"
385
+
386
+ graph_text << "The systems with critical vulnerabilities represent the largest threat to the network, " +
334
387
  "so patching this group is paramount to the overall network security. It only takes one vulnerability " +
335
388
  "to create a security incident.\n\n"
336
-
389
+
337
390
  graph_text << "It should be noted that low findings and open ports represent the discovery "
338
391
  graph_text << "of network services and open ports. Typically, these are not an indication of "
339
392
  graph_text << "a serious problem and pose little to no threat. However, the correlation of "
340
393
  graph_text << "data between the different severity levels could be used to determine degree "
341
394
  graph_text << "of vulnerability for a given system.\n"
342
-
395
+
343
396
  return graph_text
344
397
  end
345
-
398
+
346
399
  #sqlite only @todo @fix
347
400
  def top_10_sorted_raw
348
401
  raw = Item.joins(:plugin).where(:severity => 4).order("cast(plugins.cvss_base_score as real)").count(:all, :group => :plugin_id)
@@ -352,19 +405,19 @@ module Risu
352
405
  row = Array.new
353
406
  plugin_id = vuln[0]
354
407
  count = vuln[1]
355
-
356
- row.push(plugin_id)
408
+
409
+ row.push(plugin_id)
357
410
  row.push(count)
358
411
  data.push(row)
359
- end
412
+ end
360
413
 
361
414
  data = data.sort do |a, b|
362
415
  b[1] <=> a[1]
363
416
  end
364
-
417
+
365
418
  return data
366
419
  end
367
-
420
+
368
421
  def top_10_sorted
369
422
  #raw = Item.where(:severity => 3).count(:all, :group => :plugin_id)
370
423
  raw = Item.joins(:plugin).where(:severity => 4).order(:cvss_base_score).count(:all, :group => :plugin_id)
@@ -377,18 +430,18 @@ module Risu
377
430
 
378
431
  name = Plugin.find_by_id(plugin_id).plugin_name
379
432
 
380
- row.push(name)
433
+ row.push(name)
381
434
  row.push(count)
382
435
  data.push(row)
383
- end
436
+ end
384
437
 
385
438
  data = data.sort do |a, b|
386
439
  b[1] <=> a[1]
387
440
  end
388
-
389
- return data
441
+
442
+ return data
390
443
  end
391
-
444
+
392
445
  # Returns a prawn pdf table for the top 10 notable findings
393
446
  #
394
447
  # @todo change this method to return a array/table and let the template render it
@@ -404,16 +457,16 @@ module Risu
404
457
  output.table([headers] + data[0..9], :header => true, :column_widths => header_widths, :width => output.bounds.width) do
405
458
  row(0).style(:font_style => :bold, :background_color => 'cccccc')
406
459
  cells.borders = [:top, :bottom, :left, :right]
407
- end
460
+ end
408
461
  end
409
-
462
+
410
463
  # Queries for all unique risks and sorts them by count
411
- #
464
+ #
412
465
  # @return [ActiveRecord::Relation] with the query results
413
466
  def all_risks_unique_sorted
414
467
  select("items.*").select("count(*) as count_all").group(:plugin_id).order("count_all DESC")
415
468
  end
416
-
469
+
417
470
  end
418
471
  end
419
472
  end