Nist NVD

National Vulnerability Database.

Vulnerability Management · Nist NVD

Details

IDNist NVD
ProviderNIST
CategoryVulnerability Management
From Version6.0.0
Docker Imagedemisto/python3:3.12.12.5490952
Supported ModulesAgentix XSIAM

README

National Vulnerability Database

Configure Nist NVD in Cortex

Parameter Required
Nist NVD CVES URL False
Trust any certificate (not secure) False
Use system proxy settings False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

nvd-get-vulnerability


You can get latest vulnerabilities with given time from National Vulnerability Database.

Base Command

nvd-get-vulnerability

Input

Argument Name Description Required
time Get vulnerability within this time frame (in days - max range is 120 days). Example: time=30. Default is 30. Required
resultsPerPage Default: 20. Default is 20. Optional
startIndex Using for paging. Default: 0. Default is 0. Optional

Context Output

There is no context output for this command.

nvd-search-keyword


The keyword parameter allows your application to retrieve records where a word or phrase is found in the vulnerability description or reference links.

Base Command

nvd-search-keyword

Input

Argument Name Description Required
keyword Example: keyword=apple. Required
isExactMatch If the keyword is a phrase, i.e., contains more than one term, then the isExactMatch parameter may be used to influence the response. Use isExactMatch=true to retrieve records matching the exact phrase. Otherwise, the results contain any record having any of the terms. Possible values are: true, false. Default is true. Required
time Get vulnerability within this time frame (in days - max range is 120 days). Example: time=30. Default is 30. Optional
resultsPerPage Default: 20. Default is 20. Optional
startIndex Using for paging. Default: 0. Default is 0. Optional

Context Output

There is no context output for this command.

nvd-search-cvss


CVSS refers to the scoring system used by NIST to assess the severity of vulnerabilities, https://www.first.org/cvss/. NVD provides base scores using the CVSS version 2 and, more recently, version 3.x.

Base Command

nvd-search-cvss

Input

Argument Name Description Required
cvssType cvssV4, cvssV3 or cvssV2. Possible values are: cvssV2, csvsV3, cvssV4. Default is cvssV4. Required
key Search parameter that use with CVSS. Example: cvssV3Metrics | cvssV4Severity. Possible values are: Severity, Metrics. Default is Severity. Required
value Two pairs of parameters allow you to filter vulnerabilities based on CVSS base scores. Use either the cvssV2Severity or cvssV3Severity parameter to find vulnerabilities having a LOW, MEDIUM, or HIGH version 2 or 3.x score, respectively. For CVSS V3.x, cvssV3Severity=CRITICAL is also supported. Example: cvssV2Severity=HIGH | cvssV3Metrics=C:H/A:N | cvssV3Metrics=AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N. Required
time Get vulnerability within this time frame (in days - max range is 120 days). Example: time=30. Default is 30. Optional
resultsPerPage Default: 20. Default is 20. Optional
startIndex Using for paging. Default: 0. Default is 0. Optional

Context Output

There is no context output for this command.

nvd-search-cwe


CWE refers to the classification of vulnerabilities at https://cwe.mitre.org/. NIST staff associate one or more CWE to each vulnerability during the analysis process. In the following example, CWE-20 means vulnerabilities caused by Improper Input Validation. To filter search results based on CWE, use the cweId parameter. Example: cweId=CWE-20

Base Command

nvd-search-cwe

Input

Argument Name Description Required
cweId Example: cweId=CWE-20. Required
time Get vulnerability within this time frame (in days - max range is 120 days). Example: time=30. Default is 30. Optional
resultsPerPage Default: 20. Default is 20. Optional
startIndex Using for paging. Default: 0. Default is 0. Optional

Context Output

There is no context output for this command.

nvd-search-cpe


NVD analysts identify which product or products are affected by each vulnerability. The set of associated products is known as the applicability statement of the CVE. NVD uses the Common Platform Enumeration (CPE), version 2.3, to convey product vendors, names, versions, etc. For more information, see https://cpe.mitre.org/.

Base Command

