risu 1.5.3 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. data/Gemfile.ci +1 -0
  2. data/LICENSE +1 -1
  3. data/NEWS.markdown +80 -3
  4. data/README.markdown +9 -8
  5. data/Rakefile +7 -7
  6. data/bin/risu +1 -1
  7. data/lib/risu.rb +6 -3
  8. data/lib/risu/base.rb +2 -1
  9. data/lib/risu/base/schema.rb +8 -4
  10. data/lib/risu/base/template_base.rb +3 -1
  11. data/lib/risu/base/template_helper.rb +115 -0
  12. data/lib/risu/base/template_manager.rb +1 -1
  13. data/lib/risu/base/templater.rb +3 -4
  14. data/lib/risu/cli.rb +1 -1
  15. data/lib/risu/cli/application.rb +3 -10
  16. data/lib/risu/cli/banner.rb +1 -1
  17. data/lib/risu/exceptions.rb +1 -1
  18. data/lib/risu/exceptions/invaliddocument.rb +1 -1
  19. data/lib/risu/models.rb +1 -1
  20. data/lib/risu/models/familyselection.rb +1 -1
  21. data/lib/risu/models/host.rb +92 -9
  22. data/lib/risu/models/individualpluginselection.rb +1 -1
  23. data/lib/risu/models/item.rb +47 -13
  24. data/lib/risu/models/patch.rb +1 -1
  25. data/lib/risu/models/plugin.rb +9 -1
  26. data/lib/risu/models/pluginspreference.rb +1 -1
  27. data/lib/risu/models/policy.rb +1 -1
  28. data/lib/risu/models/reference.rb +69 -9
  29. data/lib/risu/models/report.rb +1 -1
  30. data/lib/risu/models/serverpreference.rb +1 -1
  31. data/lib/risu/models/servicedescription.rb +1 -1
  32. data/lib/risu/models/version.rb +1 -1
  33. data/lib/risu/parsers.rb +1 -1
  34. data/lib/risu/parsers/nessus/nessus_document.rb +1 -1
  35. data/lib/risu/parsers/nessus/nessus_sax_listener.rb +69 -50
  36. data/lib/risu/parsers/nexpose/nexpose_document.rb +2 -5
  37. data/lib/risu/parsers/nexpose/simple_nexpose.rb +1 -1
  38. data/lib/risu/renderers.rb +1 -1
  39. data/lib/risu/renderers/nilrenderer.rb +1 -1
  40. data/lib/risu/templates/assets.rb +17 -29
  41. data/lib/risu/templates/cover_sheet.rb +40 -44
  42. data/lib/risu/templates/exec_summary.rb +11 -20
  43. data/lib/risu/templates/{executive_summary.rb → executive_summary_detailed.rb} +2 -11
  44. data/lib/risu/templates/finding_statistics.rb +1 -1
  45. data/lib/risu/templates/findings_host.rb +1 -1
  46. data/lib/risu/templates/findings_summary.rb +25 -86
  47. data/lib/risu/templates/findings_summary_with_pluginid.rb +1 -1
  48. data/lib/risu/templates/graphs.rb +1 -1
  49. data/lib/risu/templates/host_summary.rb +18 -14
  50. data/lib/risu/templates/ms_patch_summary.rb +17 -24
  51. data/lib/risu/templates/ms_update_summary.rb +1 -1
  52. data/lib/risu/templates/ms_wsus_findings.rb +1 -1
  53. data/lib/risu/templates/notable.rb +10 -14
  54. data/lib/risu/templates/notable_detailed.rb +43 -54
  55. data/lib/risu/templates/pci_compliance.rb +28 -34
  56. data/lib/risu/templates/stig_findings_summary.rb +25 -38
  57. data/lib/risu/templates/technical_findings.rb +46 -55
  58. data/lib/risu/templates/template.rb +4 -3
  59. data/risu.gemspec +12 -11
  60. metadata +79 -61
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010-2012 Arxopia LLC.
1
+ # Copyright (c) 2010-2013 Arxopia LLC.
2
2
  # All rights reserved.
