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