Last updated
let cve;
if (data.vulnerability_custom_fields) {
for (let i = 0; i < data.vulnerability_custom_fields.length; i++) {
if (data.vulnerability_custom_fields[i].key === 'cve') {
cve = data.vulnerability_custom_fields[i].value;
break;
}
}
}
if (!cve) {
return {
decision: {
status: 'finish',
message: 'No CVE found'
}
};
}
return {
data: {
cve: cve,
vuln: data
},
request: {
body: {
client_id: secrets.vulndb_client_id,
client_secret: secrets.vulndb_client_secret,
grant_type: 'client_credentials'
}
}
};let body;
if (response.headers['Content-Type'] === 'application/json; charset=utf-8') {
body = JSON.parse(response.body);
}
else {
return {
decision: {
status: 'abort',
message: 'Content-Type is expected to be application/json; charset=utf-8'
}
};
}
if (body?.access_token) {
return {
data: {
vulnDBToken: body.access_token,
cve: data?.cve,
vuln: data?.vuln
}
};
}
else {
return {
decision: {
status: 'abort',
cause: 'VulnDB access token not found'
}
};
}if (data?.vulnDBToken && data?.cve && data?.vuln) {
return {
data: {
cve: data.cve,
vuln: data.vuln
},
request: {
url: 'https://vulndb.flashpoint.io/api/v2/vulnerabilities/' + data.cve + '/find_by_cve_id',
headers: {
Authorization: 'Bearer ' + data.vulnDBToken
}
}
};
}
else {
return {
decision: {
status: 'abort',
message: 'VulnDB access token not found'
}
};
}let body;
if (response.headers['Content-Type'] === 'application/json; charset=utf-8') {
body = JSON.parse(response.body);
}
else {
return {
decision: {
status: 'abort',
message: 'Content-Type is expected to be application/json; charset=utf-8'
}
};
}
if (!body?.results?[0]) {
return {
decision: {
status: 'abort',
message: 'VulnDB CVE not found'
}
};
}
return {
data: {
cve: data?.cve,
vulnDB: body.results[0],
vuln: data?.vuln
}
};if (data?.vuln && data?.vulnDB) {
const score = calculateScore(data.vuln, data.vulnDB);
const priority = convertScoreToPriority(score);
return {
request: {
url: 'https://demo.attackforge.dev/api/ss/vulnerability/' + data.vuln.vulnerability_id,
body: {
priority: priority,
custom_fields: [
{
key: 'threat_score',
value: JSON.stringify(score)
}
]
}
}
};
}
else {
return {
decision: {
status: 'abort',
message: 'Missing required vuln data'
}
};
}
function calculateScore(vuln, vdb) {
let score = 0;
// Maximum score = 140
// Higher the score = Higher Priority to fix!
// [ THREAT CONTEXT ]
const internetFacing = isInternetFacing(vuln);
// Is the threat related to exposed/internet-facing services?
if (internetFacing) {
score += 10;
}
if (vdb.cvss_version_three_metrics) {
for (let i = 0; i < vdb.cvss_version_three_metrics.length; i++) {
const metrics = vdb.cvss_version_three_metrics[i];
// Is the CVSS score 8 or higher?
if (metrics.score !== undefined && metrics.score >= 8) {
score += 5;
}
// Is the threat easily exploitable?
if (metrics.attack_complexity === 'HIGH') {
score += 1;
}
else if (metrics.attack_complexity === 'MEDIUM') {
score += 5;
}
else if (metrics.attack_complexity === 'LOW') {
score += 10;
}
// No user interaction required?
if (metrics.user_interaction === 'NONE') {
if (isInternetFacing) {
score += 10;
}
else {
score += 5;
}
}
}
}
else if (vdb.cvss_metrics) {
for (let i = 0; i < vdb.cvss_metrics.length; i++) {
const metrics = vdb.cvss_metrics[i];
// Is the CVSS score 8 or higher?
if (metrics.score !== undefined && metrics.score >= 8) {
score += 5;
}
// Is the threat easily exploitable?
if (metrics.attack_complexity === 'HIGH') {
score += 1;
}
else if (metrics.attack_complexity === 'MEDIUM') {
score += 5;
}
else if (metrics.attack_complexity === 'LOW') {
score += 10;
}
}
}
if (vdb.classifications) {
for (let i = 0; i < vdb.classifications.length; i++) {
const classifications = vdb.classifications[i];
// Is there a public exploit available for this threat?
if (classifications.name === 'exploit_public') {
if (isInternetFacing) {
score += 10;
}
else {
score += 5;
}
}
// Does this threat require configuration changes?
else if (classifications.name === 'solution_workaround') {
score += 5;
}
// Does the threat grant unauthorized access?
else if (classifications.name === 'location_remote') {
if (isInternetFacing) {
score += 10;
}
else {
score += 5;
}
}
// Disclosure in the wild?
else if (classifications.name === 'disclosure_in_wild') {
score += 5;
}
else if (classifications.name === 'disclosure_uncoordinated_disclosure') {
score += 5;
}
// Wormable?
else if (classifications.name === 'exploit_wormified') {
if (isInternetFacing) {
score += 15;
}
else {
score += 10;
}
}
// Virus / Malware?
else if (classifications.name === 'exploit_virus_malware') {
if (isInternetFacing) {
score += 10;
}
else {
score += 5;
}
}
// PoC Public?
else if (classifications.name === 'exploit_poc_public') {
if (isInternetFacing) {
score += 15;
}
else {
score += 10;
}
}
}
}
// Is a patch available for this threat?
let patchExists = false;
if (vdb.classifications) {
for (let i = 0; i < vdb.classifications.length; i++) {
const classifications = vdb.classifications[i];
if (classifications.name === 'solution' || classifications.name === 'solution_upgrade') {
patchExists = true;
break;
}
}
}
else if (vdb.cvss_version_three_metrics) {
for (let i = 0; i < vdb.cvss_version_three_metrics.length; i++) {
const metrics = vdb.cvss_version_three_metrics[i];
if (metrics.remediation_level === 'OFFICIAL_FIX' || metrics.remediation_level === 'TEMPORARY_FIX') {
patchExists = true;
break;
}
}
}
if (!patchExists) {
score += 10;
}
// Social Risk Score (Vuln DB)
if (vdb.social_risk_score === 'High') {
score += 5;
}
else if (vdb.social_risk_score === 'Medium') {
score += 3;
}
else if (vdb.social_risk_score === 'Low') {
score += 1;
}
// What is the likelihood that this threat could be used in a ransomware attack?
if (vdb.ransomware_likelihood === 'High') {
if (isInternetFacing) {
score += score + 10;
}
else {
score += 5;
}
}
else if (vdb.ransomware_likelihood === 'Medium') {
if (isInternetFacing) {
score += 5;
}
else {
score += 3;
}
}
else if (vdb.ransomware_likelihood === 'Low') {
score += 1;
}
if (vdb.tags) {
for (let i = 0; i < vdb.tags.length; i++) {
// Is this a known CISA KEV vulnerability?
if (vdb.tags[i] === 'cisa_kev') {
score += 10;
break;
}
}
}
return score;
}
function convertScoreToPriority(score) {
if (score > 0 && score <= 30) {
return 'Low';
}
else if (score > 30 && score <= 70) {
return 'Medium';
}
else if (score > 70 && score <= 110) {
return 'High';
}
else if (score > 110 && score <= 140) {
return 'Critical';
}
else {
return 'Info';
}
}
function isInternetFacing(vuln) {
if (vuln.vulnerability_affected_assets) {
for (let i = 0; i < vuln.vulnerability_affected_assets.length; i++) {
if (vuln.vulnerability_affected_assets[i].asset?.custom_fields) {
const assetCustomFields = vuln.vulnerability_affected_assets[i].asset?.custom_fields;
for (let j = 0; j < assetCustomFields.length; j++) {
if (assetCustomFields[j].key === 'internet_facing' && assetCustomFields[j].value === 'Yes') {
return true;
}
}
}
}
}
return false;
}let body;
if (response.headers['Content-Type'] === 'application/json') {
body = JSON.parse(response.body);
}
else {
return {
decision: {
status: 'abort',
message: 'Content-Type is expected to be application/json'
}
};
}
if (response.statusCode === 200 && body?.result?.result === 'Vulnerability Updated') {
return {
decision: 'finish'
};
}
else {
Logger.error(JSON.stringify(response));
return {
decision: {
status: 'abort',
message: 'Vulnerability not updated'
}
};
}