nvd-search-cpe

Input

Argument Name Description Required
cpe Example: cpe:2.3:o:microsoft:windows_10 | cpe:2.3:o:microsoft:windows_10:1511 | cpe:2.3:*:microsoft. Required
time Get vulnerability within this time frame (in days - max range is 120 days). Example: time=30. Default is 30. Optional
resultsPerPage Default: 20. Default is 20. Optional
startIndex Using for paging. Default: 0. Default is 0. Optional

Context Output

There is no context output for this command.

nvd-search-cve


Search specific CVE

Base Command

nvd-search-cve

Input

Argument Name Description Required
cve CVEID. Example: CVE-2020-1000. Required

Context Output

There is no context output for this command.

Configuration parameters

  • url — Nist NVD CVES URL
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (6)

  • nvd-get-vulnerability

    You can get latest vulnerabilities with given time from National Vulnerability Database.

  • nvd-search-cpe

    NVD analysts identify which product or products are affected by each vulnerability. The set of associated products is known as the applicability statement of the CVE. NVD uses the Common Platform Enumeration (CPE), version 2.3, to convey product vendors, names, versions, etc. For more information, see https://cpe.mitre.org/.

  • nvd-search-cve

    Search specific CVE.

  • nvd-search-cvss

    CVSS refers to the scoring system used by NIST to assess the severity of vulnerabilities, https://www.first.org/cvss/. NVD provides base scores using the CVSS version 2 and, more recently, version 3.x.

  • nvd-search-cwe

    CWE refers to the classification of vulnerabilities at https://cwe.mitre.org/. NIST staff associate one or more CWE to each vulnerability during the analysis process. In the following example, CWE-20 means vulnerabilities caused by Improper Input Validation. To filter search results based on CWE, use the cweId parameter. Example: cweId=CWE-20.

  • nvd-search-keyword

    The keyword parameter allows your application to retrieve records where a word or phrase is found in the vulnerability description or reference links.

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401
import sys
from datetime import datetime, timedelta
import requests


VERIFY_SSL = not demisto.params().get("insecure", False)

if not demisto.params().get("proxy", False):
    handle_proxy()


def test_module() -> str:
    try:
        base_url = urljoin(demisto.params()["url"], "/rest/json/cves/2.0")
        headers = {"Accept": "application/json"}
        req = requests.get(base_url, headers=headers, verify=VERIFY_SSL)
        if req.status_code != 200:
            http_status = "HTTP status is" + str(req.status_code)
            return_error(http_status)
    except Exception as e:
        return_error(e)
    return "ok"


def connection(url, additional_parameters):
    headers = {"Accept": "application/json"}
    req = requests.get(url, headers=headers, params=additional_parameters, verify=VERIFY_SSL)
    if req.status_code != 200:
        return_results(req.content)
        sys.exit(1)
    else:
        return req.json()


