risu 1.7.2 → 1.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/NEWS.markdown +10 -0
- data/lib/risu.rb +1 -1
- data/lib/risu/base/schema.rb +1 -1
- data/lib/risu/base/shares_template_helper.rb +1 -1
- data/lib/risu/base/template_helper.rb +29 -22
- data/lib/risu/parsers/nessus/nessus_sax_listener.rb +337 -294
- data/lib/risu/parsers/nexpose/simple_nexpose.rb +7 -7
- data/lib/risu/templates/technical_findings.rb +53 -95
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3976d26d2c92a443ccbc3a367a78f452e1bf959e
|
4
|
+
data.tar.gz: 0d8c53e2188555be31370de88051c3b033ab5e25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdee561ba2e2d97d7c07cc211b469c51fabc303c7ceaa673fb92aaa8141d52fa53c9a6c28054002ba8a548d1d6e1e9787bb1c44ce49fc4bf5836ea6cb31fb05a
|
7
|
+
data.tar.gz: baed03ceb606c9034731555abe4857552a61e97453a5dbd15ed6b72cef40a3a33f1fd5e4c03aa61ddc23b8f604a3985e6c3f35c4cff0fed649e5d737be011cef
|
data/NEWS.markdown
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# News
|
2
2
|
|
3
|
+
# 1.7.3 (January 8, 2015)
|
4
|
+
- Parser Optimizations by [@bluehavana]
|
5
|
+
- Renamed Attachment.type to Attachment.ttype, due to a rails naming issue
|
6
|
+
- Added SAX Parser tests for Attachments
|
7
|
+
- Rewrote the technical_findings template
|
8
|
+
- Template Helper
|
9
|
+
- Added title method
|
10
|
+
- Added definition method
|
11
|
+
- Fixed various bugs
|
12
|
+
|
3
13
|
# 1.7.2 (January 5, 2015)
|
4
14
|
- Updated Copyrights / etc
|
5
15
|
- Added VMware ESXi Post Processing
|
data/lib/risu.rb
CHANGED
data/lib/risu/base/schema.rb
CHANGED
@@ -144,7 +144,7 @@ module Risu
|
|
144
144
|
heading1 "Poor Security Practice" if poor_count > 0
|
145
145
|
|
146
146
|
#Anon ftp/smb + clear text
|
147
|
-
@output.text anon_ftp_text + anon_smb_text + anonymous_access_text if anon_ftp_count >
|
147
|
+
@output.text anon_ftp_text + anon_smb_text + anonymous_access_text if anon_ftp_count > 0 || anon_smb_count > 0
|
148
148
|
@output.text "\n"
|
149
149
|
@output.text "\n"
|
150
150
|
end
|
@@ -73,45 +73,52 @@ module Risu
|
|
73
73
|
@output.text text, options
|
74
74
|
end
|
75
75
|
|
76
|
-
#
|
77
|
-
|
78
|
-
|
79
|
-
@output.text
|
76
|
+
def title(text, size=18, color='#000000')
|
77
|
+
@output.font_size(size) do
|
78
|
+
@output.fill_color color.gsub('#', '')
|
79
|
+
@output.text text, :style => :bold
|
80
|
+
@output.fill_color "000000"
|
80
81
|
end
|
82
|
+
|
83
|
+
@output.text "\n"
|
81
84
|
end
|
82
85
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
@output.text
|
86
|
+
def definition term, text, options = {}
|
87
|
+
if text != nil
|
88
|
+
@output.text "\n#{term}", :style => :bold
|
89
|
+
@output.text text, options
|
87
90
|
end
|
88
91
|
end
|
89
92
|
|
90
93
|
#
|
91
|
-
def
|
92
|
-
|
93
|
-
@output.text title, :style => :bold
|
94
|
-
end
|
94
|
+
def heading1 title_text
|
95
|
+
title title_text, 24
|
95
96
|
end
|
96
97
|
|
97
98
|
#
|
98
|
-
def
|
99
|
-
|
100
|
-
@output.text title, :style => :bold
|
101
|
-
end
|
99
|
+
def heading2 title_text
|
100
|
+
title title_text, 18
|
102
101
|
end
|
103
102
|
|
104
103
|
#
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
|
104
|
+
def heading3 title_text
|
105
|
+
title title_text, 14
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
def heading4 title_text
|
110
|
+
title title_text, 12
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
def heading5 title_text
|
115
|
+
title title_text, 10
|
109
116
|
end
|
110
117
|
|
111
118
|
#
|
112
|
-
def heading6
|
119
|
+
def heading6 title_text
|
113
120
|
@output.font_size(8) do
|
114
|
-
@output.text
|
121
|
+
@output.text title_text, :style => :bold
|
115
122
|
end
|
116
123
|
end
|
117
124
|
|
@@ -24,6 +24,8 @@
|
|
24
24
|
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
25
25
|
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
26
|
|
27
|
+
require 'set'
|
28
|
+
|
27
29
|
ActiveRecord::Migration.verbose = false
|
28
30
|
|
29
31
|
module Risu
|
@@ -34,64 +36,125 @@ module Risu
|
|
34
36
|
class NessusSaxListener
|
35
37
|
include LibXML::XML::SaxParser::Callbacks
|
36
38
|
|
37
|
-
#
|
39
|
+
# An array of valid reference element names
|
40
|
+
VALID_REFERENCES = Set.new(%w[
|
41
|
+
cpe bid see_also xref cve iava msft
|
42
|
+
osvdb cert edb-id rhsa secunia suse dsa
|
43
|
+
owasp cwe iavb iavt cisco-sa ics-alert
|
44
|
+
cisco-bug-id cisco-sr cert-vu vmsa apple-sa
|
45
|
+
icsa cert-cc msvr usn hp glsa freebsd
|
46
|
+
])
|
47
|
+
|
48
|
+
# An array of valid host properties
|
49
|
+
VALID_HOST_PROPERTIES = Set.new(%w[
|
50
|
+
HOST_END mac-address HOST_START operating-system host-ip host-fqdn netbios-name
|
51
|
+
local-checks-proto smb-login-used ssh-auth-meth ssh-login-used pci-dss-compliance
|
52
|
+
pci-dss-compliance: system-type bios-uuid pcidss:compliance:failed pcidss:compliance:passed
|
53
|
+
pcidss:deprecated_ssl pcidss:expired_ssl_certificate pcidss:high_risk_flaw pcidss:medium_risk_flaw
|
54
|
+
pcidss:reachable_db pcidss:www:xss pcidss:directory_browsing pcidss:known_credentials
|
55
|
+
pcidss:compromised_host:worm pcidss:obsolete_operating_system pcidss:dns_zone_transfer
|
56
|
+
pcidss:unprotected_mssql_db pcidss:obsolete_software pcidss:www:sql_injection pcidss:backup_files
|
57
|
+
traceroute-hop-0 traceroute-hop-1 traceroute-hop-2 operating-system-unsupported patch-summary-total-cves
|
58
|
+
pcidss:insecure_http_methods LastUnauthenticatedResults LastAuthenticatedResults cpe-0 cpe-1
|
59
|
+
cpe-2 cpe-3 Credentialed_Scan policy-used UnsupportedProduct:microsoft:windows_xp::sp2
|
60
|
+
UnsupportedProduct:microsoft:windows_xp UnsupportedProduct:microsoft:windows_2000 UnsupportedProduct
|
61
|
+
])
|
62
|
+
|
63
|
+
# An array of all valid elements expected during parsing
|
64
|
+
VALID_ELEMENTS = VALID_REFERENCES \
|
65
|
+
+ Set.new(%w[ReportItem plugin_version risk_factor
|
66
|
+
description cvss_base_score solution item plugin_output tag synopsis plugin_modification_date
|
67
|
+
FamilyName FamilyItem Status vuln_publication_date ReportHost HostProperties preferenceName
|
68
|
+
preferenceValues preferenceType fullName pluginId pluginName selectedValue selectedValue
|
69
|
+
name value preference plugin_publication_date cvss_vector patch_publication_date
|
70
|
+
NessusClientData_v2 Policy PluginName ServerPreferences policyComments policyName PluginItem
|
71
|
+
Report Family Preferences PluginsPreferences FamilySelection IndividualPluginSelection PluginId
|
72
|
+
pci-dss-compliance exploitability_ease cvss_temporal_vector exploit_framework_core cvss_temporal_score
|
73
|
+
exploit_available metasploit_name exploit_framework_canvas canvas_package exploit_framework_metasploit
|
74
|
+
plugin_type exploithub_sku exploit_framework_exploithub stig_severity plugin_name fname always_run
|
75
|
+
cm:compliance-info cm:compliance-actual-value cm:compliance-check-id cm:compliance-policy-value
|
76
|
+
cm:compliance-audit-file cm:compliance-check-name cm:compliance-result cm:compliance-output policyOwner
|
77
|
+
visibility script_version attachment policy_comments d2_elliot_name exploit_framework_d2_elliot
|
78
|
+
exploited_by_malware compliance
|
79
|
+
])
|
80
|
+
|
81
|
+
# TODO: documentation. These are never used in the class
|
82
|
+
VALID_HOST_PROPERTIES_REGEX = [
|
83
|
+
"patch-summary-cve-num", "patch-summary-cves", "patch-summary-txt", "cpe-\d+", "KB\d+"
|
84
|
+
]
|
85
|
+
|
86
|
+
# Map of host properties to symbols for use with ActiveRecord
|
87
|
+
# interfaces
|
88
|
+
#
|
89
|
+
# These are the more commonly used host properties,
|
90
|
+
# mapping them here to store in the host table
|
91
|
+
HOST_PROPERTIES_MAPPING = {
|
92
|
+
"HOST_END" => :end,
|
93
|
+
"mac-address" => :mac,
|
94
|
+
"HOST_START" => :start,
|
95
|
+
"operating-system" => :os,
|
96
|
+
"host-ip" => :ip,
|
97
|
+
"host-fqdn" => :fqdn,
|
98
|
+
"netbios-name" => :netbios
|
99
|
+
}
|
100
|
+
|
101
|
+
# Used to map element names to private methods so
|
102
|
+
# that the methods can be called when the parser
|
103
|
+
# encounters the opening of an element.
|
104
|
+
#
|
105
|
+
# {"ElementName" => :start_method_to_be_called}
|
106
|
+
#
|
107
|
+
# @example call #start_policy for a "Policy" element
|
108
|
+
# element = "Policy"
|
109
|
+
# send(DYNAMIC_START_METHOD_NAMES[element], element, attributes)
|
110
|
+
#
|
111
|
+
# @param element [String] the element name starting to be parsed
|
112
|
+
# @param attributes [Array<Hash{Sring=>String}>] the array of
|
113
|
+
# key value pairs for the element that is starting to be parsed
|
114
|
+
DYNAMIC_START_METHOD_NAMES = {
|
115
|
+
"Policy" => :start_policy,
|
116
|
+
"preference" => :start_preference,
|
117
|
+
"item" => :start_item,
|
118
|
+
"FamilyItem" => :start_family_item,
|
119
|
+
"PluginItem" => :start_plugin_item,
|
120
|
+
"Report" => :start_report,
|
121
|
+
"ReportHost" => :start_report_host,
|
122
|
+
"tag" => :start_tag,
|
123
|
+
"ReportItem" => :start_report_item,
|
124
|
+
"attachment" => :start_attachment
|
125
|
+
}
|
126
|
+
|
127
|
+
# @see DYNAMIC_START_MEHTOD_NAMES
|
128
|
+
#
|
129
|
+
# @note only one argument for the methods
|
130
|
+
#
|
131
|
+
# @example call #end_policy_name for a "policyName" element
|
132
|
+
# element = "policyName"
|
133
|
+
# send(DYNAMIC_END_METHOD_NAMES[element], element)
|
134
|
+
#
|
135
|
+
# @param element [String] the name of the element ending
|
136
|
+
DYNAMIC_END_METHOD_NAMES = {
|
137
|
+
"policyName" => :end_policy_name,
|
138
|
+
"policyComments" => :end_policy_comments,
|
139
|
+
"policy_comments" => :end_policy_comments,
|
140
|
+
"policyOwner" => :end_policy_owner,
|
141
|
+
"visibility" => :end_visibility,
|
142
|
+
"preference" => :end_preference,
|
143
|
+
"item" => :end_item,
|
144
|
+
"FamilyItem" => :end_family_item,
|
145
|
+
"PluginItem" => :end_plugin_item,
|
146
|
+
"tag" => :end_tag,
|
147
|
+
"ReportItem" => :end_report_item,
|
148
|
+
"attachment" => :end_attachment
|
149
|
+
}
|
150
|
+
|
151
|
+
private_constant :DYNAMIC_END_METHOD_NAMES, :DYNAMIC_START_METHOD_NAMES,
|
152
|
+
:HOST_PROPERTIES_MAPPING, :VALID_HOST_PROPERTIES_REGEX, :VALID_HOST_PROPERTIES,
|
153
|
+
:VALID_ELEMENTS, :VALID_REFERENCES
|
154
|
+
|
155
|
+
# vals tracks state for elements encountered during parsing
|
38
156
|
def initialize
|
39
157
|
@vals = Hash.new
|
40
|
-
|
41
|
-
@valid_references = Array[
|
42
|
-
"cpe", "bid", "see_also", "xref", "cve", "iava", "msft",
|
43
|
-
"osvdb", "cert", "edb-id", "rhsa", "secunia", "suse", "dsa",
|
44
|
-
"owasp", "cwe", "iavb", "iavt", "cisco-sa", "ics-alert",
|
45
|
-
"cisco-bug-id", "cisco-sr", "cert-vu", "vmsa", "apple-sa",
|
46
|
-
"icsa", "cert-cc", "msvr", "usn", "hp", "glsa", "freebsd"
|
47
|
-
]
|
48
|
-
|
49
|
-
@valid_host_properties = Array[
|
50
|
-
"HOST_END", "mac-address", "HOST_START", "operating-system", "host-ip", "host-fqdn", "netbios-name",
|
51
|
-
"local-checks-proto", "smb-login-used", "ssh-auth-meth", "ssh-login-used", "pci-dss-compliance",
|
52
|
-
"pci-dss-compliance:", "system-type", "bios-uuid", "pcidss:compliance:failed", "pcidss:compliance:passed",
|
53
|
-
"pcidss:deprecated_ssl", "pcidss:expired_ssl_certificate", "pcidss:high_risk_flaw", "pcidss:medium_risk_flaw",
|
54
|
-
"pcidss:reachable_db", "pcidss:www:xss", "pcidss:directory_browsing", "pcidss:known_credentials",
|
55
|
-
"pcidss:compromised_host:worm", "pcidss:obsolete_operating_system", "pcidss:dns_zone_transfer",
|
56
|
-
"pcidss:unprotected_mssql_db", "pcidss:obsolete_software", "pcidss:www:sql_injection", "pcidss:backup_files",
|
57
|
-
"traceroute-hop-0", "traceroute-hop-1", "traceroute-hop-2", "operating-system-unsupported", "patch-summary-total-cves",
|
58
|
-
"pcidss:insecure_http_methods", "LastUnauthenticatedResults", "LastAuthenticatedResults", "cpe-0", "cpe-1",
|
59
|
-
"cpe-2", "cpe-3", "Credentialed_Scan", "policy-used", "UnsupportedProduct:microsoft:windows_xp::sp2",
|
60
|
-
"UnsupportedProduct:microsoft:windows_xp", "UnsupportedProduct:microsoft:windows_2000", "UnsupportedProduct"
|
61
|
-
]
|
62
|
-
|
63
|
-
@valid_host_properties_regex = Array[
|
64
|
-
"patch-summary-cve-num", "patch-summary-cves", "patch-summary-txt", "cpe-\d+", "KB\d+"
|
65
|
-
]
|
66
|
-
|
67
|
-
@valid_elements = Array["ReportItem", "plugin_version", "risk_factor",
|
68
|
-
"description", "cvss_base_score", "solution", "item", "plugin_output", "tag", "synopsis", "plugin_modification_date",
|
69
|
-
"FamilyName", "FamilyItem", "Status", "vuln_publication_date", "ReportHost", "HostProperties", "preferenceName",
|
70
|
-
"preferenceValues", "preferenceType", "fullName", "pluginId", "pluginName", "selectedValue", "selectedValue",
|
71
|
-
"name", "value", "preference", "plugin_publication_date", "cvss_vector", "patch_publication_date",
|
72
|
-
"NessusClientData_v2", "Policy", "PluginName", "ServerPreferences", "policyComments", "policyName", "PluginItem",
|
73
|
-
"Report", "Family", "Preferences", "PluginsPreferences", "FamilySelection", "IndividualPluginSelection", "PluginId",
|
74
|
-
"pci-dss-compliance", "exploitability_ease", "cvss_temporal_vector", "exploit_framework_core", "cvss_temporal_score",
|
75
|
-
"exploit_available", "metasploit_name", "exploit_framework_canvas", "canvas_package", "exploit_framework_metasploit",
|
76
|
-
"plugin_type", "exploithub_sku", "exploit_framework_exploithub", "stig_severity", "plugin_name", "fname", "always_run",
|
77
|
-
"cm:compliance-info", "cm:compliance-actual-value", "cm:compliance-check-id", "cm:compliance-policy-value",
|
78
|
-
"cm:compliance-audit-file", "cm:compliance-check-name", "cm:compliance-result", "cm:compliance-output", "policyOwner",
|
79
|
-
"visibility", "script_version", "attachment", "policy_comments", "d2_elliot_name", "exploit_framework_d2_elliot",
|
80
|
-
"exploited_by_malware", "compliance"
|
81
|
-
]
|
82
|
-
|
83
|
-
@valid_elements = @valid_elements + @valid_references
|
84
|
-
|
85
|
-
# These are the more commonly used host properties, mapping them here to store in the host table
|
86
|
-
@host_properties_mapping = {
|
87
|
-
"HOST_END" => :end,
|
88
|
-
"mac-address" => :mac,
|
89
|
-
"HOST_START" => :start,
|
90
|
-
"operating-system" => :os,
|
91
|
-
"host-ip" => :ip,
|
92
|
-
"host-fqdn" => :fqdn,
|
93
|
-
"netbios-name" => :netbios
|
94
|
-
}
|
95
158
|
end
|
96
159
|
|
97
160
|
# Callback for when the start of a XML element is reached
|
@@ -102,95 +165,14 @@ module Risu
|
|
102
165
|
@tag = element
|
103
166
|
@vals[@tag] = ""
|
104
167
|
|
105
|
-
if
|
168
|
+
if !VALID_ELEMENTS.include?(element)
|
106
169
|
puts "New XML element detected: #{element}. Please report this at #{Risu::GITHUB}/issues/new or via email to #{Risu::EMAIL}"
|
107
170
|
end
|
108
171
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
when "preference"
|
114
|
-
@sp = @policy.server_preferences.create
|
115
|
-
@sp.save
|
116
|
-
when "item"
|
117
|
-
@item = @policy.plugins_preferences.create
|
118
|
-
@item.save
|
119
|
-
when "FamilyItem"
|
120
|
-
@family = @policy.family_selections.create
|
121
|
-
@family.save
|
122
|
-
when "PluginItem"
|
123
|
-
@plugin_selection = @policy.individual_plugin_selections.create
|
124
|
-
@plugin_selection.save
|
125
|
-
when "Report"
|
126
|
-
@report = @policy.reports.create
|
127
|
-
@report.name = attributes["name"]
|
128
|
-
@report.save
|
129
|
-
when "ReportHost"
|
130
|
-
@rh = @report.hosts.create
|
131
|
-
@rh.name = attributes["name"]
|
132
|
-
@rh.save
|
133
|
-
when "tag"
|
134
|
-
@attr = nil
|
135
|
-
@hp = @rh.host_properties.create
|
136
|
-
|
137
|
-
if attributes["name"] =~ /[M|m][S|s]\d{2,}-\d{2,}/
|
138
|
-
@attr = if attributes["name"] =~ /[M|m][S|s]\d{2,}-\d{2,}/
|
139
|
-
attributes["name"]
|
140
|
-
else
|
141
|
-
nil
|
142
|
-
end
|
143
|
-
#Ugly as fuck. Really this needs to be rewritten. Fuck.
|
144
|
-
elsif attributes['name'] =~ /patch-summary-cve-num/ ||
|
145
|
-
attributes['name'] =~ /patch-summary-cves/ ||
|
146
|
-
attributes['name'] =~ /patch-summary-txt/ ||
|
147
|
-
attributes['name'] =~ /cpe-\d+/ ||
|
148
|
-
attributes['name'] =~ /KB\d+/
|
149
|
-
@attr = if attributes["name"] =~ /patch-summary-cve-num/ ||
|
150
|
-
attributes['name'] =~ /patch-summary-cves/ ||
|
151
|
-
attributes['name'] =~ /patch-summary-txt/ ||
|
152
|
-
attributes['name'] =~ /cpe-\d+/ ||
|
153
|
-
attributes['name'] =~ /KB\d+/
|
154
|
-
attributes["name"]
|
155
|
-
else
|
156
|
-
nil
|
157
|
-
end
|
158
|
-
else
|
159
|
-
@attr = if @valid_host_properties.include?(attributes["name"])
|
160
|
-
attributes["name"]
|
161
|
-
else
|
162
|
-
nil
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
# implicit nil check?
|
167
|
-
if attributes["name"] !~ /(netstat-(?:established|listen)-(?:tcp|udp)\d+-\d+)/ && attributes["name"] !~ /traceroute-hop-\d+/
|
168
|
-
puts "New HostProperties attribute: #{attributes["name"]}. Please report this at #{Risu::GITHUB}/issues/new or via email to #{Risu::EMAIL}\n" if @attr.nil?
|
169
|
-
end
|
170
|
-
when "ReportItem"
|
171
|
-
@vals = Hash.new # have to clear this out or everything has the same references
|
172
|
-
@ri = @rh.items.create
|
173
|
-
if attributes["pluginID"] == "0"
|
174
|
-
@plugin = Risu::Models::Plugin.find_or_create_by(:id => 1)
|
175
|
-
else
|
176
|
-
@plugin = Risu::Models::Plugin.find_or_create_by(:id => attributes["pluginID"])
|
177
|
-
end
|
178
|
-
|
179
|
-
@ri.port = attributes["port"]
|
180
|
-
@ri.svc_name = attributes["svc_name"]
|
181
|
-
@ri.protocol = attributes["protocol"]
|
182
|
-
@ri.severity = attributes["severity"]
|
183
|
-
|
184
|
-
@ri.plugin_id = @plugin.id
|
185
|
-
@plugin.plugin_name = attributes["pluginName"]
|
186
|
-
@plugin.family_name = attributes["pluginFamily"]
|
187
|
-
@plugin.save
|
188
|
-
@ri.save
|
189
|
-
when "attachment"
|
190
|
-
@attachment = @ri.attachments.create
|
191
|
-
@attachment.name = attributes['name']
|
192
|
-
@attachment.type = attributes['type']
|
193
|
-
@attachment.save
|
172
|
+
if DYNAMIC_START_METHOD_NAMES.key?(element)
|
173
|
+
# Dynamic dispatch to private instance "policyComments"methods in the const hash
|
174
|
+
# DYNAMIC_START_METHOD_NAMES where {"element" => :start_element}
|
175
|
+
send(DYNAMIC_START_METHOD_NAMES[element], element, attributes)
|
194
176
|
end
|
195
177
|
end
|
196
178
|
|
@@ -210,160 +192,221 @@ module Risu
|
|
210
192
|
# @param element
|
211
193
|
def on_end_element(element)
|
212
194
|
@tag = nil
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
}
|
279
|
-
|
280
|
-
@family.save
|
281
|
-
when "PluginItem"
|
282
|
-
@plugin_selection.attributes = {
|
283
|
-
:plugin_id => @vals["PluginId"],
|
284
|
-
:plugin_name => @vals["PluginName"],
|
285
|
-
:family => @vals["Family"],
|
286
|
-
:status => @vals["Status"]
|
287
|
-
}
|
288
|
-
|
289
|
-
@plugin_selection.save
|
290
|
-
when "tag"
|
291
|
-
if @attr =~ /[M|m][S|s]\d{2}-\d{2,}/
|
292
|
-
@patch = @rh.patches.create
|
293
|
-
@patch.name = @attr
|
294
|
-
@patch.value = @vals['tag']
|
295
|
-
@patch.save
|
296
|
-
else
|
297
|
-
@rh.attributes = {@host_properties_mapping[@attr] => @vals["tag"].gsub("\n", ",") } if @host_properties_mapping.keys.include?(@attr)
|
298
|
-
@rh.save
|
299
|
-
|
300
|
-
@hp.name = @attr
|
301
|
-
@hp.value = @vals['tag']
|
302
|
-
@hp.save
|
303
|
-
|
304
|
-
end if @attr != nil
|
305
|
-
#We cannot handle the references in the same block as the rest of the ReportItem tag because
|
306
|
-
#there tends to be more than of the different types of reference per ReportItem, this causes issue for a sax
|
307
|
-
#parser. To solve this we do the references before the final plugin data, Valid references must be added
|
308
|
-
#the @valid_reference array at the top to be parsed.
|
309
|
-
# *@valid_reference, does a 'when' on each element of the @valid_references array, pure magic
|
310
|
-
when *@valid_references
|
311
|
-
@ref = @plugin.references.create
|
312
|
-
@ref.reference_name = element
|
313
|
-
@ref.value = @vals["#{element}"]
|
314
|
-
@ref.save
|
315
|
-
when "ReportItem"
|
316
|
-
@ri.plugin_output = @vals["plugin_output"]
|
317
|
-
@ri.plugin_name = @vals["plugin_name"]
|
318
|
-
@ri.cm_compliance_info = @vals["cm:compliance-info"]
|
319
|
-
@ri.cm_compliance_actual_value = @vals["cm:compliance-actual-value"]
|
320
|
-
@ri.cm_compliance_check_id = @vals["cm:compliance-check-id"]
|
321
|
-
@ri.cm_compliance_policy_value= @vals["cm:compliance-policy-value"]
|
322
|
-
@ri.cm_compliance_audit_file = @vals["cm:compliance-audit-file"]
|
323
|
-
@ri.cm_compliance_check_name = @vals["cm:compliance-check-name"]
|
324
|
-
@ri.cm_compliance_result = @vals["cm:compliance-result"]
|
325
|
-
@ri.cm_compliance_output = @vals["cm:compliance-output"]
|
326
|
-
|
327
|
-
@ri.save
|
328
|
-
|
329
|
-
@plugin.attributes = {
|
330
|
-
:solution => @vals["solution"],
|
331
|
-
:risk_factor => @vals["risk_factor"],
|
332
|
-
:description => @vals["description"],
|
333
|
-
:plugin_publication_date => @vals["plugin_publication_date"],
|
334
|
-
:plugin_modification_date => @vals["plugin_modification_date"],
|
335
|
-
:synopsis => @vals["synopsis"],
|
336
|
-
:plugin_type => @vals["plugin_type"],
|
337
|
-
:cvss_vector => @vals["cvss_vector"],
|
338
|
-
:cvss_base_score => @vals["cvss_base_score"].to_f,
|
339
|
-
:vuln_publication_date => @vals["vuln_publication_date"],
|
340
|
-
:plugin_version => @vals["plugin_version"],
|
341
|
-
:cvss_temporal_score => @vals["cvss_temporal_score"],
|
342
|
-
:cvss_temporal_vector => @vals["cvss_temporal_vector"],
|
343
|
-
:exploitability_ease => @vals["exploitability_ease"],
|
344
|
-
:exploit_framework_core => @vals["exploit_framework_core"],
|
345
|
-
:exploit_available => @vals["exploit_available"],
|
346
|
-
:exploit_framework_metasploit => @vals["exploit_framework_metasploit"],
|
347
|
-
:metasploit_name => @vals["metasploit_name"],
|
348
|
-
:exploit_framework_canvas => @vals["exploit_framework_canvas"],
|
349
|
-
:canvas_package => @vals["canvas_package"],
|
350
|
-
:exploit_framework_exploithub => @vals["exploit_framework_exploithub"],
|
351
|
-
:exploithub_sku => @vals["exploithub_sku"],
|
352
|
-
:stig_severity => @vals["stig_severity"],
|
353
|
-
:fname => @vals["fname"],
|
354
|
-
:always_run => @vals["always_run"],
|
355
|
-
:script_version => @vals["script_version"],
|
356
|
-
:exploited_by_malware => @vals["exploited_by_malware"],
|
357
|
-
:compliance => @vals["compliance"]
|
358
|
-
}
|
359
|
-
@plugin.save
|
360
|
-
when "attachment"
|
361
|
-
@attachment.attributes = {
|
362
|
-
:ahash => @vals['attachment']
|
363
|
-
}
|
364
|
-
@attachment.save
|
195
|
+
|
196
|
+
if DYNAMIC_END_METHOD_NAMES.key?(element)
|
197
|
+
# Dynamic dispatch to private instance methods in the const hash
|
198
|
+
# DYNAMIC_END_METHOD_NAMES where {"element" => :end_element}
|
199
|
+
send(DYNAMIC_END_METHOD_NAMES[element], element)
|
200
|
+
elsif VALID_REFERENCES.include?(element)
|
201
|
+
end_valid_reference(element)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
private
|
206
|
+
|
207
|
+
# Dynamic dispatch start element methods
|
208
|
+
def start_policy(_element, _attributes)
|
209
|
+
@policy = Risu::Models::Policy.create
|
210
|
+
end
|
211
|
+
|
212
|
+
def start_preference(_element, _attributes)
|
213
|
+
@sp = @policy.server_preferences.create
|
214
|
+
end
|
215
|
+
|
216
|
+
def start_item(_element, _attributes)
|
217
|
+
@item = @policy.plugins_preferences.create
|
218
|
+
end
|
219
|
+
|
220
|
+
def start_family_item(_element, _attributes)
|
221
|
+
@family = @policy.family_selections.create
|
222
|
+
end
|
223
|
+
|
224
|
+
def start_plugin_item(_element, _attributes)
|
225
|
+
@plugin_selection = @policy.individual_plugin_selections.create
|
226
|
+
end
|
227
|
+
|
228
|
+
def start_report(_element, attributes)
|
229
|
+
@report = @policy.reports.create(:name => attributes["name"])
|
230
|
+
end
|
231
|
+
|
232
|
+
def start_report_host(_element, attributes)
|
233
|
+
@rh = @report.hosts.create(:name => attributes["name"])
|
234
|
+
end
|
235
|
+
|
236
|
+
def start_tag(_, attributes)
|
237
|
+
@attr = nil
|
238
|
+
@hp = @rh.host_properties.create
|
239
|
+
|
240
|
+
if attributes["name"] =~ /[M|m][S|s]\d{2,}-\d{2,}/
|
241
|
+
@attr = attributes["name"]
|
242
|
+
#Ugly as fuck. Really this needs to be rewritten. Fuck.
|
243
|
+
elsif attributes['name'] =~ /
|
244
|
+
(?:patch-summary-cve-num)
|
245
|
+
| (?:patch-summary-cves)
|
246
|
+
| (?:patch-summary-txt)
|
247
|
+
| (?:cpe-\d+)
|
248
|
+
| (?:KB\d+)
|
249
|
+
/x
|
250
|
+
@attr = attributes["name"]
|
251
|
+
elsif VALID_HOST_PROPERTIES.include?(attributes["name"])
|
252
|
+
@attr = attributes["name"]
|
253
|
+
end
|
254
|
+
|
255
|
+
# implicit nil check?
|
256
|
+
if attributes["name"] !~ /(netstat-(?:established|listen)-(?:tcp|udp)\d+-\d+)/ \
|
257
|
+
&& attributes["name"] !~ /traceroute-hop-\d+/ \
|
258
|
+
&& @attr.nil?
|
259
|
+
puts "New HostProperties attribute: #{attributes["name"]}. Please report this at #{Risu::GITHUB}/issues/new or via email to #{Risu::EMAIL}\n"
|
365
260
|
end
|
366
261
|
end
|
262
|
+
|
263
|
+
def start_report_item(_element, attributes)
|
264
|
+
@vals = Hash.new # have to clear this out or everything has the same references
|
265
|
+
|
266
|
+
if attributes["pluginID"] == "0"
|
267
|
+
@plugin = Risu::Models::Plugin.find_or_create_by(:id => 1)
|
268
|
+
else
|
269
|
+
@plugin = Risu::Models::Plugin.find_or_create_by(:id => attributes["pluginID"]) do |plugin|
|
270
|
+
plugin.plugin_name = attributes["pluginName"]
|
271
|
+
plugin.family_name = attributes["pluginFamily"]
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
@ri = @rh.items.create(:port => attributes["port"],
|
276
|
+
:svc_name => attributes["svc_name"],
|
277
|
+
:protocol => attributes["protocol"],
|
278
|
+
:severity => attributes["severity"],
|
279
|
+
:plugin_id => @plugin.id)
|
280
|
+
|
281
|
+
@plugin.save
|
282
|
+
end
|
283
|
+
|
284
|
+
def start_attachment(_element, attributes)
|
285
|
+
@attachment = @ri.attachments.create(:name => attributes['name'], :ttype => attributes['type'])
|
286
|
+
end
|
287
|
+
|
288
|
+
# Dynamic dispatch end element methods
|
289
|
+
def end_policy_name(_)
|
290
|
+
@policy.update(:name => @vals["policyName"])
|
291
|
+
end
|
292
|
+
|
293
|
+
def end_policy_comments(element)
|
294
|
+
return unless element == "policyComments" || element == "policy_comments"
|
295
|
+
@policy.update(:comments => @vals[element])
|
296
|
+
end
|
297
|
+
|
298
|
+
def end_policy_owner(_)
|
299
|
+
@policy.update(:owner => @vals["policyOwner"])
|
300
|
+
end
|
301
|
+
|
302
|
+
def end_visibility(_)
|
303
|
+
@policy.update(:visibility => @vals["visibility"])
|
304
|
+
end
|
305
|
+
|
306
|
+
def end_preference(_)
|
307
|
+
@sp.update(:name => @vals["name"], :value => @vals["value"])
|
308
|
+
end
|
309
|
+
|
310
|
+
# This takes a really long time, there is about 34,000 pluginIDs in this
|
311
|
+
# field and it takes about 36 minutes to parse just this info =\
|
312
|
+
# lets pre-populate the plugins table with the known plugin_id's
|
313
|
+
#
|
314
|
+
# if @vals["name"] == "plugin_set"
|
315
|
+
# @all_plugins = @vals["value"].split(";")
|
316
|
+
#
|
317
|
+
# @all_plugins.each { |p|
|
318
|
+
# @plug = Plugin.find_or_create_by_id(p)
|
319
|
+
# @plug.save
|
320
|
+
# }
|
321
|
+
# end
|
322
|
+
def end_item(_)
|
323
|
+
@item.update(:plugin_name => @vals["pluginName"],
|
324
|
+
:plugin_id => @vals["pluginId"], :fullname => @vals["fullName"],
|
325
|
+
:preference_name => @vals["preferenceName"],
|
326
|
+
:preference_type => @vals["preferenceType"],
|
327
|
+
:preference_values => @vals["preferenceValues"],
|
328
|
+
:selected_values => @vals["selectedValue"])
|
329
|
+
end
|
330
|
+
|
331
|
+
def end_family_item(_)
|
332
|
+
@family.update( :family_name => @vals["FamilyName"],
|
333
|
+
:status => @vals["Status"])
|
334
|
+
end
|
335
|
+
|
336
|
+
def end_plugin_item(_)
|
337
|
+
@plugin_selection.update(:plugin_id => @vals["PluginId"],
|
338
|
+
:plugin_name => @vals["PluginName"],
|
339
|
+
:family => @vals["Family"], :status => @vals["Status"])
|
340
|
+
end
|
341
|
+
|
342
|
+
def end_tag(_)
|
343
|
+
return if @attr.nil?
|
344
|
+
|
345
|
+
if @attr =~ /[M|m][S|s]\d{2}-\d{2,}/
|
346
|
+
@patch = @rh.patches.create(:name => @attr, :value => @vals['tag'])
|
347
|
+
else
|
348
|
+
if HOST_PROPERTIES_MAPPING.key?(@attr)
|
349
|
+
@rh.update(HOST_PROPERTIES_MAPPING[@attr] => @vals["tag"].gsub("\n", ","))
|
350
|
+
end
|
351
|
+
|
352
|
+
@hp.update(:name => @attr, :value => @vals['tag'])
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
#We cannot handle the references in the same block as the rest of the ReportItem tag because
|
357
|
+
#there tends to be more than of the different types of reference per ReportItem, this causes issue for a sax
|
358
|
+
#parser. To solve this we do the references before the final plugin data, Valid references must be added
|
359
|
+
#the VALID_REFERENCE set at the top to be parsed.
|
360
|
+
def end_valid_reference(element)
|
361
|
+
@ref = @plugin.references.create(:reference_name => element,
|
362
|
+
:value => @vals["#{element}"])
|
363
|
+
end
|
364
|
+
|
365
|
+
def end_report_item(_)
|
366
|
+
@ri.update(:plugin_output => @vals["plugin_output"],
|
367
|
+
:plugin_name => @vals["plugin_name"],
|
368
|
+
:cm_compliance_info => @vals["cm:compliance-info"],
|
369
|
+
:cm_compliance_actual_value => @vals["cm:compliance-actual-value"],
|
370
|
+
:cm_compliance_check_id => @vals["cm:compliance-check-id"],
|
371
|
+
:cm_compliance_policy_value => @vals["cm:compliance-policy-value"],
|
372
|
+
:cm_compliance_audit_file => @vals["cm:compliance-audit-file"],
|
373
|
+
:cm_compliance_check_name => @vals["cm:compliance-check-name"],
|
374
|
+
:cm_compliance_result => @vals["cm:compliance-result"],
|
375
|
+
:cm_compliance_output => @vals["cm:compliance-output"])
|
376
|
+
|
377
|
+
@plugin.update(:solution => @vals["solution"],
|
378
|
+
:risk_factor => @vals["risk_factor"],
|
379
|
+
:description => @vals["description"],
|
380
|
+
:plugin_publication_date => @vals["plugin_publication_date"],
|
381
|
+
:plugin_modification_date => @vals["plugin_modification_date"],
|
382
|
+
:synopsis => @vals["synopsis"],
|
383
|
+
:plugin_type => @vals["plugin_type"],
|
384
|
+
:cvss_vector => @vals["cvss_vector"],
|
385
|
+
:cvss_base_score => @vals["cvss_base_score"].to_f,
|
386
|
+
:vuln_publication_date => @vals["vuln_publication_date"],
|
387
|
+
:plugin_version => @vals["plugin_version"],
|
388
|
+
:cvss_temporal_score => @vals["cvss_temporal_score"],
|
389
|
+
:cvss_temporal_vector => @vals["cvss_temporal_vector"],
|
390
|
+
:exploitability_ease => @vals["exploitability_ease"],
|
391
|
+
:exploit_framework_core => @vals["exploit_framework_core"],
|
392
|
+
:exploit_available => @vals["exploit_available"],
|
393
|
+
:exploit_framework_metasploit => @vals["exploit_framework_metasploit"],
|
394
|
+
:metasploit_name => @vals["metasploit_name"],
|
395
|
+
:exploit_framework_canvas => @vals["exploit_framework_canvas"],
|
396
|
+
:canvas_package => @vals["canvas_package"],
|
397
|
+
:exploit_framework_exploithub => @vals["exploit_framework_exploithub"],
|
398
|
+
:exploithub_sku => @vals["exploithub_sku"],
|
399
|
+
:stig_severity => @vals["stig_severity"],
|
400
|
+
:fname => @vals["fname"],
|
401
|
+
:always_run => @vals["always_run"],
|
402
|
+
:script_version => @vals["script_version"],
|
403
|
+
:exploited_by_malware => @vals["exploited_by_malware"],
|
404
|
+
:compliance => @vals["compliance"])
|
405
|
+
end
|
406
|
+
|
407
|
+
def end_attachment(_)
|
408
|
+
@attachment.update(:ahash => @vals['attachment'])
|
409
|
+
end
|
367
410
|
end
|
368
411
|
end
|
369
412
|
end
|
@@ -34,12 +34,7 @@ module Risu
|
|
34
34
|
class SimpleNexpose
|
35
35
|
include LibXML::XML::SaxParser::Callbacks
|
36
36
|
|
37
|
-
|
38
|
-
#
|
39
|
-
def initialize
|
40
|
-
@vals = Hash.new
|
41
|
-
|
42
|
-
@valid_fingerprints = {
|
37
|
+
VALID_FINGERPRINTS = {
|
43
38
|
"description" => :os,
|
44
39
|
"vendor" => nil,
|
45
40
|
"family" => nil,
|
@@ -49,6 +44,11 @@ module Risu
|
|
49
44
|
"architecture" => nil
|
50
45
|
}
|
51
46
|
|
47
|
+
# @todo comment
|
48
|
+
#
|
49
|
+
def initialize
|
50
|
+
@vals = Hash.new
|
51
|
+
|
52
52
|
@report = Report.create
|
53
53
|
end
|
54
54
|
|
@@ -93,7 +93,7 @@ module Risu
|
|
93
93
|
@in_device = false
|
94
94
|
when "description"
|
95
95
|
if @in_device && @in_fingerprint
|
96
|
-
@rh.attributes = {
|
96
|
+
@rh.attributes = { VALID_FINGERPRINTS[element] => @vals[element].gsub("\n", ",") } if VALID_FINGERPRINTS.key?(element)
|
97
97
|
@rh.save
|
98
98
|
end
|
99
99
|
when "fingerprint"
|
@@ -34,117 +34,75 @@ module Risu
|
|
34
34
|
{
|
35
35
|
:name => "technical_findings",
|
36
36
|
:author => "hammackj",
|
37
|
-
:version => "0.0.
|
37
|
+
:version => "0.0.9",
|
38
38
|
:renderer => "PDF",
|
39
39
|
:description => "Generates a Technical Findings Report"
|
40
40
|
}
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
43
|
+
def print_technical_findings(risks, text, color, last=false)
|
44
|
+
if risks.length > 0
|
45
|
+
title text, 18, color
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
text "\n\n\n"
|
47
|
+
risks.each do |f|
|
48
|
+
hosts = Item.where(:plugin_id => f.plugin_id).group(:host_id)
|
49
|
+
plugin = Plugin.find_by_id(f.plugin_id)
|
52
50
|
|
53
|
-
|
54
|
-
unique_risks << Hash[:title => "Critical Findings", :color => Risu::GRAPH_COLORS[0], :values => Item.critical_risks_unique] if Item.critical_risks_unique.to_a.size != 0
|
55
|
-
unique_risks << Hash[:title => "High Findings", :color => Risu::GRAPH_COLORS[1], :values => Item.high_risks_unique] if Item.high_risks_unique.to_a.size != 0
|
51
|
+
references = Reference.where(:plugin_id => plugin.id).group(:value).order(:reference_name)
|
56
52
|
|
57
|
-
|
58
|
-
|
53
|
+
output.font_size(16) do
|
54
|
+
text "#{plugin.plugin_name}\n"
|
55
|
+
end
|
59
56
|
|
60
|
-
|
61
|
-
|
57
|
+
if hosts.length > 1
|
58
|
+
text "Hosts", :style => :bold
|
59
|
+
else
|
60
|
+
text "Host", :style => :bold
|
61
|
+
end
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
hostlist = Array.new
|
64
|
+
hosts.each do |host|
|
65
|
+
ho = Host.find_by_id(host.host_id)
|
66
|
+
host_string = "#{ho.name}"
|
67
|
+
host_string << " (#{ho.fqdn})" if ho.fqdn != nil
|
68
|
+
hostlist << host_string
|
67
69
|
end
|
68
70
|
|
69
|
-
text
|
71
|
+
text hostlist.join(', ')
|
70
72
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
text "Hosts", :style => :bold
|
84
|
-
else
|
85
|
-
text "Host", :style => :bold
|
86
|
-
end
|
87
|
-
|
88
|
-
hostlist = Array.new
|
89
|
-
hosts.each do |host|
|
90
|
-
ho = Host.find_by_id(host.host_id)
|
91
|
-
#if h.id != blacklist_host_id.first.id
|
92
|
-
host_string = "#{ho.name}"
|
93
|
-
host_string << " (#{ho.fqdn})" if ho.fqdn != nil
|
94
|
-
hostlist << host_string
|
95
|
-
#end
|
96
|
-
end
|
97
|
-
|
98
|
-
text hostlist.join(', ')
|
99
|
-
|
100
|
-
if f.plugin_output != nil
|
101
|
-
text "\nPlugin output", :style => :bold
|
102
|
-
text f.plugin_output
|
103
|
-
end
|
104
|
-
|
105
|
-
if plugin.description != nil
|
106
|
-
text "\nDescription", :style => :bold
|
107
|
-
text plugin.description.gsub(/[ ]{2,}/, " "), :inline_format => true
|
108
|
-
end
|
109
|
-
|
110
|
-
if plugin.synopsis != nil
|
111
|
-
text "\nSynopsis", :style => :bold
|
112
|
-
text plugin.synopsis
|
113
|
-
end
|
114
|
-
|
115
|
-
if plugin.cvss_base_score != nil
|
116
|
-
text "\nCVSS Base Score", :style => :bold
|
117
|
-
text plugin.cvss_base_score
|
118
|
-
end
|
119
|
-
|
120
|
-
if plugin.exploit_available != nil
|
121
|
-
text "\nExploit Available", :style => :bold
|
122
|
-
|
123
|
-
if plugin.exploit_available == "true"
|
124
|
-
text "Yes"
|
125
|
-
else
|
126
|
-
text "No"
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
if plugin.solution != nil
|
131
|
-
text "\nSolution", :style => :bold
|
132
|
-
text plugin.solution
|
133
|
-
end
|
134
|
-
|
135
|
-
if references.size != 0
|
136
|
-
text "\nReferences", :style => :bold
|
137
|
-
text plugin.references.reference_string, :inline_format => true
|
138
|
-
plugin_url = "http://www.tenablesecurity.com/plugins/index.php?view=single&id=#{plugin.id}"
|
139
|
-
text "<b>nessus_plugin</b>: #{plugin_url}", :inline_format => true, :link => plugin_url
|
140
|
-
end
|
141
|
-
|
142
|
-
text "\n"
|
143
|
-
end
|
73
|
+
definition "Plugin output", f.plugin_output
|
74
|
+
definition "Description", plugin.description.gsub(/[ ]{2,}/, " ") if plugin.description != nil
|
75
|
+
definition "Synopsis", plugin.synopsis
|
76
|
+
definition "CVSS Base Score", plugin.cvss_base_score
|
77
|
+
definition "Exploit Available", (plugin.exploit_available == "true") ? "Yes" : "No"
|
78
|
+
definition "Solution", plugin.solution
|
79
|
+
definition "References", plugin.references.reference_string, :inline_format => true
|
80
|
+
|
81
|
+
plugin_url = "http://www.tenablesecurity.com/plugins/index.php?view=single&id=#{plugin.id}"
|
82
|
+
definition "Nessus Plugin", plugin_url, :inline_format => true, :link => plugin_url
|
83
|
+
|
84
|
+
text "\n"
|
144
85
|
end
|
145
86
|
|
146
|
-
output.start_new_page if
|
87
|
+
@output.start_new_page if last == false
|
147
88
|
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def render(output)
|
92
|
+
text Report.classification.upcase, :align => :center
|
93
|
+
text "\n"
|
94
|
+
|
95
|
+
report_title Report.title
|
96
|
+
report_subtitle "Technical Findings"
|
97
|
+
report_author "This report was prepared by\n#{Report.author}"
|
98
|
+
text "\n\n\n"
|
99
|
+
|
100
|
+
# If you uncomment the med/low change the true in high to false for a new page after it
|
101
|
+
|
102
|
+
print_technical_findings(Item.critical_risks_unique, "Critical Findings", Risu::GRAPH_COLORS[0]) if Item.critical_risks_unique.to_a.size != 0
|
103
|
+
print_technical_findings(Item.high_risks_unique, "High Findings", Risu::GRAPH_COLORS[1], true) if Item.high_risks_unique.to_a.size != 0
|
104
|
+
#print_technical_findings(Item.medium_risks_unique, "Medium Findings", Risu::GRAPH_COLORS[2]) if Item.medium_risks_unique.to_a.size != 0
|
105
|
+
#print_technical_findings(Item.low_risks_unique, "Low Findings", Risu::GRAPH_COLORS[3], true) if Item.low_risks_unique.to_a.size != 0
|
148
106
|
|
149
107
|
output.number_pages "<page> of <total>", :at => [output.bounds.right - 75, 0], :width => 150, :page_filter => :all
|
150
108
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: risu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.7.
|
4
|
+
version: 1.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Hammack
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: simplecov
|