risu 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/KNOWNISSUES.markdown +50 -0
  2. data/LICENSE +25 -0
  3. data/NEWS.markdown +112 -0
  4. data/README.markdown +126 -0
  5. data/Rakefile +37 -0
  6. data/TODO.markdown +69 -0
  7. data/bin/risu +12 -0
  8. data/lib/nessusdb.rb +38 -0
  9. data/lib/nessusdb/cli.rb +9 -0
  10. data/lib/nessusdb/cli/application.rb +402 -0
  11. data/lib/nessusdb/cli/banner.rb +25 -0
  12. data/lib/nessusdb/exceptions.rb +8 -0
  13. data/lib/nessusdb/exceptions/invaliddocument.rb +10 -0
  14. data/lib/nessusdb/listener.rb +274 -0
  15. data/lib/nessusdb/models.rb +18 -0
  16. data/lib/nessusdb/models/familyselection.rb +12 -0
  17. data/lib/nessusdb/models/host.rb +359 -0
  18. data/lib/nessusdb/models/individualpluginselection.rb +14 -0
  19. data/lib/nessusdb/models/item.rb +183 -0
  20. data/lib/nessusdb/models/plugin.rb +98 -0
  21. data/lib/nessusdb/models/pluginspreference.rb +12 -0
  22. data/lib/nessusdb/models/policy.rb +17 -0
  23. data/lib/nessusdb/models/reference.rb +13 -0
  24. data/lib/nessusdb/models/report.rb +26 -0
  25. data/lib/nessusdb/models/serverpreference.rb +13 -0
  26. data/lib/nessusdb/models/version.rb +12 -0
  27. data/lib/nessusdb/nessusdocument.rb +66 -0
  28. data/lib/nessusdb/parsers.rb +8 -0
  29. data/lib/nessusdb/prawn_templater.rb +38 -0
  30. data/lib/nessusdb/schema.rb +145 -0
  31. data/lib/nessusdb/templates/assets.rb +21 -0
  32. data/lib/nessusdb/templates/cover_sheet.rb +42 -0
  33. data/lib/nessusdb/templates/data/nessuslogo.jpg +0 -0
  34. data/lib/nessusdb/templates/exec_summary.rb +56 -0
  35. data/lib/nessusdb/templates/executive_summary.rb +182 -0
  36. data/lib/nessusdb/templates/finding_statistics.rb +23 -0
  37. data/lib/nessusdb/templates/findings_host.rb +49 -0
  38. data/lib/nessusdb/templates/findings_summary.rb +68 -0
  39. data/lib/nessusdb/templates/findings_summary_with_pluginid.rb +68 -0
  40. data/lib/nessusdb/templates/graphs.rb +33 -0
  41. data/lib/nessusdb/templates/host_summary.rb +40 -0
  42. data/lib/nessusdb/templates/ms_patch_summary.rb +37 -0
  43. data/lib/nessusdb/templates/ms_update_summary.rb +43 -0
  44. data/lib/nessusdb/templates/pci_compliance.rb +66 -0
  45. data/lib/nessusdb/templates/technical_findings.rb +116 -0
  46. data/risu.gemspec +44 -0
  47. metadata +247 -0
