# Flashpoint (VulnDB)

## Prioritize Vulnerability with Threat Intelligence from VulnDB

{% embed url="<https://youtu.be/onvSZShtEB4?si=yNulV32SL5qczdR>\_" %}

The purpose of this example is to prioritize a vulnerability based on threat intelligence information harnessed from [FlashPoint VulnDB](https://flashpoint.io/ignite/vulnerability-intelligence/) and to apply a custom score/rating to the vulnerability.

This example Flow can be downloaded from our [Flows GitHub Repository](https://github.com/AttackForge/Flows) and [imported](#importing-exporting-flows) into your AttackForge.

**Initial Set Up**

> **Important**: This example requires access to the AttackForge Self-Service API and AttackForge Flows

* **Event**: Vulnerability Created
* **Secrets**:
  * af\_auth - your [AttackForge Self-Service API token](https://support.attackforge.com/attackforge-enterprise/modules/self-service-restful-api/getting-started#accessing-the-restful-api).
  * vulndb\_client\_id - your VulnDB Client Id
  * vulndb\_client\_secret - your VulnDB Client Secret

**Action 1 - Get VulnDB OAuth Token**&#x20;

* **Method**: POST
* **URL**: <https://vulndb.flashpoint.io/oauth/token>
* **Headers**:
  * Key = Content-Type; Type = Value; Value = application/json
* **Request Script**:

```javascript
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'
    }
  }
};
```

* **Response Script**:

```javascript
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'
    }
  };
}
```

**Action 2 - Get Threat Intel for Vuln from VulnDB**

* **Method**: \<defined in Request Script>
* **URL**: \<defined in Request Script>
* **Headers**:
  * Key = Content-Type; Type = Value; Value = application/json
  * \<others defined in Request Script>
* **Request Script**:

```javascript
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'
    }
  };
}
```

* **Response Script**:

```javascript
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
  } 
};
```

**Action 3 - Apply Threat Intel, Prioritize Vulnerability and Update Vulnerability**

* **Method**: \<defined in Request Script>
* **URL**: \<defined in Request Script>
* **Headers**:
  * Key = Content-Type; Type = Value; Value = application/json
  * Key = X-SSAPI-KEY; Type = Secret; Value = af\_auth
* **Request Script**:

```javascript
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;
}
```

* **Response Script**:

```javascript
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'
    }
  };
}
```
