cvss_rating 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 86710948607aed7404a2f0fe021a0cb734cf1a6b
4
+ data.tar.gz: 8a98d94e813c4a0be0afe2b22b5f6fd66f5d5b63
5
+ SHA512:
6
+ metadata.gz: e1c0f19932a291bb805fd5c784ccc0d685bad189aab48ae5b2f2aed4bd56330c345cd3100a2530d12aff54259ea5499ca048f3137a2447e0c8423a829a860abe
7
+ data.tar.gz: 77af3c98596f4ad2d7f0a429f8275c7c487c91947ab88eb4a099187e84a0cb145518fc9829726bc6849fb78432957af850299934cce8f371494eff136d7719c6
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cvss_rating.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Stephen Kapp
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # Cvss Rating
2
+
3
+ Implements CVSS Risk Rating version 2.0
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'cvss_rating'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install cvss_rating
18
+
19
+ ## Usage
20
+
21
+ Check out the unit tests for examples of usage
22
+
23
+ ## TODO
24
+
25
+ * CVSS 3.0 Support
26
+ * Code and API clean up
27
+ * More Unit Tests
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rdoc/task'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the app_version plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the app_version plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'Cvss Rating'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cvss_rating/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cvss_rating"
8
+ spec.version = Cvss::Rating::VERSION
9
+ spec.authors = ["Stephen Kapp"]
10
+ spec.email = ["mort666@virus.org"]
11
+ spec.summary = %q{CVSS Risk Rating Calucation and Vector parsing}
12
+ spec.description = %q{CVSS Risk Rating Calucation and Vector parsing, implements CVSS 2.0 rating}
13
+ spec.homepage = "https://github.com/mort666/cvss_rating"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "minitest"
23
+ end
@@ -0,0 +1,5 @@
1
+ module Cvss
2
+ class Rating
3
+ VERSION = "0.1.1"
4
+ end
5
+ end
@@ -0,0 +1,453 @@
1
+ require "cvss_rating/version"
2
+
3
+ module Cvss
4
+ class Rating
5
+
6
+ attr_accessor :av, :ac, :au, :ci, :ii, :ai, :ex, :rl, :rc, :cdp, :td, :cr, :ir, :ar
7
+ attr_accessor :base, :temporal, :overall, :environmental, :impact, :exploitability, :adjimpact, :key
8
+
9
+ ACCESS_VECTOR = { :local => 0.395, :adjacent_network => 0.646, :network => 1.0 }
10
+ ACCESS_COMPLEXITY = { :high => 0.35, :medium => 0.61, :low => 0.71 }
11
+ AUTHENTICATION = { :none => 0.704, :single => 0.56, :multiple => 0.45 }
12
+
13
+ CONFIDENTIALITY_IMPACT = { :none => 0.0, :partial => 0.275, :complete => 0.660 }
14
+ INTEGRITY_IMPACT = { :none => 0.0, :partial => 0.275, :complete => 0.660 }
15
+ AVAILABILITY_IMPACT = { :none => 0.0, :partial => 0.275, :complete => 0.660 }
16
+
17
+ CONFIDENTIALITY_REQUIREMENT = { :low => 0.5, :medium => 1.0, :high => 1.51, :notdefined => -1.0 }
18
+ INTEGRITY_REQUIREMENT = { :low => 0.5, :medium => 1.0, :high => 1.51, :notdefined => -1.0 }
19
+ AVAILABILITY_REQUIREMENT = { :low => 0.5, :medium => 1.0, :high => 1.51, :notdefined => -1.0 }
20
+
21
+ EXPLOITABILITY = { :unproven => 0.85, :poc => 0.9, :functional => 0.95, :high => 1.0, :notdefined => -1.0 }
22
+ REMEDIATION_LEVEL = { :official => 0.87, :temporary => 0.9, :workaround => 0.95, :unavailable => 1.0, :notdefined => -1.0 }
23
+ REPORT_CONFIDENCE = { :unconfirmed => 0.90, :uncorroborated => 0.95, :confirmed => 1.0, :notdefined => -1.0 }
24
+
25
+ COLLATERAL_DAMAGE = { :none => 0.0, :low => 0.1, :low_medium => 0.3, :medium_high => 0.4, :high => 0.5, :notdefined => -1.0 }
26
+ TARGET_DISTRIBUTION = { :none => 0.0, :low => 0.25, :medium => 0.75, :high => 1.0, :notdefined => -1.0 }
27
+
28
+ ACCESS_VECTOR_KEY = { :local => 'L', :adjacent_network => 'A', :network => 'N' }
29
+ ACCESS_COMPLEXITY_KEY = { :high => 'H', :medium => 'M', :low => 'L' }
30
+ AUTHENTICATION_KEY = { :none => 'N', :single => 'S', :multiple => 'M' }
31
+
32
+ CONFIDENTIALITY_IMPACT_KEY = { :none => 'N', :partial => 'P', :complete => 'C' }
33
+ INTEGRITY_IMPACT_KEY = { :none => 'N', :partial => 'P', :complete => 'C' }
34
+ AVAILABILITY_IMPACT_KEY = { :none => 'N', :partial => 'P', :complete => 'C' }
35
+
36
+ CONFIDENTIALITY_REQUIREMENT_KEY = { :low => 'L', :medium => 'M', :high => 'H', :notdefined => 'ND' }
37
+ INTEGRITY_REQUIREMENT_KEY = { :low => 'L', :medium => 'M', :high => 'H', :notdefined => 'ND' }
38
+ AVAILABILITY_REQUIREMENT_KEY = { :low => 'L', :medium => 'M', :high => 'H', :notdefined => 'ND' }
39
+
40
+ EXPLOITABILITY_KEY = { :unproven => 'U', :poc => 'P', :functional => 'F', :high => 'H', :notdefined => 'ND' }
41
+ REMEDIATION_LEVEL_KEY = { :official => 'OF', :temporary => "TF", :workaround => 'W', :unavailable => 'U', :notdefined => 'ND' }
42
+ REPORT_CONFIDENCE_KEY = { :unconfirmed => 'UC', :uncorroborated => 'UR', :confirmed => 'C', :notdefined => 'ND' }
43
+
44
+ COLLATERAL_DAMAGE_KEY = { :none => 'N', :low => 'L', :low_medium => 'LM', :medium_high => 'MH', :high => 'H', :notdefined => 'ND' }
45
+ TARGET_DISTRIBUTION_KEY = { :none => 'N', :low => 'L', :medium => 'M', :high => 'H', :notdefined => 'ND' }
46
+
47
+ def initialize(attributes = {})
48
+ @base = nil
49
+ @temporal = nil
50
+ @environmental = nil
51
+
52
+ self.init
53
+
54
+ attributes.each do |name, value|
55
+ send("#{name}=", value)
56
+ end
57
+ end
58
+
59
+ def init(ex = "ND", rl = "ND", rc = "ND", cd = "ND", td = "ND", cr = "ND", ir = "ND", ar = "ND")
60
+ self.ex = ex
61
+ self.rl = rl
62
+ self.rc = rc
63
+
64
+ self.cdp = cd
65
+ self.td = td
66
+ self.cr = cr
67
+ self.ir = ir
68
+ self.ar = ar
69
+ end
70
+
71
+ def scores(av, ac, au, ci, ii, ai, ex = "ND", rl = "ND", rc = "ND", cd = "ND", td = "ND", cr = "ND", ir = "ND", ar = "ND")
72
+ self.av = av
73
+ self.ac = ac
74
+ self.au = au
75
+ self.ci = ci
76
+ self.ii = ii
77
+ self.ai = ai
78
+
79
+ self.ex = ex
80
+ self.rl = rl
81
+ self.rc = rc
82
+
83
+ self.cd = cd
84
+ self.td = td
85
+ self.cr = cr
86
+ self.ir = ir
87
+ self.ar = ar
88
+ end
89
+
90
+ def get_key(vector, value)
91
+ get_key = eval(vector + "_KEY")[(eval(vector).select { |k,v| v == value }).keys[0]]
92
+ end
93
+
94
+ def noenvironmental
95
+ if get_key("COLLATERAL_DAMAGE", @cdp) == "ND" && get_key("TARGET_DISTRIBUTION", @td) == "ND" && get_key("CONFIDENTIALITY_REQUIREMENT", @cr) == "ND" && get_key("INTEGRITY_REQUIREMENT", @ir) == "ND" && get_key("AVAILABILITY_REQUIREMENT", @ar) == "ND"
96
+ return true
97
+ else
98
+ return false
99
+ end
100
+ end
101
+
102
+ def notemporal
103
+ if get_key("EXPLOITABILITY", @ex) == "ND" && get_key("REMEDIATION_LEVEL", @rl) == "ND" && get_key("REPORT_CONFIDENCE", @rc) == "ND"
104
+ return true
105
+ else
106
+ return false
107
+ end
108
+ end
109
+
110
+ def set_key
111
+ @key = "AV:%s/AC:%s/Au:%s/C:%s/I:%s/A:%s" % [ get_key("ACCESS_VECTOR", @av),
112
+ get_key("ACCESS_COMPLEXITY", @ac),
113
+ get_key("AUTHENTICATION", @au),
114
+ get_key("CONFIDENTIALITY_IMPACT", @ci),
115
+ get_key("INTEGRITY_IMPACT", @ii),
116
+ get_key("AVAILABILITY_IMPACT", @ai)]
117
+
118
+ if !notemporal
119
+ @key += "/E:%s/RL:%s/RC:%s" % [ get_key("EXPLOITABILITY", @ex),
120
+ get_key("REMEDIATION_LEVEL", @rl),
121
+ get_key("REPORT_CONFIDENCE", @rc)]
122
+ end
123
+
124
+ if !noenvironmental
125
+ @key += "/CDP:%s/TD:%s/CR:%s/IR:%s/AR:%s" % [ get_key("COLLATERAL_DAMAGE", @cdp),
126
+ get_key("TARGET_DISTRIBUTION", @td),
127
+ get_key("CONFIDENTIALITY_REQUIREMENT", @cr),
128
+ get_key("INTEGRITY_REQUIREMENT", @ir),
129
+ get_key("AVAILABILITY_REQUIREMENT", @ar)]
130
+ end
131
+ end
132
+
133
+ def av=(av)
134
+ @av = case av
135
+ when "local", "L" then ACCESS_VECTOR[:local]
136
+ when "adjacent network", "A" then ACCESS_VECTOR[:adjacent_network]
137
+ when "network", "N" then ACCESS_VECTOR[:network]
138
+ else
139
+ raise "Bad Argument"
140
+ end
141
+ end
142
+
143
+ def av
144
+ av = get_key("ACCESS_VECTOR", @av) if !@av.nil?
145
+ end
146
+
147
+ def ac=(ac)
148
+ @ac = case ac
149
+ when "high", "H" then ACCESS_COMPLEXITY[:high]
150
+ when "medium", "M" then ACCESS_COMPLEXITY[:medium]
151
+ when "low", "L" then ACCESS_COMPLEXITY[:low]
152
+ else
153
+ raise "Bad Argument"
154
+ end
155
+ end
156
+
157
+ def ac
158
+ ac = get_key("ACCESS_COMPLEXITY", @ac) if !@ac.nil?
159
+ end
160
+
161
+ def au=(au)
162
+ @au = case au
163
+ when "none", "N" then AUTHENTICATION[:none]
164
+ when "single instance", "S" then AUTHENTICATION[:single]
165
+ when "multiple instance", "M" then AUTHENTICATION[:multiple]
166
+ else
167
+ raise "Bad Argument"
168
+ end
169
+ end
170
+
171
+ def au
172
+ au = get_key("AUTHENTICATION", @au) if !@au.nil?
173
+ end
174
+
175
+ def ci=(ci)
176
+ @ci = case ci
177
+ when "none", "N" then CONFIDENTIALITY_IMPACT[:none]
178
+ when "partial", "P" then CONFIDENTIALITY_IMPACT[:partial]
179
+ when "complete", "C" then CONFIDENTIALITY_IMPACT[:complete]
180
+ else
181
+ raise "Bad Argument"
182
+ end
183
+ end
184
+
185
+ def ci
186
+ ci = get_key("CONFIDENTIALITY_IMPACT", @ci) if !@ci.nil?
187
+ end
188
+
189
+ def ii=(ii)
190
+ @ii = case ii
191
+ when "none", "N" then INTEGRITY_IMPACT[:none]
192
+ when "partial", "P" then INTEGRITY_IMPACT[:partial]
193
+ when "complete", "C" then INTEGRITY_IMPACT[:complete]
194
+ else
195
+ raise "Bad Argument"
196
+ end
197
+ end
198
+
199
+ def ii
200
+ ii = get_key("INTEGRITY_IMPACT", @ii) if !@ii.nil?
201
+ end
202
+
203
+ def ai=(ai)
204
+ @ai = case ai
205
+ when "none", "N" then AVAILABILITY_IMPACT[:none]
206
+ when "partial", "P" then AVAILABILITY_IMPACT[:partial]
207
+ when "complete", "C" then AVAILABILITY_IMPACT[:complete]
208
+ else
209
+ raise "Bad Argument"
210
+ end
211
+ end
212
+
213
+ def ai
214
+ ai = get_key("AVAILABILITY_IMPACT", @ai) if !@ai.nil?
215
+ end
216
+
217
+ def ex=(ex)
218
+ @ex = case ex
219
+ when "unproven", "U" then EXPLOITABILITY[:unproven]
220
+ when "proof-of-concept", "P", "POC" then EXPLOITABILITY[:poc]
221
+ when "functional", "F" then EXPLOITABILITY[:functional]
222
+ when "high", "H" then EXPLOITABILITY[:high]
223
+ when "not defined", "ND" then EXPLOITABILITY[:notdefined]
224
+ else
225
+ raise "Bad Argument"
226
+ end
227
+ end
228
+
229
+ def ex
230
+ ex = get_key("EXPLOITABILITY", @ex) if !@ex.nil?
231
+ end
232
+
233
+ def rl=(rl)
234
+ @rl = case rl
235
+ when "official-fix", "O" then REMEDIATION_LEVEL[:official]
236
+ when "temporary-fix", "T", "TF" then REMEDIATION_LEVEL[:temporary]
237
+ when "workaround", "W" then REMEDIATION_LEVEL[:workaround]
238
+ when "unavailable", "U" then REMEDIATION_LEVEL[:unavailable]
239
+ when "not defined", "ND" then REMEDIATION_LEVEL[:notdefined]
240
+ else
241
+ raise "Bad Argument"
242
+ end
243
+ end
244
+
245
+ def rl
246
+ rl = get_key("REMEDIATION_LEVEL", @rl) if !@rl.nil?
247
+ end
248
+
249
+ def rc=(rc)
250
+ @rc = case rc
251
+ when "unconfirmed", "UC" then REPORT_CONFIDENCE[:unconfirmed]
252
+ when "uncorroborated", "UR" then REPORT_CONFIDENCE[:uncorroborated]
253
+ when "confirmed", "C" then REPORT_CONFIDENCE[:confirmed]
254
+ when "not defined", "ND" then REPORT_CONFIDENCE[:notdefined]
255
+ else
256
+ raise "Bad Argument"
257
+ end
258
+ end
259
+
260
+ def rc
261
+ rc = get_key("REPORT_CONFIDENCE", @rc) if !@av.nil?
262
+ end
263
+
264
+ def cdp=(cd)
265
+ @cdp = case cd
266
+ when "none", "N" then COLLATERAL_DAMAGE[:none]
267
+ when "low", "L" then COLLATERAL_DAMAGE[:low]
268
+ when "low-medium", "LM" then COLLATERAL_DAMAGE[:low_medium]
269
+ when "medium-high", "MH" then COLLATERAL_DAMAGE[:medium_high]
270
+ when "high", "H" then COLLATERAL_DAMAGE[:high]
271
+ when "not defined", "ND" then COLLATERAL_DAMAGE[:notdefined]
272
+ else
273
+ raise "Bad Argument"
274
+ end
275
+ end
276
+
277
+ def cdp
278
+ cdp = get_key("COLLATERAL_DAMAGE", @cdp) if !@cdp.nil?
279
+ end
280
+
281
+ def td=(td)
282
+ @td = case td
283
+ when "none", "N" then TARGET_DISTRIBUTION[:none]
284
+ when "low", "L" then TARGET_DISTRIBUTION[:low]
285
+ when "medium", "M" then TARGET_DISTRIBUTION[:medium]
286
+ when "high", "H" then TARGET_DISTRIBUTION[:high]
287
+ when "not defined", "ND" then TARGET_DISTRIBUTION[:notdefined]
288
+ else
289
+ raise "Bad Argument"
290
+ end
291
+ end
292
+
293
+ def td
294
+ td = get_key("TARGET_DISTRIBUTION", @td) if !@td.nil?
295
+ end
296
+
297
+ def cr=(cr)
298
+ @cr = case cr
299
+ when "low", "L" then CONFIDENTIALITY_REQUIREMENT[:low]
300
+ when "medium", "M" then CONFIDENTIALITY_REQUIREMENT[:medium]
301
+ when "high", "H" then CONFIDENTIALITY_REQUIREMENT[:high]
302
+ when "not defined", "ND" then CONFIDENTIALITY_REQUIREMENT[:notdefined]
303
+ else
304
+ raise "Bad Argument"
305
+ end
306
+ end
307
+
308
+ def cr
309
+ cr = get_key("CONFIDENTIALITY_REQUIREMENT", @cr) if !@cr.nil?
310
+ end
311
+
312
+ def ir=(ir)
313
+ @ir = case ir
314
+ when "low", "L" then INTEGRITY_REQUIREMENT[:low]
315
+ when "medium", "M" then INTEGRITY_REQUIREMENT[:medium]
316
+ when "high", "H" then INTEGRITY_REQUIREMENT[:high]
317
+ when "not defined", "ND" then INTEGRITY_REQUIREMENT[:notdefined]
318
+ else
319
+ raise "Bad Argument"
320
+ end
321
+ end
322
+
323
+ def ir
324
+ ir = get_key("INTEGRITY_REQUIREMENT", @ir) if !@ir.nil?
325
+ end
326
+
327
+ def ar=(ar)
328
+ @ar = case ar
329
+ when "low", "L" then AVAILABILITY_REQUIREMENT[:low]
330
+ when "medium", "M" then AVAILABILITY_REQUIREMENT[:medium]
331
+ when "high", "H" then AVAILABILITY_REQUIREMENT[:high]
332
+ when "not defined", "ND" then AVAILABILITY_REQUIREMENT[:notdefined]
333
+ else
334
+ raise "Bad Argument"
335
+ end
336
+ end
337
+
338
+ def ar
339
+ ar = get_key("AVAILABILITY_REQUIREMENT", @ar) if !@ar.nil?
340
+ end
341
+
342
+ VECTORS = {
343
+ "av" => "av=",
344
+ "ac" => "ac=",
345
+ "au" => "au=",
346
+ "c" => "ci=",
347
+ "i" => "ii=",
348
+ "a" => "ai=",
349
+ "e" => "ex=",
350
+ "rl" => "rl=",
351
+ "rc" => "rc=",
352
+ "cdp" => "cdp=",
353
+ "td" => "td=",
354
+ "cr" => "cr=",
355
+ "ir" => "ir=",
356
+ "ar" => "ar="
357
+ }
358
+
359
+ def parse(vector)
360
+ string = vector.split("/")
361
+ len = string.length
362
+
363
+ self.init
364
+
365
+ @originalkey = vector
366
+
367
+ string.each do |section|
368
+ tmp = section.split(":")
369
+ send(VECTORS[tmp[0].downcase].to_sym, tmp[1])
370
+ end
371
+ end
372
+
373
+ def key
374
+ self.set_key
375
+ return @key
376
+ end
377
+
378
+ def to_s
379
+ printf "Base Score:\t\t\t%3.1f\n", @base
380
+ printf " Impact Subscore:\t\t%3.1f\n", @impact
381
+ printf " Exploitability Subscore:\t%3.1f\n", @exploitability
382
+ printf "Temporal Score:\t\t\t%3.1f\n", @temporal if !self.notemporal
383
+ printf "Environmental Score:\t\t%3.1f\n", @environmental if !self.noenvironmental
384
+ printf " Adjusted Impact Score:\t%3.1f\n", @adjimpact if !self.noenvironmental
385
+ printf "Overall Score:\t\t\t%3.1f\n", overallscore
386
+ end
387
+
388
+ def calculate
389
+ @impact = self.impactscore
390
+ @adjimpact = self.adjustedimpactscore
391
+ @exploitability = self.exploitabilityscore
392
+ @base = self.basescore
393
+ @temporal = self.temporalscore
394
+ @environmental = self.environmentalscore(self.adjustedtemporalscore(self.adjustedbasescore(@adjimpact, @exploitability)))
395
+ end
396
+
397
+ def adjustedimpactscore
398
+ tmp = []
399
+ tmp[0] = 10
400
+ tmp[1] = 10.41*(1-(1-@ci.abs*@cr.abs)*(1-@ii.abs*@ir.abs)*(1-@ai.abs*@ar.abs))
401
+ adjustedimpactscore = tmp.min
402
+ end
403
+
404
+ def adjustedbasescore(adjustedimpact, exploitabilityscore)
405
+ adjustedbasescore = (0.6*adjustedimpact + 0.4 * exploitabilityscore - 1.5) * impactfunction(adjustedimpact)
406
+ end
407
+
408
+ def adjustedtemporalscore(adjustedbasescore)
409
+ adjustedtemporalscore = adjustedbasescore * @ex.abs * @rl.abs * @rc.abs
410
+ end
411
+
412
+ def exploitabilityscore
413
+ exploitability = 20 * @ac.abs * @au.abs * @av.abs
414
+ end
415
+
416
+ def environmentalscore(adjustedtemporalscore)
417
+ environmentalscore = (adjustedtemporalscore + (10 - adjustedtemporalscore) * (@cdp == -1 ? 0 : @cdp.abs)) * @td.abs
418
+
419
+ return environmentalscore == 0.0 ? "Undefined" : environmentalscore
420
+ end
421
+
422
+ def overallscore
423
+ if self.noenvironmental
424
+ if self.notemporal
425
+ overallscore = @base
426
+ else
427
+ overallscore = @temporal
428
+ end
429
+ else
430
+ overallscore = @environmental
431
+ end
432
+ return overallscore
433
+ end
434
+
435
+ def impactfunction(impact)
436
+ return impact != 0 ? 1.176 : 0.0
437
+ end
438
+
439
+ def impactscore
440
+ impact = 10.41*(1.0-(1.0-@ci.abs)*(1.0-@ii.abs)*(1.0-@ai.abs))
441
+ end
442
+
443
+ def basescore
444
+ basescore = (0.6 * @impact + 0.4 * @exploitability - 1.5) * impactfunction(@impact)
445
+ end
446
+
447
+ def temporalscore
448
+ temporalscore = @base * @ex.abs * @rl.abs * @rc.abs
449
+
450
+ return temporalscore == 0.0 ? "Undefined" : temporalscore
451
+ end
452
+ end
453
+ end
@@ -0,0 +1,61 @@
1
+ require 'minitest/autorun'
2
+ require 'active_support'
3
+ require 'cvss_rating'
4
+
5
+ class CvssRatingTest < MiniTest::Unit::TestCase
6
+ def setup
7
+ @cvss = Cvss::Rating.new
8
+ @cvss.av = "N"
9
+ @cvss.ac = "M"
10
+ @cvss.au = "N"
11
+ @cvss.ci = "P"
12
+ @cvss.ii = "P"
13
+ @cvss.ai = "P"
14
+ @cvss.set_key
15
+
16
+ @cvss_2 = Cvss::Rating.new
17
+ @cvss_2.av = "L"
18
+ @cvss_2.ac = "M"
19
+ @cvss_2.au = "M"
20
+ @cvss_2.ci = "P"
21
+ @cvss_2.ii = "C"
22
+ @cvss_2.ai = "C"
23
+ @cvss_2.cdp = "L"
24
+ @cvss_2.td = "H"
25
+ @cvss_2.cr = "M"
26
+ @cvss_2.ir = "M"
27
+ @cvss_2.ar = "M"
28
+ @cvss_2.set_key
29
+ end
30
+
31
+ def test_cvss_rating_from_vector
32
+ cvss = Cvss::Rating.new
33
+ cvss.parse("AV:N/AC:M/Au:N/C:P/I:P/A:P")
34
+ assert_equal @cvss.key, cvss.key
35
+
36
+ assert_equal @cvss.base, cvss.base
37
+
38
+ assert_equal @cvss.overallscore, cvss.overallscore
39
+
40
+ cvss.init
41
+ cvss.parse("AV:L/AC:M/Au:M/C:P/I:C/A:C/CDP:L/TD:H/CR:M/IR:M/AR:M")
42
+ assert_equal @cvss_2.key, cvss.key
43
+
44
+ assert_equal @cvss_2.base, cvss.base
45
+
46
+ assert_equal @cvss_2.overallscore, cvss.overallscore
47
+ end
48
+
49
+ def test_cvss_rating_parameters
50
+ cvss = Cvss::Rating.new
51
+ cvss.init
52
+
53
+ cvss.av = "local"
54
+
55
+ assert_equal @cvss_2.av, cvss.av
56
+
57
+ cvss.cdp = 'low'
58
+
59
+ assert_equal @cvss_2.cdp, cvss.cdp
60
+ end
61
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cvss_rating
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Stephen Kapp
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: CVSS Risk Rating Calucation and Vector parsing, implements CVSS 2.0 rating
42
+ email:
43
+ - mort666@virus.org
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - cvss_rating.gemspec
54
+ - lib/cvss_rating.rb
55
+ - lib/cvss_rating/version.rb
56
+ - test/cvss_rating_test.rb
57
+ homepage: https://github.com/mort666/cvss_rating
58
+ licenses:
59
+ - MIT
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 2.2.2
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: CVSS Risk Rating Calucation and Vector parsing
81
+ test_files:
82
+ - test/cvss_rating_test.rb