risu 1.5.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|