# Process of extraction vulnerability details in the NVD
def extractVulnDetails(requestfromconnection):
    req = requestfromconnection
    pretty_list = []  # list()

    def get_value_from_hierarchy(mapping, key_chain):
        """Retrieve value from a nested dictionary based on a dot-separated key chain."""
        keys = key_chain.split(".")
        value = mapping
        for key in keys:
            if key in value:
                value = value[key]
            else:
                return None
        return value

    key_locations = {
        "CVSS Attack Vector": ["cvssData.attackVector", "cvssData.accessVector", "attackVector"],
        "CVSS Attack Complexity": ["cvssData.attackComplexity", "cvssData.accessComplexity", "attackComplexity"],
        "CVSS Base Score": ["cvssData.baseScore", "baseScore"],
        "CVSS Base Severity": ["cvssData.baseSeverity", "baseSeverity"],
        "Exploitability Score": ["cvssData.exploitabilityScore", "exploitabilityScore"],
        "Impact Score": ["cvssData.impactScore", "impactScore"],
        "CVSS Version": ["cvssData.version", "version"],
        "CVSS Vector String": ["cvssData.vectorString", "vectorString"],
        "CVSS Privileges Required": ["cvssData.privilegesRequired", "obtainAllPrivilege"],
        "CVSS User Interaction": ["cvssData.userInteraction", "userInteractionRequired"],
        "CVSS Scope": ["cvssData.scope"],
        "CVSS Confidentiality Impact": ["cvssData.confidentialityImpact", "confidentialityImpact"],
        "CVSS Integrity Impact": ["cvssData.integrityImpact", "integrityImpact"],
        "CVSS Availability Impact": ["cvssData.availabilityImpact", "availabilityImpact"],
    }

    if "vulns" not in req:
        for i in req["vulnerabilities"]:
            pretty_dict = {}
            pretty_dict["CVE ID"] = i["cve"]["id"]
            pretty_dict["Published Date"] = i["cve"]["published"]
            pretty_dict["Last Modified Date"] = i["cve"]["lastModified"]
            description = []
            for k in i["cve"]["descriptions"]:
                description.append(k["value"])
            pretty_dict["Description"] = description
            reference_data = []
            for j in i["cve"]["references"]:
                reference_data.append(j["url"])
            pretty_dict["References"] = reference_data
            pretty_dict["Vulnerability Status"] = i["cve"]["vulnStatus"]

            if "metrics" in list(i["cve"].keys()):
                cvssmetricslist = []

                for _cvssmetrickey, cvssmetric in i["cve"]["metrics"].items():
                    cvssmetricsdict = {}
                    cvssmetric = cvssmetric[0]

                    for key, locations in key_locations.items():
                        cvssmetricsdict[key] = next(
                            (
                                get_value_from_hierarchy(cvssmetric, loc)
                                for loc in locations
                                if get_value_from_hierarchy(cvssmetric, loc) is not None
                            ),
                            None,
                        )
                    cvssmetricslist.append(cvssmetricsdict)

            pretty_dict["metrics"] = cvssmetricslist
            pretty_list.append(pretty_dict)
    elif ("vulns") in req and (not len(req["vulns"])):
        demisto.results("Vendor name may be wrong or no CPE added")

    if (("result") in req) and (not len(req["result"]["CVE_Items"])):
        demisto.results("There were no vulnerability in the criteria you were looking for.")
    return pretty_list


def generalSearch():
    base_url = urljoin(demisto.params()["url"], "/rest/json/cves/2.0")
    time = int(demisto.args().get("time"))
    last_time = datetime.today() - timedelta(days=int(time))
    start_date = last_time.strftime("%Y-%m-%dT%H:%M:%S.000")
    end_date = datetime.today().strftime("%Y-%m-%dT%H:%M:%S.000")
    startIndex = demisto.args().get("startIndex")
    resultsPerPage = demisto.args().get("resultsPerPage")
    additional_parameters = {
        "lastModStartDate": f"{start_date}+00:00",
        "lastModEndDate": f"{end_date}+00:00",
        "startIndex": f"{startIndex}",
        "resultsPerPage": f"{resultsPerPage}",
    }

    generalSearchRequest = connection(base_url, additional_parameters)
    generalVulnerabilityList = extractVulnDetails(generalSearchRequest)

    headers = ["CVE ID", "Description", "Published Date", "Last Modified Date", "References"]
    markdown = "General Search\n"
    markdown += tableToMarkdown("Vulnerabilities", generalVulnerabilityList, headers=headers, removeNull=True)

    results = CommandResults(
        readable_output=markdown,
        outputs_prefix="NistNVD.GeneralSearch",
        outputs_key_field="CVE ID",
        outputs=generalVulnerabilityList,
    )

    return_results(results)