@@ -0,0 +1,23 @@
1
+ text Report.classification, :align => :center
2
+ text "\n"
3
+
4
+ font_size(22) { text Report.title, :align => :center }
5
+ font_size(18) {
6
+ text "Finding Statistics", :align => :center
7
+ text "\n"
8
+ text "This report was prepared by\n#{Report.author}", :align => :center
9
+ }
10
+
11
+ text "\n\n\n"
12
+
13
+ text "Scan Date:", :style => :bold
14
+ text "#{Report.scan_date}"
15
+ text "\n"
16
+
17
+ headers = ["Number of hosts","Number of risks","High Risks", "Medium Risks", "Low Risks", "Info Risks"]
18
+ data = [Host.count, Item.risks.count, Item.high_risks.count, Item.medium_risks.count, Item.low_risks.count, Item.info_risks.count]
19
+
20
+ table([headers] + [data], :header => true, :width => bounds.width) do
21
+ row(0).style(:font_style => :bold, :background_color => 'cccccc')
22
+ cells.borders = [:top, :bottom, :left, :right]
23
+ end
@@ -0,0 +1,49 @@
1
+ text Report.classification, :align => :center
2
+ text "\n"
3
+
4
+ font_size(22) { text Report.title, :align => :center }
5
+ font_size(18) {
6
+ text "Findings Summary Report", :align => :center
7
+ text "\n"
8
+ text "This report was prepared by\n#{Report.author}", :align => :center
9
+ }
10
+
11
+ text "\n\n\n"
12
+
13
+ Host.sorted.each do |host|
14
+ if host.items.high_risks_unique_sorted.all.size > 0 or host.items.medium_risks_unique_sorted.all.size > 0
15
+ font_size(20) {
16
+ text "#{host.ip} - #{host.fqdn}", :style => :bold
17
+ }
18
+ end
19
+
20
+ if host.items.high_risks_unique_sorted.all.size > 0
21
+ font_size(18) {
22
+ fill_color "FF0000"
23
+ text "High Findings", :style => :bold
24
+ fill_color "000000"
25
+ }
26
+
27
+ host.items.high_risks_unique_sorted.each do |item|
28
+ name = Plugin.find_by_id(item.plugin_id).plugin_name
29
+ text "#{name}"
30
+ end
31
+ end
32
+
33
+ if host.items.medium_risks_unique_sorted.all.size > 0
34
+ font_size(18) {
35
+ fill_color "FF8040"
36
+ text "Medium Findings", :style => :bold
37
+ fill_color "000000"
38
+ }
39
+
40
+ host.items.medium_risks_unique_sorted.each do |item|
41
+ name = Plugin.find_by_id(item.plugin_id).plugin_name
42
+ text "#{name}"
43
+ end
44
+ end
45
+
46
+ if host.items.high_risks_unique_sorted.all.size > 0 or host.items.medium_risks_unique_sorted.all.size > 0
47
+ text "\n"
48
+ end
49
+ end
@@ -0,0 +1,68 @@
1
+ text Report.classification, :align => :center
2
+ text "\n"
3
+
4
+ font_size(22) { text Report.title, :align => :center }
5
+ font_size(18) {
6
+ text "Findings Summary Report", :align => :center
7
+ text "\n"
8
+ text "This report was prepared by\n#{Report.author}", :align => :center
9
+ }
10
+
11
+ text "\n\n\n"
12
+
13
+ font_size(20) {
14
+ fill_color "FF0000"
15
+ text "High Findings", :style => :bold
16
+ fill_color "000000"
17
+ }
18
+
19
+ Item.high_risks_unique_sorted.each do |item|
20
+ name = Plugin.find_by_id(item.plugin_id).plugin_name
21
+ count = Item.where(:plugin_id => item.plugin_id).count
22
+
23
+ text "#{count} - #{name}"
24
+ end
25
+
26
+ start_new_page
27
+
28
+ font_size(20) {
29
+ fill_color "FF8040"
30
+ text "Medium Findings", :style => :bold
31
+ fill_color "000000"
32
+ }
33
+
34
+ Item.medium_risks_unique_sorted.each do |item|
35
+ name = Plugin.find_by_id(item.plugin_id).plugin_name
36
+ count = Item.where(:plugin_id => item.plugin_id).count
37
+
38
+ text "#{count} - #{name}"
39
+ end
40
+
41
+ start_new_page
42
+
43
+ font_size(20) {
44
+ fill_color "0000FF"
45
+ text "Low Findings", :style => :bold
46
+ fill_color "000000"
47
+ }
48
+
49
+ Item.low_risks_unique_sorted.each do |item|
50
+ name = Plugin.find_by_id(item.plugin_id).plugin_name
51
+ count = Item.where(:plugin_id => item.plugin_id).count
52
+
53
+ text "#{count} - #{name}"
54
+ end
55
+
56
+ #Provides nothing
57
+ #font_size(20) {
58
+ # fill_color "008000"
59
+ # text "Low Findings", :style => :bold
60
+ # fill_color "000000"
61
+ #}
62
+ #
63
+ #Item.low_risks_unique_sorted.each do |item|
64
+ # name = Plugin.find_by_id(item.plugin_id).plugin_name
65
+ # count = Item.where(:plugin_id => item.plugin_id).count
66
+ #
67
+ # text "#{count} - #{name}"
68
+ #end
@@ -0,0 +1,68 @@
1
+ text Report.classification, :align => :center
2
+ text "\n"
3
+
4
+ font_size(22) { text Report.title, :align => :center }
5
+ font_size(18) {
6
+ text "Findings Summary Report", :align => :center
7
+ text "\n"
8
+ text "This report was prepared by\n#{Report.author}", :align => :center
9
+ }
10
+
11
+ text "\n\n\n"
12
+
13
+ font_size(20) {
14
+ fill_color "FF0000"
15
+ text "High Findings", :style => :bold
16
+ fill_color "000000"
17
+ }
18
+
19
+ Item.high_risks_unique_sorted.each do |item|
20
+ name = Plugin.find_by_id(item.plugin_id).plugin_name
21
+ count = Item.where(:plugin_id => item.plugin_id).count
22
+
23
+ text "#{count} - #{name} - #{item.plugin_id}"
24
+ end
25
+
26
+ start_new_page
27
+
28
+ font_size(20) {
29
+ fill_color "FF8040"
30
+ text "Medium Findings", :style => :bold
31
+ fill_color "000000"
32
+ }
33
+
34
+ Item.medium_risks_unique_sorted.each do |item|
35
+ name = Plugin.find_by_id(item.plugin_id).plugin_name
36
+ count = Item.where(:plugin_id => item.plugin_id).count
37
+
38
+ text "#{count} - #{name} - #{item.plugin_id}"
39
+ end
40
+
41
+ start_new_page
42
+
43
+ font_size(20) {
44
+ fill_color "0000FF"
45
+ text "Low Findings", :style => :bold
46
+ fill_color "000000"
47
+ }
48
+
49
+ Item.low_risks_unique_sorted.each do |item|
50
+ name = Plugin.find_by_id(item.plugin_id).plugin_name
51
+ count = Item.where(:plugin_id => item.plugin_id).count
52
+
53
+ text "#{count} - #{name} - #{item.plugin_id}"
54
+ end
55
+
56
+ #Provides nothing
57
+ #font_size(20) {
58
+ # fill_color "008000"
59
+ # text "Low Findings", :style => :bold
60
+ # fill_color "000000"
61
+ #}
62
+ #
63
+ #Item.low_risks_unique_sorted.each do |item|
64
+ # name = Plugin.find_by_id(item.plugin_id).plugin_name
65
+ # count = Item.where(:plugin_id => item.plugin_id).count
66
+ #
67
+ # text "#{count} - #{name}"
68
+ #end
@@ -0,0 +1,33 @@
1
+ text Report.classification, :align => :center
2
+ text "\n"
3
+
4
+ font_size(24) { text Report.title, :align => :center }
5
+ font_size(18) {
6
+ text "This report was prepared by\n#{Report.author}", :align => :center
7
+ }
8
+
9
+ text "\n\n\n"
10
+
11
+ start_new_page
12
+
13
+ image Item.risks_by_severity_graph, :width => 500, :height => 375, :position => :center
14
+
15
+ start_new_page
16
+
17
+ image Item.risks_by_service_graph(10), :width => 500, :height => 375, :position => :center
18
+
19
+ start_new_page
20
+
21
+ image Plugin.top_by_count_graph(10), :width => 500, :height => 375, :position => :center
22
+
23
+ start_new_page
24
+
25
+ image Host.top_vuln_graph(10), :width => 500, :height => 375, :position => :center
26
+
27
+ start_new_page
28
+
29
+ image Host.other_os_graph, :width => 500, :height => 375, :position => :center
30
+
31
+ start_new_page
32
+
33
+ image Host.windows_os_graph, :width => 500, :height => 375, :position => :center
@@ -0,0 +1,40 @@
1
+ text Report.classification, :align => :center
2
+ text "\n"
3
+
4
+ font_size(22) { text Report.title, :align => :center }
5
+ font_size(18) {
6
+ text "Host Summary Report", :align => :center
7
+ text "\n"
8
+ text "This report was prepared by\n#{Report.author}", :align => :center
9
+ }
10
+
11
+ text "\n\n\n"
12
+
13
+ results = Array.new
14
+
15
+ headers = ["Hostname", "Total", "High", "Medium", "Low", "Info"]
16
+ header_widths = {0 => 137, 1 => 75, 2 => 75, 3 => 75, 4 => 75, 5 => 75}
17
+
18
+ Host.sorted.each do |host|
19
+ row = Array.new
20
+
21
+ total = Item.risks.where(:host_id => host.id).count
22
+ high = Item.high_risks.where(:host_id => host.id).count
23
+ medium = Item.medium_risks.where(:host_id => host.id).count
24
+ low = Item.low_risks.where(:host_id => host.id).count
25
+ info = Item.info_risks.where(:host_id => host.id).count
26
+
27
+ row.push(host.name)
28
+ row.push(total)
29
+ row.push(high)
30
+ row.push(medium)
31
+ row.push(low)
32
+ row.push(info)
33
+
34
+ results.push(row)
35
+ end
36
+
37
+ table([headers] + results, :header => true, :column_widths => header_widths, :row_colors => ['ffffff', 'E5E5E5']) do
38
+ row(0).style(:font_style => :bold, :background_color => 'D0D0D0')
39
+ cells.borders = [:top, :bottom, :left, :right]
40
+ end
@@ -0,0 +1,37 @@
1
+ text Report.classification, :align => :center
2
+ text "\n"
3
+
4
+ font_size(22) { text Report.title, :align => :center }
5
+ font_size(18) {
6
+ text "Missing Microsoft Patch Summary", :align => :center
7
+ text "\n"
8
+ text "This report was prepared by\n#{Report.author}", :align => :center
9
+ }
10
+
11
+ text "\n\n\n"
12
+
13
+ Item.ms_patches.each do |item|
14
+ host = Host.find_by_id(item.host_id)
15
+
16
+ if host == nil
17
+ next
18
+ end
19
+
20
+ if host.name != nil
21
+ text "Host:", :style => :bold
22
+ text host.name
23
+ end
24
+
25
+ if host.os != nil
26
+ text "OS:", :style => :bold
27
+ text host.os
28
+ end
29
+
30
+ if host.mac != nil
31
+ text "Mac:", :style => :bold
32
+ text host.mac
33
+ end
34
+ text "\n"
35
+ text item.plugin_output
36
+ text "\n"
37
+ end
@@ -0,0 +1,43 @@
1
+ text Report.classification, :align => :center
2
+ text "\n"
3
+
4
+ font_size(22) { text Report.title, :align => :center }
5
+ font_size(18) {
6
+ text "Microsoft Update Summary", :align => :center
7
+ text "\n"
8
+ text "This report was prepared by\n#{Report.author}", :align => :center
9
+ }
10
+
11
+ text "\n\n\n"
12
+
13
+ font_size(12)
14
+
15
+ results = Array.new
16
+
17
+ headers = ["Hostname","Operating System", "Windows Update Status"]
18
+ header_widths = {0 => 108, 1 => 264, 2 => 140}
19
+
20
+ Item.ms_update.each do |item|
21
+ host = Host.find_by_id(item.host_id)
22
+
23
+ if host == nil
24
+ next
25
+ end
26
+
27
+ row = Array.new
28
+ row.push(host.name)
29
+ row.push(host.os)
30
+
31
+ if item.plugin_output =~ /'Automatic Updates' are disabled/
32
+ row.push("Disabled")
33
+ else
34
+ row.push("Enabled")
35
+ end
36
+
37
+ results.push(row)
38
+ end
39
+
40
+ table([headers] + results, :header => true, :column_widths => header_widths, :row_colors => ['ffffff', '336699']) do
41
+ row(0).style(:font_style => :bold, :background_color => 'cccccc')
42
+ cells.borders = [:top, :bottom, :left, :right]
43
+ end
@@ -0,0 +1,66 @@
1
+ text Report.classification, :align => :center
2
+ text "\n"
3
+
4
+ font_size(22) { text Report.title, :align => :center }
5
+ font_size(18) {
6
+ text "PCI /DSS Complience Overview", :align => :center
7
+ text "\n"
8
+ text "This report was prepared by\n#{Report.author}", :align => :center
9
+ }
10
+
11
+ text "\n\n\n"
12
+
13
+ @hosts_count = Host.find(:all, :conditions => ["pci_dss_compliance is not null"]).count
14
+ @hosts_passed = Host.find(:all, :conditions => ["pci_dss_compliance like 'passed'"])
15
+ @hosts_failed = Host.find(:all, :conditions => ["pci_dss_compliance like 'failed'"])
16
+
17
+ font_size(20) {
18
+ text "Summary\n", :style => :bold
19
+ }
20
+
21
+ text "Of #{@hosts_count} total hosts, #{@hosts_passed.count} passed and #{@hosts_failed.count} failed."
22
+
23
+ text "\n\n"
24
+
25
+ if @hosts_passed.length > 0
26
+ font_size(20) {
27
+ fill_color "00FF00"
28
+ text "PCI / DSS Compliant Hosts", :style => :bold
29
+ fill_color "000000"
30
+ }
31
+
32
+ text "\n"
33
+
34
+ @hosts_passed.each do |host|
35
+ text "#{host.ip} / #{host.fqdn} - passed\n"
36
+ end unless @hosts_passed == nil
37
+
38
+ start_new_page
39
+ end
40
+
41
+ if @hosts_failed.length > 0
42
+ font_size(20) {
43
+ fill_color "FF0000"
44
+ text "Non PCI / DSS Compliant Hosts", :style => :bold
45
+ fill_color "000000"
46
+ }
47
+
48
+ text "\n"
49
+
50
+ @hosts_failed.each do |host|
51
+ host_id = host.id
52
+ plugin = Plugin.find(:first, :conditions => { :id => 33929 })
53
+ item = Item.find(:first, :conditions => { :host_id => host_id, :plugin_id => plugin.id })
54
+
55
+ text "#{host.ip} / #{host.fqdn} - failed\n", :style => :bold
56
+ text "Description:\n", :style => :bold
57
+ text "#{plugin.description}\n"
58
+ text "Plugin Output:\n", :style => :bold
59
+ text "#{item.plugin_output}\n"
60
+
61
+ text "\n"
62
+
63
+ end unless @hosts_failed == nil
64
+
65
+ start_new_page
66
+ end
@@ -0,0 +1,116 @@
1
+ text Report.classification, :align => :center
2
+ text "\n"
3
+
4
+ font_size(22) { text Report.title, :align => :center }
5
+ font_size(18) {
6
+ text "High and Medium Findings", :align => :center
7
+ text "\n"
8
+ text "This report was prepared by\n#{Report.author}", :align => :center
9
+ }
10
+
11
+ text "\n\n\n"
12
+
13
+ #@todo Revamping blacklisting in 1.3
14
+ #blacklist_ip = "-"
15
+ #blacklist_host_id = Host.where(:ip => blacklist_ip)
16
+ #.where("host_id != (?)", blacklist_host_id)
17
+
18
+ unique_risks = Array.new
19
+ unique_risks << Hash[:title => "High Findings", :color => "FF0000", :values => Item.high_risks_unique]
20
+ unique_risks << Hash[:title => "Medium Findings", :color => "FF8040", :values => Item.medium_risks_unique]
21
+
22
+ unique_risks.each do |h|
23
+ if h[:values].length > 1
24
+ font_size(20) {
25
+ fill_color h[:color]
26
+ text h[:title], :style => :bold
27
+ fill_color "000000"
28
+ }
29
+
30
+ text "\n"
31
+
32
+ h[:values].each do |f|
33
+
34
+ hosts = Item.where(:plugin_id => f.plugin_id)
35
+ plugin = Plugin.find_by_id(f.plugin_id)
36
+
37
+ #Check if vuln is just on the blacklisted
38
+ #if hosts.count == 1
39
+ # if hosts.first.host_id == blacklist_host_id.first.id
40
+ # next
41
+ # end
42
+ #end
43
+
44
+
45
+ references = Reference.where(:plugin_id => plugin.id).group(:value).order(:reference_name)
46
+
47
+ font_size(16) { text "#{plugin.plugin_name}\n" }
48
+
49
+ if hosts.length > 1
50
+ text "Hosts", :style => :bold
51
+ else
52
+ text "Host", :style => :bold
53
+ end
54
+
55
+ hostlist = Array.new
56
+ hosts.each do |host|
57
+ h = Host.find_by_id(host.host_id)
58
+ #if h.id != blacklist_host_id.first.id
59
+ hostlist << h.name
60
+ #end
61
+ end
62
+
63
+ text hostlist.join(', ')
64
+
65
+ if f.plugin_output != nil
66
+ text "\nPlugin output", :style => :bold
67
+ text f.plugin_output
68
+ end
69
+
70
+ if plugin.description != nil
71
+ text "\nDescription", :style => :bold
72
+ text plugin.description
73
+ end
74
+
75
+ if plugin.synopsis != nil
76
+ text "\nSynopsis", :style => :bold
77
+ text plugin.synopsis
78
+ end
79
+
80
+ if plugin.cvss_base_score != nil
81
+ text "\nCVSS Base Score", :style => :bold
82
+ text plugin.cvss_base_score
83
+ end
84
+
85
+ if plugin.exploit_available != nil
86
+ text "\nExploit Available", :style => :bold
87
+
88
+ if plugin.exploit_available == "true"
89
+ text "Yes"
90
+ else
91
+ text "No"
92
+ end
93
+ end
94
+
95
+ if plugin.solution != nil
96
+ text "\nSolution", :style => :bold
97
+ text plugin.solution
98
+ end
99
+
100
+ if references.size != 0
101
+ text "\nReferences", :style => :bold
102
+ references.each { |ref|
103
+ ref_text = sprintf "%s: %s\n", ref.reference_name, ref.value
104
+ text ref_text
105
+ }
106
+ text "\nNessus Plugin", :style => :bold
107
+ text "http://www.tenablesecurity.com/plugins/index.php?view=single&id=#{f.plugin_id}"
108
+ end
109
+ text "\n"
110
+ end
111
+ end
112
+
113
+ start_new_page unless h[:values] == nil
114
+ end
115
+
116
+ number_pages "<page> of <total>", :at => [bounds.right - 75, 0], :width => 150, :page_filter => :all