cvss-suite 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rspec.yml +3 -3
- data/.github/workflows/rubocop.yml +7 -6
- data/.rubocop.yml +36 -1
- data/CHANGES.md +19 -0
- data/CNAME +1 -0
- data/CODE_OF_CONDUCT.md +3 -2
- data/Gemfile +3 -2
- data/LICENSE.md +2 -1
- data/README.md +10 -8
- data/cvss_suite.gemspec +7 -7
- data/lib/cvss_suite/cvss.rb +15 -5
- data/lib/cvss_suite/cvss2/cvss2.rb +22 -2
- data/lib/cvss_suite/cvss2/cvss2_base.rb +15 -14
- data/lib/cvss_suite/cvss2/cvss2_environmental.rb +21 -20
- data/lib/cvss_suite/cvss2/cvss2_temporal.rb +14 -13
- data/lib/cvss_suite/cvss3/cvss3.rb +4 -3
- data/lib/cvss_suite/cvss3/cvss3_base.rb +17 -16
- data/lib/cvss_suite/cvss3/cvss3_environmental.rb +97 -41
- data/lib/cvss_suite/cvss3/cvss3_temporal.rb +14 -13
- data/lib/cvss_suite/cvss31/cvss31.rb +4 -3
- data/lib/cvss_suite/cvss31/cvss31_base.rb +17 -16
- data/lib/cvss_suite/cvss31/cvss31_environmental.rb +97 -41
- data/lib/cvss_suite/cvss31/cvss31_temporal.rb +14 -13
- data/lib/cvss_suite/cvss_metric.rb +3 -2
- data/lib/cvss_suite/cvss_property.rb +3 -2
- data/lib/cvss_suite/errors.rb +4 -1
- data/lib/cvss_suite/helpers/cvss31_helper.rb +3 -2
- data/lib/cvss_suite/helpers/cvss3_helper.rb +3 -2
- data/lib/cvss_suite/invalid_cvss.rb +5 -2
- data/lib/cvss_suite/version.rb +4 -3
- data/lib/cvss_suite.rb +4 -2
- metadata +10 -10
@@ -1,9 +1,10 @@
|
|
1
1
|
# CVSS-Suite, a Ruby gem to manage the CVSS vector
|
2
2
|
#
|
3
|
-
# Copyright (c) Siemens AG
|
3
|
+
# Copyright (c) 2016-2022 Siemens AG
|
4
|
+
# Copyright (c) 2022 0llirocks
|
4
5
|
#
|
5
6
|
# Authors:
|
6
|
-
#
|
7
|
+
# 0llirocks <http://0lli.rocks>
|
7
8
|
#
|
8
9
|
# This work is licensed under the terms of the MIT license.
|
9
10
|
# See the LICENSE.md file in the top-level directory.
|
@@ -26,8 +27,20 @@ module CvssSuite
|
|
26
27
|
##
|
27
28
|
# Returns score of this metric
|
28
29
|
|
29
|
-
def score(
|
30
|
-
|
30
|
+
def score(base, temporal)
|
31
|
+
@base = base
|
32
|
+
|
33
|
+
merged_modified_privileges_required = @modified_privileges_required
|
34
|
+
if @modified_privileges_required.selected_value[:name] == 'Not Defined'
|
35
|
+
merged_modified_privileges_required = @base.privileges_required
|
36
|
+
end
|
37
|
+
|
38
|
+
merged_modified_scope = @modified_scope
|
39
|
+
if @modified_scope.selected_value[:name] == 'Not Defined'
|
40
|
+
merged_modified_scope = @base.scope
|
41
|
+
end
|
42
|
+
|
43
|
+
privilege_score = Cvss3Helper.privileges_required_score(merged_modified_privileges_required, merged_modified_scope)
|
31
44
|
|
32
45
|
modified_exploitability_sub_score = modified_exploitability_sub(privilege_score)
|
33
46
|
|
@@ -35,7 +48,7 @@ module CvssSuite
|
|
35
48
|
|
36
49
|
return 0 if modified_impact_sub_score <= 0
|
37
50
|
|
38
|
-
calculate_score
|
51
|
+
calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal.score
|
39
52
|
end
|
40
53
|
|
41
54
|
private
|
@@ -44,70 +57,79 @@ module CvssSuite
|
|
44
57
|
@properties.push(@confidentiality_requirement =
|
45
58
|
CvssProperty.new(name: 'Confidentiality Requirement', abbreviation: 'CR', position: [8, 11],
|
46
59
|
values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
|
47
|
-
|
48
|
-
|
49
|
-
|
60
|
+
{ name: 'Medium', abbreviation: 'M', weight: 1.0 },
|
61
|
+
{ name: 'High', abbreviation: 'H', weight: 1.5 },
|
62
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
50
63
|
@properties.push(@integrity_requirement =
|
51
64
|
CvssProperty.new(name: 'Integrity Requirement', abbreviation: 'IR', position: [9, 12],
|
52
65
|
values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
|
53
|
-
|
54
|
-
|
55
|
-
|
66
|
+
{ name: 'Medium', abbreviation: 'M', weight: 1.0 },
|
67
|
+
{ name: 'High', abbreviation: 'H', weight: 1.5 },
|
68
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
56
69
|
|
57
70
|
@properties.push(@availability_requirement =
|
58
71
|
CvssProperty.new(name: 'Availability Requirement', abbreviation: 'AR', position: [10, 13],
|
59
72
|
values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
|
60
|
-
|
61
|
-
|
62
|
-
|
73
|
+
{ name: 'Medium', abbreviation: 'M', weight: 1.0 },
|
74
|
+
{ name: 'High', abbreviation: 'H', weight: 1.5 },
|
75
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
63
76
|
@properties.push(@modified_attack_vector =
|
64
77
|
CvssProperty.new(name: 'Modified Attack Vector', abbreviation: 'MAV', position: [11, 14],
|
65
78
|
values: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
79
|
+
{ name: 'Adjacent Network', abbreviation: 'A', weight: 0.62 },
|
80
|
+
{ name: 'Local', abbreviation: 'L', weight: 0.55 },
|
81
|
+
{ name: 'Physical', abbreviation: 'P', weight: 0.2 },
|
82
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
70
83
|
@properties.push(@modified_attack_complexity =
|
71
84
|
CvssProperty.new(name: 'Modified Attack Complexity', abbreviation: 'MAC', position: [12, 15],
|
72
85
|
values: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
|
73
|
-
|
74
|
-
|
86
|
+
{ name: 'High', abbreviation: 'H', weight: 0.44 },
|
87
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
75
88
|
@properties.push(@modified_privileges_required =
|
76
89
|
CvssProperty.new(name: 'Modified Privileges Required', abbreviation: 'MPR', position: [13, 16],
|
77
90
|
values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
78
|
-
|
79
|
-
|
80
|
-
|
91
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.62 },
|
92
|
+
{ name: 'High', abbreviation: 'H', weight: 0.27 },
|
93
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
81
94
|
@properties.push(@modified_user_interaction =
|
82
95
|
CvssProperty.new(name: 'Modified User Interaction', abbreviation: 'MUI', position: [14, 17],
|
83
96
|
values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
84
|
-
|
85
|
-
|
97
|
+
{ name: 'Required', abbreviation: 'R', weight: 0.62 },
|
98
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
86
99
|
@properties.push(@modified_scope =
|
87
100
|
CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS', position: [15, 18],
|
88
101
|
values: [{ name: 'Changed', abbreviation: 'C' },
|
89
|
-
|
102
|
+
{ name: 'Unchanged', abbreviation: 'U' },
|
103
|
+
{ name: 'Not Defined', abbreviation: 'X' }]))
|
90
104
|
@properties.push(@modified_confidentiality =
|
91
105
|
CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC', position: [16, 19],
|
92
106
|
values: [{ name: 'None', abbreviation: 'N', weight: 0 },
|
93
|
-
|
94
|
-
|
95
|
-
|
107
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
108
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 },
|
109
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
96
110
|
@properties.push(@modified_integrity =
|
97
111
|
CvssProperty.new(name: 'Modified Integrity', abbreviation: 'MI', position: [17, 20],
|
98
112
|
values: [{ name: 'None', abbreviation: 'N', weight: 0 },
|
99
|
-
|
100
|
-
|
101
|
-
|
113
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
114
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 },
|
115
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
102
116
|
@properties.push(@modified_availability =
|
103
117
|
CvssProperty.new(name: 'Modified Availability', abbreviation: 'MA', position: [18, 21],
|
104
118
|
values: [{ name: 'None', abbreviation: 'N', weight: 0 },
|
105
|
-
|
106
|
-
|
107
|
-
|
119
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
120
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 },
|
121
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
108
122
|
end
|
109
123
|
|
110
124
|
def modified_impact_sub(isc_modified)
|
125
|
+
if @modified_scope.selected_value[:name] == 'Not Defined'
|
126
|
+
if @base.scope.selected_value[:name] == 'Changed'
|
127
|
+
return 7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified - 0.02)**15
|
128
|
+
else
|
129
|
+
return 6.42 * isc_modified
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
111
133
|
if @modified_scope.selected_value[:name] == 'Changed'
|
112
134
|
7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified - 0.02)**15
|
113
135
|
else
|
@@ -116,20 +138,54 @@ module CvssSuite
|
|
116
138
|
end
|
117
139
|
|
118
140
|
def isc_modified
|
119
|
-
|
120
|
-
|
121
|
-
|
141
|
+
merged_modified_confidentiality = @modified_confidentiality
|
142
|
+
if @modified_confidentiality.selected_value[:name] == 'Not Defined'
|
143
|
+
merged_modified_confidentiality = @base.confidentiality
|
144
|
+
end
|
145
|
+
|
146
|
+
merged_modified_integrity = @modified_integrity
|
147
|
+
if @modified_integrity.selected_value[:name] == 'Not Defined'
|
148
|
+
merged_modified_integrity = @base.integrity
|
149
|
+
end
|
150
|
+
|
151
|
+
merged_modified_availability = @modified_availability
|
152
|
+
if @modified_availability.selected_value[:name] == 'Not Defined'
|
153
|
+
merged_modified_availability = @base.availability
|
154
|
+
end
|
155
|
+
|
156
|
+
confidentiality_score = 1 - merged_modified_confidentiality.score * @confidentiality_requirement.score
|
157
|
+
integrity_score = 1 - merged_modified_integrity.score * @integrity_requirement.score
|
158
|
+
availability_score = 1 - merged_modified_availability.score * @availability_requirement.score
|
122
159
|
|
123
160
|
[0.915, (1 - confidentiality_score * integrity_score * availability_score)].min
|
124
161
|
end
|
125
162
|
|
126
163
|
def modified_exploitability_sub(privilege_score)
|
127
|
-
|
128
|
-
|
164
|
+
merged_modified_attack_vector = @modified_attack_vector
|
165
|
+
if @modified_attack_vector.selected_value[:name] == 'Not Defined'
|
166
|
+
merged_modified_attack_vector = @base.attack_vector
|
167
|
+
end
|
168
|
+
|
169
|
+
merged_modified_attack_complexity = @modified_attack_complexity
|
170
|
+
if @modified_attack_complexity.selected_value[:name] == 'Not Defined'
|
171
|
+
merged_modified_attack_complexity = @base.attack_complexity
|
172
|
+
end
|
173
|
+
|
174
|
+
merged_modified_user_interaction = @modified_user_interaction
|
175
|
+
if @modified_user_interaction.selected_value[:name] == 'Not Defined'
|
176
|
+
merged_modified_user_interaction = @base.user_interaction
|
177
|
+
end
|
178
|
+
|
179
|
+
8.22 * merged_modified_attack_vector.score * merged_modified_attack_complexity.score *
|
180
|
+
privilege_score * merged_modified_user_interaction.score
|
129
181
|
end
|
130
182
|
|
131
183
|
def calculate_score(modified_impact_sub_score, modified_exploitability_sub_score, temporal_score)
|
132
|
-
|
184
|
+
if @modified_scope.selected_value[:name] == 'Not Defined'
|
185
|
+
factor = @base.scope.selected_value[:name] == 'Changed' ? 1.08 : 1.0
|
186
|
+
else
|
187
|
+
factor = @modified_scope.selected_value[:name] == 'Changed' ? 1.08 : 1.0
|
188
|
+
end
|
133
189
|
|
134
190
|
Cvss3Helper.round_up(
|
135
191
|
[factor * (modified_impact_sub_score + modified_exploitability_sub_score), 10].min
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# CVSS-Suite, a Ruby gem to manage the CVSS vector
|
2
2
|
#
|
3
|
-
# Copyright (c) Siemens AG
|
3
|
+
# Copyright (c) 2016-2022 Siemens AG
|
4
|
+
# Copyright (c) 2022 0llirocks
|
4
5
|
#
|
5
6
|
# Authors:
|
6
|
-
#
|
7
|
+
# 0llirocks <http://0lli.rocks>
|
7
8
|
#
|
8
9
|
# This work is licensed under the terms of the MIT license.
|
9
10
|
# See the LICENSE.md file in the top-level directory.
|
@@ -33,24 +34,24 @@ module CvssSuite
|
|
33
34
|
@properties.push(@exploit_code_maturity =
|
34
35
|
CvssProperty.new(name: 'Exploit Code Maturity', abbreviation: 'E', position: [8],
|
35
36
|
values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
{ name: 'Unproven', abbreviation: 'U', weight: 0.91 },
|
38
|
+
{ name: 'Proof-of-Concept', abbreviation: 'P', weight: 0.94 },
|
39
|
+
{ name: 'Functional', abbreviation: 'F', weight: 0.97 },
|
40
|
+
{ name: 'High', abbreviation: 'H', weight: 1.0 }]))
|
40
41
|
@properties.push(@remediation_level =
|
41
42
|
CvssProperty.new(name: 'Remediation Level', abbreviation: 'RL', position: [9],
|
42
43
|
values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
{ name: 'Official Fix', abbreviation: 'O', weight: 0.95 },
|
45
|
+
{ name: 'Temporary Fix', abbreviation: 'T', weight: 0.96 },
|
46
|
+
{ name: 'Workaround', abbreviation: 'W', weight: 0.97 },
|
47
|
+
{ name: 'Unavailable', abbreviation: 'U', weight: 1.0 }]))
|
47
48
|
|
48
49
|
@properties.push(@report_confidence =
|
49
50
|
CvssProperty.new(name: 'Report Confidence', abbreviation: 'RC', position: [10],
|
50
51
|
values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
|
51
|
-
|
52
|
-
|
53
|
-
|
52
|
+
{ name: 'Unknown', abbreviation: 'U', weight: 0.92 },
|
53
|
+
{ name: 'Reasonable', abbreviation: 'R', weight: 0.96 },
|
54
|
+
{ name: 'Confirmed', abbreviation: 'C', weight: 1.0 }]))
|
54
55
|
end
|
55
56
|
end
|
56
57
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# CVSS-Suite, a Ruby gem to manage the CVSS vector
|
2
2
|
#
|
3
|
-
# Copyright (c) Siemens AG
|
3
|
+
# Copyright (c) 2019-2022 Siemens AG
|
4
|
+
# Copyright (c) 2022 0llirocks
|
4
5
|
#
|
5
6
|
# Authors:
|
6
|
-
#
|
7
|
+
# 0llirocks <http://0lli.rocks>
|
7
8
|
#
|
8
9
|
# This work is licensed under the terms of the MIT license.
|
9
10
|
# See the LICENSE.md file in the top-level directory.
|
@@ -46,7 +47,7 @@ module CvssSuite
|
|
46
47
|
def environmental_score
|
47
48
|
return temporal_score unless @environmental.valid?
|
48
49
|
|
49
|
-
Cvss31Helper.round_up(@environmental.score(@temporal
|
50
|
+
Cvss31Helper.round_up(@environmental.score(@base, @temporal))
|
50
51
|
end
|
51
52
|
|
52
53
|
private
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# CVSS-Suite, a Ruby gem to manage the CVSS vector
|
2
2
|
#
|
3
|
-
# Copyright (c) Siemens AG
|
3
|
+
# Copyright (c) 2019-2022 Siemens AG
|
4
|
+
# Copyright (c) 2022 0llirocks
|
4
5
|
#
|
5
6
|
# Authors:
|
6
|
-
#
|
7
|
+
# 0llirocks <http://0lli.rocks>
|
7
8
|
#
|
8
9
|
# This work is licensed under the terms of the MIT license.
|
9
10
|
# See the LICENSE.md file in the top-level directory.
|
@@ -53,41 +54,41 @@ module CvssSuite
|
|
53
54
|
@properties.push(@attack_vector =
|
54
55
|
CvssProperty.new(name: 'Attack Vector', abbreviation: 'AV', position: [0],
|
55
56
|
values: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
{ name: 'Adjacent', abbreviation: 'A', weight: 0.62 },
|
58
|
+
{ name: 'Local', abbreviation: 'L', weight: 0.55 },
|
59
|
+
{ name: 'Physical', abbreviation: 'P', weight: 0.2 }]))
|
59
60
|
@properties.push(@attack_complexity =
|
60
61
|
CvssProperty.new(name: 'Attack Complexity', abbreviation: 'AC', position: [1],
|
61
62
|
values: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
|
62
|
-
|
63
|
+
{ name: 'High', abbreviation: 'H', weight: 0.44 }]))
|
63
64
|
@properties.push(@privileges_required =
|
64
65
|
CvssProperty.new(name: 'Privileges Required', abbreviation: 'PR', position: [2],
|
65
66
|
values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
66
|
-
|
67
|
-
|
67
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.62 },
|
68
|
+
{ name: 'High', abbreviation: 'H', weight: 0.27 }]))
|
68
69
|
@properties.push(@user_interaction =
|
69
70
|
CvssProperty.new(name: 'User Interaction', abbreviation: 'UI', position: [3],
|
70
71
|
values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
71
|
-
|
72
|
+
{ name: 'Required', abbreviation: 'R', weight: 0.62 }]))
|
72
73
|
@properties.push(@scope =
|
73
74
|
CvssProperty.new(name: 'Scope', abbreviation: 'S', position: [4],
|
74
75
|
values: [{ name: 'Unchanged', abbreviation: 'U' },
|
75
|
-
|
76
|
+
{ name: 'Changed', abbreviation: 'C' }]))
|
76
77
|
@properties.push(@confidentiality =
|
77
78
|
CvssProperty.new(name: 'Confidentiality', abbreviation: 'C', position: [5],
|
78
79
|
values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
|
79
|
-
|
80
|
-
|
80
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
81
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 }]))
|
81
82
|
@properties.push(@integrity =
|
82
83
|
CvssProperty.new(name: 'Integrity', abbreviation: 'I', position: [6],
|
83
84
|
values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
|
84
|
-
|
85
|
-
|
85
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
86
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 }]))
|
86
87
|
@properties.push(@availability =
|
87
88
|
CvssProperty.new(name: 'Availability', abbreviation: 'A', position: [7],
|
88
89
|
values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
|
89
|
-
|
90
|
-
|
90
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
91
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 }]))
|
91
92
|
end
|
92
93
|
end
|
93
94
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# CVSS-Suite, a Ruby gem to manage the CVSS vector
|
2
2
|
#
|
3
|
-
# Copyright (c) Siemens AG
|
3
|
+
# Copyright (c) 2019-2022 Siemens AG
|
4
|
+
# Copyright (c) 2022 0llirocks
|
4
5
|
#
|
5
6
|
# Authors:
|
6
|
-
#
|
7
|
+
# 0llirocks <http://0lli.rocks>
|
7
8
|
#
|
8
9
|
# This work is licensed under the terms of the MIT license.
|
9
10
|
# See the LICENSE.md file in the top-level directory.
|
@@ -26,8 +27,20 @@ module CvssSuite
|
|
26
27
|
|
27
28
|
##
|
28
29
|
# Returns score of this metric
|
29
|
-
def score(
|
30
|
-
|
30
|
+
def score(base, temporal)
|
31
|
+
@base = base
|
32
|
+
|
33
|
+
merged_modified_privileges_required = @modified_privileges_required
|
34
|
+
if @modified_privileges_required.selected_value[:name] == 'Not Defined'
|
35
|
+
merged_modified_privileges_required = @base.privileges_required
|
36
|
+
end
|
37
|
+
|
38
|
+
merged_modified_scope = @modified_scope
|
39
|
+
if @modified_scope.selected_value[:name] == 'Not Defined'
|
40
|
+
merged_modified_scope = @base.scope
|
41
|
+
end
|
42
|
+
|
43
|
+
privilege_score = Cvss3Helper.privileges_required_score(merged_modified_privileges_required, merged_modified_scope)
|
31
44
|
|
32
45
|
modified_exploitability_sub_score = modified_exploitability_sub(privilege_score)
|
33
46
|
|
@@ -35,7 +48,7 @@ module CvssSuite
|
|
35
48
|
|
36
49
|
return 0 if modified_impact_sub_score <= 0
|
37
50
|
|
38
|
-
calculate_score modified_impact_sub_score, modified_exploitability_sub_score,
|
51
|
+
calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal.score
|
39
52
|
end
|
40
53
|
|
41
54
|
private
|
@@ -44,70 +57,79 @@ module CvssSuite
|
|
44
57
|
@properties.push(@confidentiality_requirement =
|
45
58
|
CvssProperty.new(name: 'Confidentiality Requirement', abbreviation: 'CR', position: [8, 11],
|
46
59
|
values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
|
47
|
-
|
48
|
-
|
49
|
-
|
60
|
+
{ name: 'Medium', abbreviation: 'M', weight: 1.0 },
|
61
|
+
{ name: 'High', abbreviation: 'H', weight: 1.5 },
|
62
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
50
63
|
@properties.push(@integrity_requirement =
|
51
64
|
CvssProperty.new(name: 'Integrity Requirement', abbreviation: 'IR', position: [9, 12],
|
52
65
|
values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
|
53
|
-
|
54
|
-
|
55
|
-
|
66
|
+
{ name: 'Medium', abbreviation: 'M', weight: 1.0 },
|
67
|
+
{ name: 'High', abbreviation: 'H', weight: 1.5 },
|
68
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
56
69
|
|
57
70
|
@properties.push(@availability_requirement =
|
58
71
|
CvssProperty.new(name: 'Availability Requirement', abbreviation: 'AR', position: [10, 13],
|
59
72
|
values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
|
60
|
-
|
61
|
-
|
62
|
-
|
73
|
+
{ name: 'Medium', abbreviation: 'M', weight: 1.0 },
|
74
|
+
{ name: 'High', abbreviation: 'H', weight: 1.5 },
|
75
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
63
76
|
@properties.push(@modified_attack_vector =
|
64
77
|
CvssProperty.new(name: 'Modified Attack Vector', abbreviation: 'MAV', position: [11, 14],
|
65
78
|
values: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
79
|
+
{ name: 'Adjacent Network', abbreviation: 'A', weight: 0.62 },
|
80
|
+
{ name: 'Local', abbreviation: 'L', weight: 0.55 },
|
81
|
+
{ name: 'Physical', abbreviation: 'P', weight: 0.2 },
|
82
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
70
83
|
@properties.push(@modified_attack_complexity =
|
71
84
|
CvssProperty.new(name: 'Modified Attack Complexity', abbreviation: 'MAC', position: [12, 15],
|
72
85
|
values: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
|
73
|
-
|
74
|
-
|
86
|
+
{ name: 'High', abbreviation: 'H', weight: 0.44 },
|
87
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
75
88
|
@properties.push(@modified_privileges_required =
|
76
89
|
CvssProperty.new(name: 'Modified Privileges Required', abbreviation: 'MPR', position: [13, 16],
|
77
90
|
values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
78
|
-
|
79
|
-
|
80
|
-
|
91
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.62 },
|
92
|
+
{ name: 'High', abbreviation: 'H', weight: 0.27 },
|
93
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
81
94
|
@properties.push(@modified_user_interaction =
|
82
95
|
CvssProperty.new(name: 'Modified User Interaction', abbreviation: 'MUI', position: [14, 17],
|
83
96
|
values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
|
84
|
-
|
85
|
-
|
97
|
+
{ name: 'Required', abbreviation: 'R', weight: 0.62 },
|
98
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
86
99
|
@properties.push(@modified_scope =
|
87
100
|
CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS', position: [15, 18],
|
88
101
|
values: [{ name: 'Changed', abbreviation: 'C' },
|
89
|
-
|
102
|
+
{ name: 'Unchanged', abbreviation: 'U' },
|
103
|
+
{ name: 'Not Defined', abbreviation: 'X' }]))
|
90
104
|
@properties.push(@modified_confidentiality =
|
91
105
|
CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC', position: [16, 19],
|
92
106
|
values: [{ name: 'None', abbreviation: 'N', weight: 0 },
|
93
|
-
|
94
|
-
|
95
|
-
|
107
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
108
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 },
|
109
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
96
110
|
@properties.push(@modified_integrity =
|
97
111
|
CvssProperty.new(name: 'Modified Integrity', abbreviation: 'MI', position: [17, 20],
|
98
112
|
values: [{ name: 'None', abbreviation: 'N', weight: 0 },
|
99
|
-
|
100
|
-
|
101
|
-
|
113
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
114
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 },
|
115
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
102
116
|
@properties.push(@modified_availability =
|
103
117
|
CvssProperty.new(name: 'Modified Availability', abbreviation: 'MA', position: [18, 21],
|
104
118
|
values: [{ name: 'None', abbreviation: 'N', weight: 0 },
|
105
|
-
|
106
|
-
|
107
|
-
|
119
|
+
{ name: 'Low', abbreviation: 'L', weight: 0.22 },
|
120
|
+
{ name: 'High', abbreviation: 'H', weight: 0.56 },
|
121
|
+
{ name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
|
108
122
|
end
|
109
123
|
|
110
124
|
def modified_impact_sub(isc_modified)
|
125
|
+
if @modified_scope.selected_value[:name] == 'Not Defined'
|
126
|
+
if @base.scope.selected_value[:name] == 'Changed'
|
127
|
+
return 7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified * 0.9731 - 0.02)**13
|
128
|
+
else
|
129
|
+
return 6.42 * isc_modified
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
111
133
|
if @modified_scope.selected_value[:name] == 'Changed'
|
112
134
|
7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified * 0.9731 - 0.02)**13
|
113
135
|
else
|
@@ -116,20 +138,54 @@ module CvssSuite
|
|
116
138
|
end
|
117
139
|
|
118
140
|
def isc_modified
|
119
|
-
|
120
|
-
|
121
|
-
|
141
|
+
merged_modified_confidentiality = @modified_confidentiality
|
142
|
+
if @modified_confidentiality.selected_value[:name] == 'Not Defined'
|
143
|
+
merged_modified_confidentiality = @base.confidentiality
|
144
|
+
end
|
145
|
+
|
146
|
+
merged_modified_integrity = @modified_integrity
|
147
|
+
if @modified_integrity.selected_value[:name] == 'Not Defined'
|
148
|
+
merged_modified_integrity = @base.integrity
|
149
|
+
end
|
150
|
+
|
151
|
+
merged_modified_availability = @modified_availability
|
152
|
+
if @modified_availability.selected_value[:name] == 'Not Defined'
|
153
|
+
merged_modified_availability = @base.availability
|
154
|
+
end
|
155
|
+
|
156
|
+
confidentiality_score = 1 - merged_modified_confidentiality.score * @confidentiality_requirement.score
|
157
|
+
integrity_score = 1 - merged_modified_integrity.score * @integrity_requirement.score
|
158
|
+
availability_score = 1 - merged_modified_availability.score * @availability_requirement.score
|
122
159
|
|
123
160
|
[0.915, (1 - confidentiality_score * integrity_score * availability_score)].min
|
124
161
|
end
|
125
162
|
|
126
163
|
def modified_exploitability_sub(privilege_score)
|
127
|
-
|
128
|
-
|
164
|
+
merged_modified_attack_vector = @modified_attack_vector
|
165
|
+
if @modified_attack_vector.selected_value[:name] == 'Not Defined'
|
166
|
+
merged_modified_attack_vector = @base.attack_vector
|
167
|
+
end
|
168
|
+
|
169
|
+
merged_modified_attack_complexity = @modified_attack_complexity
|
170
|
+
if @modified_attack_complexity.selected_value[:name] == 'Not Defined'
|
171
|
+
merged_modified_attack_complexity = @base.attack_complexity
|
172
|
+
end
|
173
|
+
|
174
|
+
merged_modified_user_interaction = @modified_user_interaction
|
175
|
+
if @modified_user_interaction.selected_value[:name] == 'Not Defined'
|
176
|
+
merged_modified_user_interaction = @base.user_interaction
|
177
|
+
end
|
178
|
+
|
179
|
+
8.22 * merged_modified_attack_vector.score * merged_modified_attack_complexity.score *
|
180
|
+
privilege_score * merged_modified_user_interaction.score
|
129
181
|
end
|
130
182
|
|
131
183
|
def calculate_score(modified_impact_sub_score, modified_exploitability_sub_score, temporal_score)
|
132
|
-
|
184
|
+
if @modified_scope.selected_value[:name] == 'Not Defined'
|
185
|
+
factor = @base.scope.selected_value[:name] == 'Changed' ? 1.08 : 1.0
|
186
|
+
else
|
187
|
+
factor = @modified_scope.selected_value[:name] == 'Changed' ? 1.08 : 1.0
|
188
|
+
end
|
133
189
|
|
134
190
|
Cvss31Helper.round_up(
|
135
191
|
[factor * (modified_impact_sub_score + modified_exploitability_sub_score), 10].min
|