3
3
  #
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010-2012 Arxopia LLC.
1
+ # Copyright (c) 2010-2013 Arxopia LLC.
2
2
  # All rights reserved.
3
3
  #
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010-2012 Arxopia LLC.
1
+ # Copyright (c) 2010-2013 Arxopia LLC.
2
2
  # All rights reserved.
3
3
  #
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -26,35 +26,31 @@
26
26
 
27
27
  module Risu
28
28
  module Templates
29
- class Top10 < Risu::Base::TemplateBase
29
+ class NotableTemplate < Risu::Base::TemplateBase
30
+ include TemplateHelper
30
31
 
31
- # @todo comments
32
- #
32
+ #Creates an instance of the [NotableTemplate] class and initializes its meta-data
33
33
  def initialize ()
34
34
  @template_info =
35
35
  {
36
36
  :name => "notable",
37
37
  :author => "hammackj",
38
- :version => "0.0.2",
38
+ :version => "0.0.3",
39
39
  :description => "Notable Vulnerabilities"
40
40
  }
41
41
  end
42
42
 
43
- # @todo comments
44
- #
43
+ # Renders a Notable Findings Report
45
44
  def render(output)
46
45
  output.text Report.classification.upcase, :align => :center
47
46
  output.text "\n"
48
47
 
49
- output.font_size(22) {
50
- output.text Report.title, :align => :center
51
- }
48
+ report_title Report.title
49
+ report_subtitle "Notable Vulnerabilities"
52
50
 
53
- output.font_size(18) {
54
- output.text "Notable Vulnerabilities", :align => :center
55
- output.text "\n"
51
+ output.font_size(14) do
56
52
  output.text "This report was prepared by\n#{Report.author}", :align => :center
57
- }
53
+ end
58
54
 
59
55
  output.text "\n\n\n"
60
56
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010-2012 Arxopia LLC.
1
+ # Copyright (c) 2010-2013 Arxopia LLC.
2
2
  # All rights reserved.
3
3
  #
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -26,16 +26,16 @@
26
26
 
27
27
  module Risu
28
28
  module Templates
29
- class NotableDetailed < Risu::Base::TemplateBase
29
+ class NotableTemplateDetailed < Risu::Base::TemplateBase
30
+ include TemplateHelper
30
31
 
31
- #
32
- #
32
+ #Creates an instance of the [NotableTemplateDetailed] class and initializes its meta-data
33
33
  def initialize ()
34
34
  @template_info =
35
35
  {
36
36
  :name => "notable_detailed",
37
37
  :author => "hammackj",
38
- :version => "0.0.4",
38
+ :version => "0.0.5",
39
39
  :description => "Notable Vulnerabilities Detailed"
40
40
  }
41
41
  end
@@ -43,26 +43,18 @@ module Risu
43
43
  #
44
44
  #
45
45
  def render(output)
46
- output.text Report.classification.upcase, :align => :center
47
- output.text "\n"
46
+ @output.text Report.classification.upcase, :align => :center
47
+ @output.text "\n"
48
48
 
49
- output.font_size(22) do
50
- output.text Report.title, :align => :center
51
- end
52
-
53
- output.font_size(18) do
54
- output.text "Notable Vulnerabilities", :align => :center
55
- output.text "\n"
56
- output.text "This report was prepared by\n#{Report.author}", :align => :center
57
- end
49
+ report_title Report.title
50
+ report_subtitle "Notable Vulnerabilities"
51
+ report_author "This report was prepared by\n#{Report.author}"
58
52
 
59
- output.text "\n\n\n"
53
+ @output.text "\n\n\n"
60
54
 
61
- output.text "Scan Date:", :style => :bold
62
- output.text "#{Report.scan_date}"
63
- output.text "\n"
64
-
65
- output.font_size(10)
55
+ @output.text "Scan Date:", :style => :bold
56
+ @output.text "#{Report.scan_date}"
57
+ @output.text "\n"
66
58
 