def keywordSearch():
    base_url = urljoin(demisto.params()["url"], "/rest/json/cves/2.0")
    keyword = demisto.args().get("keyword")
    isExactMatch = argToBoolean(demisto.args().get("isExactMatch"))
    time = int(demisto.args().get("time"))
    last_time = datetime.today() - timedelta(days=int(time))
    start_date = last_time.strftime("%Y-%m-%dT%H:%M:%S%z")
    end_date = datetime.today().strftime("%Y-%m-%dT%H:%M:%S.000")
    startIndex = demisto.args().get("startIndex")
    resultsPerPage = demisto.args().get("resultsPerPage")
    additional_parameters = {
        "lastModStartDate": f"{start_date}+00:00",
        "lastModEndDate": f"{end_date}+00:00",
        "keywordSearch": keyword,
        "startIndex": f"{startIndex}",
        "resultsPerPage": f"{resultsPerPage}",
    }
    if isExactMatch:
        additional_parameters["keywordExactMatch"] = None
        additional_parameters = "&".join([k if v is None else f"{k}={v}" for k, v in additional_parameters.items()])  # type: ignore
    generalSearchRequest = connection(base_url, additional_parameters)
    generalVulnerabilityList = extractVulnDetails(generalSearchRequest)

    headers = ["CVE ID", "Description", "Published Date", "Last Modified Date", "References"]
    markdown = "Keyword Search\n"
    markdown += tableToMarkdown("Vulnerabilities", generalVulnerabilityList, headers=headers, removeNull=True)

    results = CommandResults(
        readable_output=markdown,
        outputs_prefix="NistNVD.KeywordSearch",
        outputs_key_field="CVE ID",
        outputs=generalVulnerabilityList,
    )

    return_results(results)


def cvssSearch():
    base_url = urljoin(demisto.params()["url"], "/rest/json/cves/2.0")
    time = int(demisto.args().get("time"))
    last_time = datetime.today() - timedelta(days=int(time))
    start_date = last_time.strftime("%Y-%m-%dT%H:%M:%S.000")
    end_date = datetime.today().strftime("%Y-%m-%dT%H:%M:%S.000")

    cvssType = demisto.args().get("cvssType")
    key = demisto.args().get("key")
    searchParameters = cvssType + key
    value = demisto.args().get("value")

    startIndex = demisto.args().get("startIndex")
    resultsPerPage = demisto.args().get("resultsPerPage")

    additional_parameters = {
        "lastModStartDate": f"{start_date}+00:00",
        "lastModEndDate": f"{end_date}+00:00",
        f"{searchParameters}": f"{value}",
        "startIndex": f"{startIndex}",
        "resultsPerPage": f"{resultsPerPage}",
    }
    generalSearchRequest = connection(base_url, additional_parameters)
    generalVulnerabilityList = extractVulnDetails(generalSearchRequest)

    headers = ["CVE ID", "Description", "Published Date", "Last Modified Date", "References"]
    markdown = "CVSS Search\n"
    markdown += tableToMarkdown("Vulnerabilities", generalVulnerabilityList, headers=headers, removeNull=True)

    results = CommandResults(
        readable_output=markdown,
        outputs_prefix="NistNVD.CVSSSearch",
        outputs_key_field="CVE ID",
        outputs=generalVulnerabilityList,
    )

    return_results(results)


def cweSearch():
    base_url = urljoin(demisto.params()["url"], "/rest/json/cves/2.0")
    time = int(demisto.args().get("time"))
    last_time = datetime.today() - timedelta(days=int(time))
    start_date = last_time.strftime("%Y-%m-%dT%H:%M:%S.000")
    end_date = datetime.today().strftime("%Y-%m-%dT%H:%M:%S.000")

    cweId = demisto.args().get("cweId")
    startIndex = demisto.args().get("startIndex")
    resultsPerPage = demisto.args().get("resultsPerPage")

    additional_parameters = {
        "lastModStartDate": f"{start_date}+00:00",
        "lastModEndDate": f"{end_date}+00:00",
        "cweId": f"{cweId}",
        "startIndex": f"{startIndex}",
        "resultsPerPage": f"{resultsPerPage}",
    }
    generalSearchRequest = connection(base_url, additional_parameters)
    generalVulnerabilityList = extractVulnDetails(generalSearchRequest)

    headers = ["CVE ID", "Description", "Published Date", "Last Modified Date", "References"]
    markdown = "CWE Search\n"
    markdown += tableToMarkdown("Vulnerabilities", generalVulnerabilityList, headers=headers, removeNull=True)

    results = CommandResults(
        readable_output=markdown, outputs_prefix="NistNVD.CWESearch", outputs_key_field="CVE ID", outputs=generalVulnerabilityList
    )

    return_results(results)


