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.
- data/Gemfile.ci +1 -0
- data/LICENSE +1 -1
- data/NEWS.markdown +80 -3
- data/README.markdown +9 -8
- data/Rakefile +7 -7
- data/bin/risu +1 -1
- data/lib/risu.rb +6 -3
- data/lib/risu/base.rb +2 -1
- data/lib/risu/base/schema.rb +8 -4
- data/lib/risu/base/template_base.rb +3 -1
- data/lib/risu/base/template_helper.rb +115 -0
- data/lib/risu/base/template_manager.rb +1 -1
- data/lib/risu/base/templater.rb +3 -4
- data/lib/risu/cli.rb +1 -1
- data/lib/risu/cli/application.rb +3 -10
- data/lib/risu/cli/banner.rb +1 -1
- data/lib/risu/exceptions.rb +1 -1
- data/lib/risu/exceptions/invaliddocument.rb +1 -1
- data/lib/risu/models.rb +1 -1
- data/lib/risu/models/familyselection.rb +1 -1
- data/lib/risu/models/host.rb +92 -9
- data/lib/risu/models/individualpluginselection.rb +1 -1
- data/lib/risu/models/item.rb +47 -13
- data/lib/risu/models/patch.rb +1 -1
- data/lib/risu/models/plugin.rb +9 -1
- data/lib/risu/models/pluginspreference.rb +1 -1
- data/lib/risu/models/policy.rb +1 -1
- data/lib/risu/models/reference.rb +69 -9
- data/lib/risu/models/report.rb +1 -1
- data/lib/risu/models/serverpreference.rb +1 -1
- data/lib/risu/models/servicedescription.rb +1 -1
- data/lib/risu/models/version.rb +1 -1
- data/lib/risu/parsers.rb +1 -1
- data/lib/risu/parsers/nessus/nessus_document.rb +1 -1
- data/lib/risu/parsers/nessus/nessus_sax_listener.rb +69 -50
- data/lib/risu/parsers/nexpose/nexpose_document.rb +2 -5
- data/lib/risu/parsers/nexpose/simple_nexpose.rb +1 -1
- data/lib/risu/renderers.rb +1 -1
- data/lib/risu/renderers/nilrenderer.rb +1 -1
- data/lib/risu/templates/assets.rb +17 -29
- data/lib/risu/templates/cover_sheet.rb +40 -44
- data/lib/risu/templates/exec_summary.rb +11 -20
- data/lib/risu/templates/{executive_summary.rb → executive_summary_detailed.rb} +2 -11
- data/lib/risu/templates/finding_statistics.rb +1 -1
- data/lib/risu/templates/findings_host.rb +1 -1
- data/lib/risu/templates/findings_summary.rb +25 -86
- data/lib/risu/templates/findings_summary_with_pluginid.rb +1 -1
- data/lib/risu/templates/graphs.rb +1 -1
- data/lib/risu/templates/host_summary.rb +18 -14
- data/lib/risu/templates/ms_patch_summary.rb +17 -24
- data/lib/risu/templates/ms_update_summary.rb +1 -1
- data/lib/risu/templates/ms_wsus_findings.rb +1 -1
- data/lib/risu/templates/notable.rb +10 -14
- data/lib/risu/templates/notable_detailed.rb +43 -54
- data/lib/risu/templates/pci_compliance.rb +28 -34
- data/lib/risu/templates/stig_findings_summary.rb +25 -38
- data/lib/risu/templates/technical_findings.rb +46 -55
- data/lib/risu/templates/template.rb +4 -3
- data/risu.gemspec +12 -11
- metadata +79 -61
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010-
|
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
|
29
|
+
class NotableTemplate < Risu::Base::TemplateBase
|
30
|
+
include TemplateHelper
|
30
31
|
|
31
|
-
#
|
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.
|
38
|
+
:version => "0.0.3",
|
39
39
|
:description => "Notable Vulnerabilities"
|
40
40
|
}
|
41
41
|
end
|
42
42
|
|
43
|
-
#
|
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
|
-
|
50
|
-
|
51
|
-
}
|
48
|
+
report_title Report.title
|
49
|
+
report_subtitle "Notable Vulnerabilities"
|
52
50
|
|
53
|
-
output.font_size(
|
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-
|
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
|
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.
|
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
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
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
|
-
|
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.
|
142
|
-
|
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
|
-
|
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-
|
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.
|
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
|
-
|
47
|
-
|
43
|
+
text Report.classification.upcase, :align => :center
|
44
|
+
text "\n"
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
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
|
-
|
60
|
+
text "Of #{@hosts_count} total hosts, #{@hosts_passed.count} passed and #{@hosts_failed.count} failed."
|
67
61
|
|
68
|
-
|
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
|
-
|
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
|
-
|
87
|
+
text "\n"
|
94
88
|
|
95
89
|
@hosts_failed.each do |host|
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
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
|
-
|
100
|
+
text "\n"
|
107
101
|
|
108
102
|
end unless @hosts_failed == nil
|
109
103
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010-
|
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
|
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.
|
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
|
-
|
49
|
-
|
45
|
+
text Report.classification.upcase, :align => :center
|
46
|
+
text "\n"
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
92
|
+
text "<b>Hosts</b>: #{hosts_string}", :inline_format => true
|
99
93
|
else
|
100
|
-
|
94
|
+
text "<b>Host</b>: #{hosts_string}", :inline_format => true
|
101
95
|
end
|
102
96
|
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
109
|
-
|
102
|
+
text "\nDescription:", :style => :bold
|
103
|
+
text stig.plugin.description
|
110
104
|
end
|
111
105
|
|
112
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|