67
59
  data = Item.top_10_sorted_raw
68
60
 
@@ -72,88 +64,85 @@ module Risu
72
64
 
73
65
  unique_risks.each do |h|
74
66
  if h[:values].length > 1
75
- output.text "\n"
67
+ @output.text "\n"
76
68
 
77
69
  h[:values].each do |f|
78
70
  plugin_id = f[0]
79
71
 
80
- hosts = Item.where(:plugin_id => plugin_id)
72
+ hosts = Item.where(:plugin_id => plugin_id).group(:host_id)
81
73
  item = Item.where(:plugin_id => plugin_id)
82
74
  plugin = Plugin.find_by_id(plugin_id)
83
75
 
84
76
  references = Reference.where(:plugin_id => plugin.id).group(:value).order(:reference_name)
85
77
 
86
- output.font_size(16) do
87
- output.text "#{counter}: #{plugin.plugin_name}\n"
88
- end
78
+ heading3 "#{counter}: #{Item.scrub_plugin_name(plugin.plugin_name)}\n"
89
79
 
90
80
  if hosts.length > 1
91
- output.text "Hosts", :style => :bold
81
+ @output.text "Hosts", :style => :bold
92
82
  else
93
- output.text "Host", :style => :bold
83
+ @output.text "Host", :style => :bold
94
84
  end
95
85
 
96
86
  hostlist = Array.new
97
87
  hosts.each do |host|
98
88
  h = Host.find_by_id(host.host_id)
99
- hostlist << h.name
89
+ host_string = "#{h.name}"
90
+ host_string << " (#{h.fqdn})" if h.fqdn != nil
91
+ hostlist << host_string
100
92
  end
101
93
 
102
- output.text hostlist.join(', ')
94
+ @output.text hostlist.join(', ')
103
95
 
104
96
  #if item.plugin_output != nil
105
- # output.text "\nPlugin output", :style => :bold
106
- # output.text f.plugin_output
97
+ # @output.text "\nPlugin output", :style => :bold
98
+ # @output.text f.plugin_output
107
99
  #end
108
100
 
109
101
  if plugin.description != nil
110
- output.text "\nDescription", :style => :bold
111
- output.text plugin.description
102
+ @output.text "\nDescription", :style => :bold
103
+ @output.text plugin.description.gsub(/[ ]{2,}/, " ")
112
104
  end
113
105
 
114
106
  if plugin.synopsis != nil
115
- output.text "\nSynopsis", :style => :bold
116
- output.text plugin.synopsis
107
+ @output.text "\nSynopsis", :style => :bold
108
+ @output.text plugin.synopsis
117
109
  end
118
110
 
119
111
  if plugin.cvss_base_score != nil
120
- output.text "\nCVSS Base Score", :style => :bold
121
- output.text plugin.cvss_base_score
112
+ @output.text "\nCVSS Base Score", :style => :bold
113
+ @output.text plugin.cvss_base_score
122
114
  end
123
115
 
124
116
  if plugin.exploit_available != nil
125
- output.text "\nExploit Available", :style => :bold
117
+ @output.text "\nExploit Available", :style => :bold
126
118
 
127
119
  if plugin.exploit_available == "true"
128
- output.text "Yes"
120
+ @output.text "Yes"
129
121
  else
130
- output.text "No"
122
+ @output.text "No"
131
123
  end
132
124
  end
133
125
 
134
126
  if plugin.solution != nil
135
- output.text "\nSolution", :style => :bold
136
- output.text plugin.solution
127
+ @output.text "\nSolution", :style => :bold
128
+ @output.text plugin.solution
137
129
  end
138
130
 
139
131
  if references.size != 0
