|
|
|
|
|
vectorMap4 = { |
|
"attackVector": "AV", |
|
"attackComplexity": "AC", |
|
"attackRequirements": "AT", |
|
"privilegesRequired": "PR", |
|
"userInteraction": "UI", |
|
"vulnConfidentialityImpact": "VC", |
|
"vulnIntegrityImpact": "VI", |
|
"vulnAvailabilityImpact": "VA", |
|
"subConfidentialityImpact": "SC", |
|
"subIntegrityImpact": "SI", |
|
"subAvailabilityImpact": "SA", |
|
"Safety": "S", |
|
"Automatable": "AU", |
|
"Recovery": "R", |
|
"valueDensity": "V", |
|
"vulnerabilityResponseEffort": "RE", |
|
"providerUrgency": "U", |
|
"exploitMaturity": "E" |
|
}; |
|
|
|
function invertObject(obj) { |
|
const inverted = {}; |
|
for (const key in obj) { |
|
inverted[obj[key]] = key; |
|
} |
|
return inverted; |
|
} |
|
|
|
|
|
var metricMap4 = invertObject(vectorMap4); |
|
|
|
var valueMap = { |
|
"UNDEFINED": "X", |
|
"GREEN": "Green", |
|
"RED": "Red", |
|
"CLEAR": "Clear", |
|
"AMBER": "Amber" |
|
}; |
|
|
|
function vector(cv){ |
|
var v = "CVSS:4.0"; |
|
for(const key in metricMap4) { |
|
if(cv[key]) |
|
v = v + '/' + key + ':' + cv[key] |
|
} |
|
return v; |
|
} |
|
|
|
function vectorize(c) { |
|
var cv = {}; |
|
for(const key in c){ |
|
var m = vectorMap4[key]; |
|
var v = undefined; |
|
console.log(key +'='+ c[key]) |
|
if(m && c[key]) { |
|
v = valueMap[c[key]] || c[key].charAt(0); |
|
} |
|
if(v) { |
|
cv[m]=v; |
|
} |
|
} |
|
return cv; |
|
} |
|
|
|
function vectorizeString(s) { |
|
var cv = {}; |
|
var metrics = s.split("/"); |
|
for(index in metrics) { |
|
var [key, value] = metrics[index].split(":"); |
|
cv[key] = value; |
|
} |
|
return cv; |
|
} |
|
|
|
function macroVector(cvss) { |
|
var c = vectorize(cvss); |
|
|
|
var N='N', P='P', X='X', H='H', L='L', R='R', S = 'S'; |
|
|
|
var av = c.AV, |
|
ac = c.AC, |
|
ui = c.UI, |
|
at = c.AT, |
|
pr = c.PR, |
|
vc = c.VC, |
|
va = c.VA, |
|
vi = c.VI, |
|
sc = c.SC, |
|
si = c.SI, |
|
sa = c.SA, |
|
e = e, |
|
cr = c.CR, |
|
ir = c.IR, |
|
ar = c.AR, |
|
msi = c.MSI, |
|
msa = c.MSA |
|
; |
|
|
|
if([vc, vi, va, sc, si, sa].every((met) => met == N)) { |
|
return 0; |
|
} |
|
|
|
|
|
|
|
|
|
var eq = []; |
|
eq[1] = 0; |
|
if(av == N && pr == N && ui == N) { |
|
eq[1] = 0 |
|
} else if ((av == N || pr == N || ui == N) && !(av == N && pr == N && ui == N) && !(av == P)) { |
|
eq[1] = 1 |
|
} else if (av == P || !(av == N || pr == N || ui == N)) { |
|
eq[1] = 2 |
|
} else { |
|
console.log("EQ1 invalid CVSS configuration: AV:%s/PR:%s/UI:%s\n", av, pr, ui); |
|
return undefined; |
|
} |
|
|
|
eq[2] = 0 |
|
if (ac == L && at == N) { |
|
eq[2] = 0 |
|
} else if (!(ac == L && at == N)) { |
|
eq[2] = 1 |
|
} else { |
|
console.log("EQ2 invalid CVSS configuration: AC:%s/AT:%s\n", ac, at) |
|
return undefined; |
|
} |
|
|
|
eq[3] = 0; |
|
if(vc == H && vi == H){ |
|
eq[3] = 0 |
|
} else if (!(vc == H && vi == H) && (vc == H || vi == H || va == H)) { |
|
eq[3] = 1 |
|
} else if (!(vc == H || vi == H || va == H)) { |
|
eq[3] = 2 |
|
} else { |
|
console.log("EQ3 invalid CVSS configuration: VC:%s/VI:%s/VA:%s\n", vc, vi, va) |
|
return undefined; |
|
|
|
} |
|
|
|
eq[4] = 0 |
|
if (msi == S || msa == S) { |
|
eq[4] = 0 |
|
} else if (!(msi == S && msa == S) && (sc == H || si == H || sa == H)) { |
|
eq[4] = 1 |
|
} else if (!(msi == S && msa == S) && !(sc == H || si == H || sa == H)) { |
|
eq[4] = 2 |
|
} else { |
|
console.log("EQ4 invalid CVSS configuration: MSI:%s/MSA:%s/SC:%s/SI:%s/SA:%s\n", msi, msa, cvss40.get("SC"), cvss40.get("SI"), cvss40.get("SA")) |
|
return undefined; |
|
} |
|
|
|
eq[5] = 0 |
|
if (e == "A" || e == X || e == undefined) { |
|
eq[5] = 0 |
|
} else if (e == "P") { |
|
eq[5] = 1 |
|
} else if (e == "U") { |
|
eq[5] = 2 |
|
} else { |
|
console.log("EQ5 invalid CVSS configuration: E:%s\n", e) |
|
return undefined; |
|
} |
|
|
|
eq[6] = 0 |
|
if (av == N && pr == N && ui == N) { |
|
eq[6] = 0 |
|
} else if ((cr == H && vc == H) || (c.IR == H && vi == H) || (c.AR == H && va == H) ){ |
|
eq[6] = 1 |
|
} else { |
|
console.log("EQ6 invalid CVSS configuration: AV:%s/PR:%s/UI:%s/CR:%s/VC:%s/IR:%s/VI:%s/AR:%s/VA:%s\n", av, pr, ui, cr, vc, c.IR, vi) |
|
return undefined; |
|
|
|
} |
|
|
|
eq[7]= 0 |
|
if (vc == H && vi == H && (cr == H || ir == H || (ar == H && va == H))) { |
|
eq[7] = '00'; |
|
} else if (vc == H && vi == H && !(cr == H || ir == H) && !(ar == H && va == H)) { |
|
eq[7] = '01'; |
|
} else if (!(vc == H && vi == H) && (vc == H || vi == H || va == H) && (cr == H && vc == H) || (ir == H && vi == H) || (ar == H && va == H)) { |
|
eq[7] = 10; |
|
} else if (!(vc == H && vi == H) && (vc == H || vi == H || va == H) && !(cr == H && vc == H) && !(ir == H && vi == H) && !(ar == H && va == H)) { |
|
eq[7] = 11; |
|
} else if (!(vc == H || vi == H || va == H) && (cr == H && vc == H) || (ir == H && vi == H) || (ar == H && va == H)){ |
|
eq[7] = 20; |
|
} else if (!(vc == H || vi == H || va == H) && !(cr == H && vc == H) && !(ir == H && vi == H) && !(ar == H && va == H)) { |
|
eq[7] = 21; |
|
} else { |
|
console.log("EQ36 invalid CVSS configuration: CR:%s/VC:%s/IR:%s/VI:%s/AR:%s/VA:%s\n", cr, vc, ir, vi, ar, va) |
|
return undefined; |
|
} |
|
var current = eq; |
|
var diff = []; |
|
var currentScore = lookup(eq); |
|
for(const eqSet = 1; eqSet < 7; eqSet++) { |
|
var lowSet = Array.from(originalArray); |
|
lowSet[eqSet] = lowSet[eqSet]+1; |
|
var lowScore = lookup(lowSet); |
|
var maxDiff = currentScore - lowScore; |
|
var mV = maxVectors(eqSet); |
|
var hammingDistance = 0; |
|
for(const m in mV) { |
|
var hd = getHammingDistance(c, vectorizeString(m)); |
|
if(hd > hammingDistance) { |
|
hammingDistance = hd; |
|
} |
|
} |
|
var prop = hammingDistance/depth; |
|
diff[eqSet] = maxDiff * prop; |
|
} |
|
} |
|
|
|
function getHammingDistance(a, b) { |
|
var dist = {}; |
|
for(const key in a) { |
|
dist[key] = levels[key][a[key]] - levels[key][b[key]]; |
|
} |
|
if(a.MSI == 'S') { |
|
dist.SI = levels.SI['S'] - levels.SI[b.SI] |
|
} |
|
if(a.MSA == 'S') { |
|
dist.SI = levels.SA['S'] - levels.SA[b.SA] |
|
} |
|
var ret = 0; |
|
for(const key in dist) { |
|
ret = ret + Math.abs(dist[key]); |
|
} |
|
return ret; |
|
} |
|
|
|
const maxHamming = { |
|
"eq1" : { |
|
"0" : 1, |
|
"1" : 4, |
|
"2" : 5 |
|
}, |
|
"eq2" : { |
|
"0" : 1, |
|
"1" : 2 |
|
}, |
|
"eq3" : { |
|
"00": 7, |
|
"01": 6, |
|
"10": 8, |
|
"11": 8, |
|
"21": 10 |
|
}, |
|
"eq4" : { |
|
"0" : 6, |
|
"1" : 5, |
|
"2" : 4 |
|
|
|
}, |
|
"eq5" : { |
|
"0" : 1, |
|
"1" : 1, |
|
"2" : 1 |
|
}, |
|
} |
|
|
|
function maxVectors(eqSet, eqVal) { |
|
return maxComposed[eqSet-1][eqVal]; |
|
} |
|
|
|
const maxComposed = [ |
|
{ |
|
"0": ["AV:N/PR:N/UI:N/"], |
|
"1" : ["AV:A/PR:N/UI:N/","AV:N/PR:L/UI:N/","AV:N/PR:N/UI:P/"], |
|
"2": ["AV:P/PR:N/UI:N/","AV:A/PR:L/UI:P/"] |
|
}, |
|
{ |
|
"0" : ["AC:L/AT:N/"], |
|
"1" : ["AC:H/AT:N/","AC:L/AT:P/"] |
|
}, |
|
{ |
|
"00": ["VC:H/VI:H/VA:H/CR:H/IR:H/AR:H/"], |
|
"01": ["VC:H/VI:H/VA:L/CR:M/IR:M/AR:H/","VC:H/VI:H/VA:H/CR:M/IR:M/AR:M/"], |
|
"10": ["VC:L/VI:H/VA:H/CR:H/IR:H/AR:H/","VC:H/VI:L/VA:H/CR:H/IR:H/AR:H/"], |
|
"11": ["VC:L/VI:H/VA:L/CR:H/IR:M/AR:H/","VC:L/VI:H/VA:H/CR:H/IR:M/AR:M/","VC:H/VI:L/VA:H/CR:M/IR:H/AR:M/","VC:H/VI:L/VA:L/CR:M/IR:H/AR:H/","VC:L/VI:L/VA:H/CR:H/IR:H/AR:M/"], |
|
"21": ["VC:L/VI:L/VA:L/CR:H/IR:H/AR:H/"] |
|
}, |
|
{ |
|
"0" : ["SC:H/SI:S/SA:S/"], |
|
"1" : ["SC:H/SI:H/SA:H/"], |
|
"2" : ["SC:L/SI:L/SA:L/"] |
|
|
|
}, |
|
{ |
|
"0" : ["E:A/"], |
|
"1" : ["E:P/"], |
|
"2" : ["E:U/"], |
|
}, |
|
] |
|
|
|
function lookup(m) { |
|
var score = lookuptable[m.join(''); |
|
return score; |
|
} |
|
|
|
const lookuptable = { |
|
"000000": 10, |
|
"000001": 9.9, |
|
"000010": 9.8, |
|
"000011": 9.5, |
|
"000020": 9.5, |
|
"000021": 9.2, |
|
"000100": 10, |
|
"000101": 9.6, |
|
"000110": 9.3, |
|
"000111": 8.7, |
|
"000120": 9.1, |
|
"000121": 8.1, |
|
"000200": 9.3, |
|
"000201": 9, |
|
"000210": 8.9, |
|
"000211": 8, |
|
"000220": 8.1, |
|
"000221": 6.8, |
|
"001000": 9.8, |
|
"001001": 9.5, |
|
"001010": 9.5, |
|
"001011": 9.2, |
|
"001020": 9, |
|
"001021": 8.4, |
|
"001100": 9.3, |
|
"001101": 9.2, |
|
"001110": 8.9, |
|
"001111": 8.1, |
|
"001120": 8.1, |
|
"001121": 6.5, |
|
"001200": 8.8, |
|
"001201": 8, |
|
"001210": 7.8, |
|
"001211": 7, |
|
"001220": 6.9, |
|
"001221": 4.8, |
|
"002001": 9.2, |
|
"002011": 8.2, |
|
"002021": 7.2, |
|
"002101": 7.9, |
|
"002111": 6.9, |
|
"002121": 5, |
|
"002201": 6.9, |
|
"002211": 5.5, |
|
"002221": 2.7, |
|
"010000": 9.9, |
|
"010001": 9.7, |
|
"010010": 9.5, |
|
"010011": 9.2, |
|
"010020": 9.2, |
|
"010021": 8.5, |
|
"010100": 9.5, |
|
"010101": 9.1, |
|
"010110": 9, |
|
"010111": 8.3, |
|
"010120": 8.4, |
|
"010121": 7.1, |
|
"010200": 9.2, |
|
"010201": 8.1, |
|
"010210": 8.2, |
|
"010211": 7.1, |
|
"010220": 7.2, |
|
"010221": 5.3, |
|
"011000": 9.5, |
|
"011001": 9.3, |
|
"011010": 9.2, |
|
"011011": 8.5, |
|
"011020": 8.5, |
|
"011021": 7.3, |
|
"011100": 9.2, |
|
"011101": 8.2, |
|
"011110": 8, |
|
"011111": 7.2, |
|
"011120": 7, |
|
"011121": 5.9, |
|
"011200": 8.4, |
|
"011201": 7, |
|
"011210": 7.1, |
|
"011211": 5.2, |
|
"011220": 5, |
|
"011221": 3, |
|
"012001": 8.6, |
|
"012011": 7.5, |
|
"012021": 5.2, |
|
"012101": 7.1, |
|
"012111": 5.2, |
|
"012121": 2.9, |
|
"012201": 6.3, |
|
"012211": 2.9, |
|
"012221": 1.7, |
|
"100000": 9.8, |
|
"100001": 9.5, |
|
"100010": 9.4, |
|
"100011": 8.7, |
|
"100020": 9.1, |
|
"100021": 8.1, |
|
"100100": 9.4, |
|
"100101": 8.9, |
|
"100110": 8.6, |
|
"100111": 7.4, |
|
"100120": 7.7, |
|
"100121": 6.4, |
|
"100200": 8.7, |
|
"100201": 7.5, |
|
"100210": 7.4, |
|
"100211": 6.3, |
|
"100220": 6.3, |
|
"100221": 4.9, |
|
"101000": 9.4, |
|
"101001": 8.9, |
|
"101010": 8.8, |
|
"101011": 7.7, |
|
"101020": 7.6, |
|
"101021": 6.7, |
|
"101100": 8.6, |
|
"101101": 7.6, |
|
"101110": 7.4, |
|
"101111": 5.8, |
|
"101120": 5.9, |
|
"101121": 5, |
|
"101200": 7.2, |
|
"101201": 5.7, |
|
"101210": 5.7, |
|
"101211": 5.2, |
|
"101220": 5.2, |
|
"101221": 2.5, |
|
"102001": 8.3, |
|
"102011": 7, |
|
"102021": 5.4, |
|
"102101": 6.5, |
|
"102111": 5.8, |
|
"102121": 2.6, |
|
"102201": 5.3, |
|
"102211": 2.1, |
|
"102221": 1.3, |
|
"110000": 9.5, |
|
"110001": 9, |
|
"110010": 8.8, |
|
"110011": 7.6, |
|
"110020": 7.6, |
|
"110021": 7, |
|
"110100": 9, |
|
"110101": 7.7, |
|
"110110": 7.5, |
|
"110111": 6.2, |
|
"110120": 6.1, |
|
"110121": 5.3, |
|
"110200": 7.7, |
|
"110201": 6.6, |
|
"110210": 6.8, |
|
"110211": 5.9, |
|
"110220": 5.2, |
|
"110221": 3, |
|
"111000": 8.9, |
|
"111001": 7.8, |
|
"111010": 7.6, |
|
"111011": 6.7, |
|
"111020": 6.2, |
|
"111021": 5.8, |
|
"111100": 7.4, |
|
"111101": 5.9, |
|
"111110": 5.7, |
|
"111111": 5.7, |
|
"111120": 4.7, |
|
"111121": 2.3, |
|
"111200": 6.1, |
|
"111201": 5.2, |
|
"111210": 5.7, |
|
"111211": 2.9, |
|
"111220": 2.4, |
|
"111221": 1.6, |
|
"112001": 7.1, |
|
"112011": 5.9, |
|
"112021": 3, |
|
"112101": 5.8, |
|
"112111": 2.6, |
|
"112121": 1.5, |
|
"112201": 2.3, |
|
"112211": 1.3, |
|
"112221": 0.6, |
|
"200000": 9.3, |
|
"200001": 8.7, |
|
"200010": 8.6, |
|
"200011": 7.2, |
|
"200020": 7.5, |
|
"200021": 5.8, |
|
"200100": 8.6, |
|
"200101": 7.4, |
|
"200110": 7.4, |
|
"200111": 6.1, |
|
"200120": 5.6, |
|
"200121": 3.4, |
|
"200200": 7, |
|
"200201": 5.4, |
|
"200210": 5.2, |
|
"200211": 4, |
|
"200220": 4, |
|
"200221": 2.2, |
|
"201000": 8.5, |
|
"201001": 7.5, |
|
"201010": 7.4, |
|
"201011": 5.5, |
|
"201020": 6.2, |
|
"201021": 5.1, |
|
"201100": 7.2, |
|
"201101": 5.7, |
|
"201110": 5.5, |
|
"201111": 4.1, |
|
"201120": 4.6, |
|
"201121": 1.9, |
|
"201200": 5.3, |
|
"201201": 3.6, |
|
"201210": 3.4, |
|
"201211": 1.9, |
|
"201220": 1.9, |
|
"201221": 0.8, |
|
"202001": 6.4, |
|
"202011": 5.1, |
|
"202021": 2, |
|
"202101": 4.7, |
|
"202111": 2.1, |
|
"202121": 1.1, |
|
"202201": 2.4, |
|
"202211": 0.9, |
|
"202221": 0.4, |
|
"210000": 8.8, |
|
"210001": 7.5, |
|
"210010": 7.3, |
|
"210011": 5.3, |
|
"210020": 6, |
|
"210021": 5, |
|
"210100": 7.3, |
|
"210101": 5.5, |
|
"210110": 5.9, |
|
"210111": 4, |
|
"210120": 4.1, |
|
"210121": 2, |
|
"210200": 5.4, |
|
"210201": 4.3, |
|
"210210": 4.5, |
|
"210211": 2.2, |
|
"210220": 2, |
|
"210221": 1.1, |
|
"211000": 7.5, |
|
"211001": 5.5, |
|
"211010": 5.8, |
|
"211011": 4.5, |
|
"211020": 4, |
|
"211021": 2.1, |
|
"211100": 6.1, |
|
"211101": 5.1, |
|
"211110": 4.8, |
|
"211111": 1.8, |
|
"211120": 2, |
|
"211121": 0.9, |
|
"211200": 4.6, |
|
"211201": 1.8, |
|
"211210": 1.7, |
|
"211211": 0.7, |
|
"211220": 0.8, |
|
"211221": 0.2, |
|
"212001": 5.3, |
|
"212011": 2.4, |
|
"212021": 1.4, |
|
"212101": 2.4, |
|
"212111": 1.2, |
|
"212121": 0.5, |
|
"212201": 1, |
|
"212211": 0.3, |
|
"212221": 0.1 |
|
} |
|
|
|
function getLevel(m,v) { |
|
return levels[m][v] |
|
} |
|
|
|
const levels = { |
|
'AV': {"N": 0.0, "A": 0.1, "L": 0.2, "P": 0.3}, |
|
'PR': {"N": 0.0, "L": 0.1, "H": 0.2}, |
|
'UI': {"N": 0.0, "P": 0.1, "A": 0.2}, |
|
'AC': {'L':0.0, 'H':0.1}, |
|
'AT': {'N':0.0, 'P':0.1}, |
|
'VC': {'H':0.0, 'L':0.1, 'N':0.2}, |
|
'VI': {'H':0.0, 'L':0.1, 'N':0.2}, |
|
'VA': {'H':0.0, 'L':0.1, 'N':0.2}, |
|
'SC': {'H':0.1, 'L':0.2, 'N':0.3}, |
|
'SI': {'S':0.0, 'H':0.1, 'L':0.2, 'N':0.3}, |
|
'SA': {'S':0.0, 'H':0.1, 'L':0.2, 'N':0.3}, |
|
'CR': {'H':0.0, 'M':0.1, 'L':0.2}, |
|
'IR': {'H':0.0, 'M':0.1, 'L':0.2}, |
|
'AR': {'H':0.0, 'M':0.1, 'L':0.2}, |
|
'E': {'U': 0.2, 'P': 0.1, 'A': 0} |
|
} |
|
|
|
function score(mv) { |
|
var eq1 = mv[0], |
|
eq2 = mv[1], |
|
eq3 = mv[2], |
|
eq4 = mv[3], |
|
eq5 = mv[4], |
|
eq6 = mv[5], |
|
eq36 = mv[6]; |
|
} |