def cpeSearch():
    base_url = urljoin(demisto.params()["url"], "/rest/json/cves/2.0")
    time = int(demisto.args().get("time"))
    last_time = datetime.today() - timedelta(days=int(time))
    start_date = last_time.strftime("%Y-%m-%dT%H:%M:%S.000")
    end_date = datetime.today().strftime("%Y-%m-%dT%H:%M:%S.000")

    cpeName = demisto.args().get("cpe")
    startIndex = demisto.args().get("startIndex")
    resultsPerPage = demisto.args().get("resultsPerPage")

    additional_parameters = {
        "lastModStartDate": f"{start_date}+00:00",
        "lastModEndDate": f"{end_date}+00:00",
        "cpeName": f"{cpeName}",
        "startIndex": f"{str(startIndex)}",
        "resultsPerPage": f"{str(resultsPerPage)}",
    }
    generalSearchRequest = connection(base_url, additional_parameters)
    generalVulnerabilityList = extractVulnDetails(generalSearchRequest)

    headers = ["CVE ID", "Description", "Published Date", "Last Modified Date", "References"]
    markdown = "CPE Search\n"
    markdown += tableToMarkdown("Vulnerabilities", generalVulnerabilityList, headers=headers, removeNull=True)

    results = CommandResults(
        readable_output=markdown, outputs_prefix="NistNVD.CPESearch", outputs_key_field="CVE ID", outputs=generalVulnerabilityList
    )

    return_results(results)


def cveSearch():
    base_url = urljoin(demisto.params()["url"], "/rest/json/cves/2.0/")
    cve = demisto.args().get("cve")

    additional_parameters = {"cveId": cve}
    generalSearchRequest = connection(base_url, additional_parameters)
    generalVulnerabilityList = extractVulnDetails(generalSearchRequest)
    headers = [
        "CVE ID",
        "Description",
        "Published Date",
        "Last Modified Date",
        "References",
        "CVSS Base Score",
        "CVSS Base Severity",
        "Exploitability Score",
        "Impact Score",
        "CVSS Version",
        "CVSS Vector String",
        "CVSS Attack Vector",
        "CVSS Attack Complexity",
        "CVSS Privileges Required",
        "CVSS User Interaction",
        "CVSS Scope",
        "CVSS Confidentiality Impact",
        "CVSS Integrity Impact",
        "CVSS Availability Impact",
        "Vulnerability Status",
    ]
    markdown = "CVE Search\n"
    markdown += tableToMarkdown("Vulnerabilities", generalVulnerabilityList, headers=headers, removeNull=True)

    results = CommandResults(
        readable_output=markdown, outputs_prefix="NistNVD.CVESearch", outputs_key_field="CVE ID", outputs=generalVulnerabilityList
    )

    return_results(results)


def main() -> None:
    """main function, parses params and runs command functions
    :return:
    :rtype:
    """
    """ EXECUTION """
    demisto.debug(f"Command being called is {demisto.command()}")

    """ EXECUTION """
    demisto.info(f"command is {demisto.command()}")
    try:
        if demisto.command() == "test-module":
            demisto.results(test_module())
        elif demisto.command() == "nvd-get-vulnerability":
            generalSearch()
        elif demisto.command() == "nvd-search-keyword":
            keywordSearch()
        elif demisto.command() == "nvd-search-cvss":
            cvssSearch()
        elif demisto.command() == "nvd-search-cwe":
            cweSearch()
        elif demisto.command() == "nvd-search-cpe":
            cpeSearch()
        elif demisto.command() == "nvd-search-cve":
            cveSearch()
    # Log exceptions and return errors
    except Exception as e:
        demisto.error(traceback.format_exc())  # print the traceback
        return_error(f"Failed to execute {demisto.command()} command.\nError:\n{str(e)}")


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()