140
- output.text "\nReferences", :style => :bold
141
- references.each do |ref|
142
- ref_text = sprintf "%s: %s\n", ref.reference_name, ref.value
143
- output.text ref_text
144
- end
145
- output.text "\nNessus Plugin", :style => :bold
146
- output.text "http://www.tenablesecurity.com/plugins/index.php?view=single&id=#{plugin_id}"
132
+ @output.text "\nReferences", :style => :bold
133
+ @output.text plugin.references.reference_string, :inline_format => true
134
+ @output.text "<b>nessus_plugin</b>: http://www.tenablesecurity.com/plugins/index.php?view=single&id=#{plugin_id}", :inline_format => true
147
135
  end
148
- output.text "\n"
136
+
137
+ @output.text "\n"
149
138
  counter += 1
150
139
  end
151
140
  end
152
141
 
153
- output.start_new_page unless h[:values] == nil
142
+ @output.start_new_page unless h[:values] == nil
154
143
  end
155
144
 
156
- output.number_pages "<page> of <total>", :at => [output.bounds.right - 75, 0], :width => 150, :page_filter => :all
145
+ @output.number_pages "<page> of <total>", :at => [@output.bounds.right - 75, 0], :width => 150, :page_filter => :all
157
146
  end
158
147
  end
159
148
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010-2012 Arxopia LLC.
1
+ # Copyright (c) 2010-2013 Arxopia LLC.
2
2
  # All rights reserved.
3
3
  #
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -27,83 +27,77 @@
27
27
  module Risu
28
28
  module Templates
29
29
  class PCICompliance < Risu::Base::TemplateBase
30
+ include TemplateHelper
30
31
 
31
- #
32
- #
33
32
  def initialize ()
34
33
  @template_info =
35
34
  {
36
35
  :name => "pci_compliance",
37
36
  :author => "hammackj",
38
- :version => "0.0.3",
37
+ :version => "0.0.4",
39
38
  :description => "Generates a PCI Compliance Overview Report"
40
39
  }
41
40
  end
42
41
 
43
- #
44
- #
45
42
  def render(output)
46
- output.text Report.classification.upcase, :align => :center
47
- output.text "\n"
43
+ text Report.classification.upcase, :align => :center
44
+ text "\n"
48
45
 
49
- output.font_size(22) { output.text Report.title, :align => :center }
50
- output.font_size(18) {
51
- output.text "PCI / DSS Compliance Overview", :align => :center
52
- output.text "\n"
53
- output.text "This report was prepared by\n#{Report.author}", :align => :center
54
- }
46
+ report_title Report.title
47
+ report_subtitle "PCI / DSS Compliance Overview"
48
+ report_author "This report was prepared by\n#{Report.author}"
55
49
 
56
- output.text "\n\n\n"
50
+ text "\n\n\n"
57
51
 
58
52
  @hosts_count = Host.find(:all, :conditions => ["pci_dss_compliance is not null"]).count
59
53
  @hosts_passed = Host.find(:all, :conditions => ["pci_dss_compliance like 'passed'"])
60
54
  @hosts_failed = Host.find(:all, :conditions => ["pci_dss_compliance like 'failed'"])
61
55
 
62
- output.font_size(20) {
56
+ output.font_size(20) do
63
57
  output.text "Summary\n", :style => :bold
64
- }
58
+ end
65
59
 
66
- output.text "Of #{@hosts_count} total hosts, #{@hosts_passed.count} passed and #{@hosts_failed.count} failed."
60
+ text "Of #{@hosts_count} total hosts, #{@hosts_passed.count} passed and #{@hosts_failed.count} failed."
67
61
 
68
- output.text "\n\n"
62
+ text "\n\n"
69
63
 
70
64
  if @hosts_passed.length > 0
71
- output.font_size(20) {
65
+ output.font_size(20) do
72
66
  output.fill_color "00FF00"
73
67
  output.text "PCI / DSS Compliant Hosts", :style => :bold
74
68
  output.fill_color "000000"
75
- }
69
+ end
76
70
 
77
71
  output.text "\n"
78
72
 
79
73
  @hosts_passed.each do |host|
