cvss / cvss.js
khulnasoft's picture
Create cvss.js
3591e57 verified
raw
history blame
12.1 kB
// work in progress
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;
}
// Compute EQs
// => EQ1 - Table 25
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;
}
// => EQ2 - Table 26
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;
}
// => EQ3 - Table 27
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;
}
// => EQ4 - Table 28
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;
}
// => EQ5 - Table 29
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;
}
// => EQ6 - Table 30
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;
}
// => EQ3+EQ6 - Table 31
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];
}