80
- output.text "#{host.ip} / #{host.fqdn} - passed\n"
74
+ text "#{host.ip} / #{host.fqdn} - passed\n"
81
75
  end unless @hosts_passed == nil
82
76
 
83
77
  output.start_new_page
84
78
  end
85
79
 
86
80
  if @hosts_failed.length > 0
87
- output.font_size(20) {
81
+ output.font_size(20) do
88
82
  output.fill_color "FF0000"
89
83
  output.text "Non PCI / DSS Compliant Hosts", :style => :bold
90
84
  output.fill_color "000000"
91
- }
85
+ end
92
86
 
93
- output.text "\n"
87
+ text "\n"
94
88
 
95
89
  @hosts_failed.each do |host|
96
- host_id = host.id
97
- plugin = Plugin.find(:first, :conditions => { :id => 33929 })
98
- item = Item.find(:first, :conditions => { :host_id => host_id, :plugin_id => plugin.id })
90
+ host_id = host.id
91
+ plugin = Plugin.find(:first, :conditions => { :id => 33929 })
92
+ item = Item.find(:first, :conditions => { :host_id => host_id, :plugin_id => plugin.id })
99
93
 
100
- output.text "#{host.ip} / #{host.fqdn} - failed\n", :style => :bold
101
- output.text "Description:\n", :style => :bold
102
- output.text "#{plugin.description}\n"
103
- output.text "Plugin Output:\n", :style => :bold
104
- output.text "#{item.plugin_output}\n"
94
+ output.text "#{host.ip} / #{host.fqdn} - failed\n", :style => :bold
95
+ output.text "Description:\n", :style => :bold
96
+ output.text "#{plugin.description}\n"
97
+ output.text "Plugin Output:\n", :style => :bold
98
+ output.text "#{item.plugin_output}\n"
105
99
 
106
- output.text "\n"
100
+ text "\n"
107
101
 
108
102
  end unless @hosts_failed == nil
109
103
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010-2012 Arxopia LLC.
1
+ # Copyright (c) 2010-2013 Arxopia LLC.
2
2
  # All rights reserved.
3
3
  #
4
4
  # Redistribution and use in source and binary forms, with or without
@@ -26,39 +26,30 @@
26
26
 
27
27
  module Risu
28
28
  module Templates
29
- class StigFindingsSummary < Risu::Base::TemplateBase
29
+ class StigFindingsSummaryTemplate < Risu::Base::TemplateBase
30
+ include TemplateHelper
30
31
 
31
- # Initializes the template loading meta-data
32
- #
33
32
  def initialize ()
34
33
  @template_info =
35
34
  {
36
35
  :name => "stig_findings_summary",
37
36
  :author => "hammackj",
38
- :version => "0.0.3",
37
+ :version => "0.0.4",
39
38
  :description => "DISA Stig findings summary report"
40
39
  }
41
40
 
42
41
  @output = nil
43
42
  end
44
43
 
45
- #
46
- #
47
44
  def header
48
- @output.text Report.classification.upcase, :align => :center
49
- @output.text "\n"
45
+ text Report.classification.upcase, :align => :center
46
+ text "\n"
50
47
 
51
- @output.font_size(22) do
52
- @output.text Report.title, :align => :center
53
- end
54
-
55
- @output.font_size(18) do
56
- @output.text "Stig Findings Summary", :align => :center
57
- @output.text "\n"
58
- @output.text "This report was prepared by\n#{Report.author}", :align => :center
59
- end
48
+ report_title Report.title
49
+ report_subtitle "Stig Findings Summary"
50
+ report_author "This report was prepared by\n#{Report.author}"
60
51
 
61
- @output.text "\n\n\n"
52
+ text "\n\n\n"
62
53
  end
63
54
 
64
55
  # Creates a list of hosts from an list of Items
@@ -68,6 +59,9 @@ module Risu
68
59
  Host.where('id IN (:hosts)', :hosts => Item.where(:plugin_id => plugin_id).select(:host_id).select('host_id AS id'))
69
60
  end
70
61
 
62
+ #
63
+ # @todo pull to main Host api
64
+ #
71
65
  def host_list_text(hosts)
72
66
  host_string = ""
73
67
  hosts.all.each do |host|
@@ -90,26 +84,26 @@ module Risu
90
84
  stigs = Item.stig_findings(category).group(:plugin_id)
91
85
 
92
86
  stigs.each do |stig|
93
- @output.text "#{stig.plugin_name}", :size => 16
87
+ text "#{stig.plugin_name}", :size => 16
94
88
  hosts = host_list_from_plugin_id(stig.plugin_id)
95
89
  hosts_string = host_list_text(hosts)
96
90
 
97
91
  if hosts.count > 1
98
- @output.text "<b>Hosts</b>: #{hosts_string}", :inline_format => true
92
+ text "<b>Hosts</b>: #{hosts_string}", :inline_format => true
99
93
  else
100
- @output.text "<b>Host</b>: #{hosts_string}", :inline_format => true
94
+ text "<b>Host</b>: #{hosts_string}", :inline_format => true
101
95
  end
102
96
 
103
- @output.text "<b>Risk</b>: #{stig.plugin.risk_factor}", :inline_format => true
104
- @output.text "<b>CVE Reference</b>: #{ref_string(stig.plugin.references.cve)}", :inline_format => true
105
- @output.text "<b>IAVA Reference</b>: #{ref_string(stig.plugin.references.iava)}", :inline_format => true
97
+ text "<b>Risk</b>: #{stig.plugin.risk_factor}", :inline_format => true
98
+ text "<b>CVE Reference</b>: #{ref_string(stig.plugin.references.cve)}", :inline_format => true
99
+ text "<b>IAVA Reference</b>: #{ref_string(stig.plugin.references.iava)}", :inline_format => true
106
100
 
107
101
  if stig.plugin.description != nil
108
- @output.text "\nDescription:", :style => :bold
109
- @output.text stig.plugin.description
102
+ text "\nDescription:", :style => :bold
103
+ text stig.plugin.description
110
104
  end
111
105
 
112
- @output.text "\n"
106
+ text "\n"
113
107
  end
114
108
  end
115
109
 
@@ -126,34 +120,27 @@ module Risu
126
120
  ref_string.chomp!(", ")
127
121
  end
128
122
 
129
- # Called during the rendering process
130
- #
131
123
  def render(output)
132
- @output = output
133
-
134
- @output.font_size 10
135
-
136
124
  header
137
125
 
138
126
  if Item.stig_findings("I").count > 0
139
- @output.text "<color rgb='551A8B'>Category I Findings</color>", :size => 18, :style => :bold, :inline_format => true
127
+ text "<color rgb='551A8B'>Category I Findings</color>", :size => 18, :style => :bold, :inline_format => true
140
128
  stig_findings_text("I")
141
129
  end
142
130
 
143
131
  if Item.stig_findings("II").count > 0
144
132
  @output.start_new_page
145
- @output.text "<color rgb='FF0000'>Category II Findings</color>", :size => 18, :style => :bold, :inline_format => true
133
+ text "<color rgb='FF0000'>Category II Findings</color>", :size => 18, :style => :bold, :inline_format => true
146
134
  stig_findings_text("II")
147
135
  end
148
136
 
149
137
  if Item.stig_findings("III").count > 0
150
138
  @output.start_new_page
151
- @output.text "<color rgb='FF8040'>Category III Findings</color>", :size => 18, :style => :bold, :inline_format => true
139
+ text "<color rgb='FF8040'>Category III Findings</color>", :size => 18, :style => :bold, :inline_format => true
152
140
  stig_findings_text("III")
153
141
  end
154
142
 
155
143
  @output.number_pages "<page> of <total>", :at => [@output.bounds.right - 75, 0], :width => 150, :page_filter => :all
156
-
157
144
  end
158
145
  end
159
146
  end