QintelPMI

Qintel’s Patch Management Intelligence (PMI) product simplifies the vulnerability management process by providing vital context around reported Common Vulnerabilities and Exposures. With this integration, users can query PMI to surface CVEs that are known by Qintel to be leveraged by eCrime and Nation State adversaries.

Data Enrichment & Threat Intelligence · Qintel

Details

IDQintelPMI
ProviderQintel
CategoryData Enrichment & Threat Intelligence
From Version6.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Qintel’s Patch Management Intelligence (PMI) product simplifies the vulnerability management process by providing vital context around reported Common Vulnerabilities and Exposures. With this integration, users can query PMI to surface CVEs that are known by Qintel to be leveraged by eCrime and Nation State adversaries.
This integration was integrated and tested with version 0.16.0 of PMI

Configure QintelPMI in Cortex

Parameter Required
PMI API URL (optional) False
Qintel Credentials True
Password True
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.

cve


Queries Qintel for CVE intelligence

Base Command

cve

Input

Argument Name Description Required
cve List of CVEs. Required

Context Output

Path Type Description
CVE.ID String The ID of the CVE, for example: CVE-2015-1653
CVE.CVSS String The CVSS of the CVE, for example: 10.0
CVE.Published Date The timestamp of when the CVE was published.
CVE.Modified Date The timestamp of when the CVE was last modified.
CVE.Description String A description of the CVE.
Qintel.CVE.ID string The ID of the CVE
Qintel.CVE.AffectedSystem string Systems affected by the CVE
Qintel.CVE.AffectedVersions string Systems affected by the CVE
Qintel.CVE.LastObserved string Last threat actor observation time
Qintel.CVE.Observations array List of observations
DBotScore.Indicator String The indicator that was tested.
DBotScore.Score Number The actual score.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.

Command Example

!cve cve=CVE-2021-0123

Context Example

{
    "CVE": {
        "CVSS": "None",
        "Description": "None",
        "ID": "CVE-2021-0123",
        "Modified": "None",
        "Published": "None"
    },
    "DBotScore": {
        "Indicator": "CVE-2021-0123",
        "Score": 0,
        "Type": "cve",
        "Vendor": null
    },
    "Qintel": {
        "CVE": {
            "AffectedSystem": "Example System",
            "AffectedVersions": "1.0, 1.1",
            "LastObserved": "2021-04-20 04:00:00",
            "Observations": [
                {
                    "actor": "Unattributed Threat Actor",
                    "actor_type": "other",
                    "date_observed": "2021-04-20 04:00:00",
                    "exploit_notes": null,
                    "exploit_type": "cve"
                }
            ],
            "id": "CVE-2021-0123"
        }
    }
}

Human Readable Output

Qintel vulnerability results for: CVE-2021-0123

Vulnerability in Example System affecting versions: 1.0, 1.1
Last observed: 2021-04-20 04:00:00

actor actor_type exploit_type exploit_notes date_observed
Unattributed Threat Actor other cve   2021-04-20 04:00:00

Configuration parameters

  • remote — PMI API URL (optional)
  • credentials — Qintel Credentials (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (1)

  • cve

    Queries Qintel for CVE intelligence.

"""Qintel PMI Integration for Cortex XSOAR - Unit Tests file"""

import json

MOCK_URL = "https://this-is-only-a-test.local"
MOCK_CLIENT_ID = "client-id"
MOCK_CLIENT_SECRET = "client-secret"


def util_load_json(path):
    with open(path, encoding="utf-8") as f:
        return json.loads(f.read())


def test_make_timestamp():
    from datetime import datetime

    from QintelPMI import _make_timestamp

    res = _make_timestamp(None)
    assert res is None

    res = _make_timestamp(1626211855)
    assert isinstance(res, datetime)
    assert res.isoformat() == "2021-07-13T21:30:55"

    res = _make_timestamp("2021-07-13T21:30:55")
    assert isinstance(res, datetime)
    assert int(res.timestamp()) == 1626211855


def test_test_module(mocker):
    """Tests cve reputation command function with valid response.

    Checks the output of the command function with the expected output.
    """

    from QintelPMI import Client, test_module

    client = Client(base_url=MOCK_URL, verify=False, client_id=MOCK_CLIENT_ID, client_secret=MOCK_CLIENT_SECRET)

    mock_response = util_load_json("test_data/test_module.json")
    mocker.patch.object(Client, "_http_request", return_value=mock_response)

    response = test_module(client)

    assert response == "ok"


def test_cve_command(mocker):
    """Tests cve reputation command function with valid response.

    Checks the output of the command function with the expected output.
    """

    from QintelPMI import Client, cve_command

    client = Client(base_url=MOCK_URL, verify=False, client_id=MOCK_CLIENT_ID, client_secret=MOCK_CLIENT_SECRET)

    mock_response = util_load_json("test_data/cve_command.json")
    mocker.patch.object(Client, "_http_request", return_value=mock_response)

    args = {"cve": "CVE-2021-0123"}

    response = cve_command(client, **args)

    assert len(response) == 1

    outputs = response[0].outputs
    hr = response[0].readable_output
    prefix = response[0].outputs_prefix

    assert prefix == "Qintel.CVE"

    assert "Qintel vulnerability results for: CVE-2021-0123" in hr
    assert "Vulnerability in Example System affecting versions: 1.0, 1.1" in hr
    assert "Last observed: 2021-07-13 09:31:09" in hr
    assert "|actor|actor_type|exploit_type|exploit_notes|date_observed|" in hr
    assert "| Unattributed Threat Actor | other | cve |  | 2021-07-13 09:31:09 |" in hr

    assert outputs["id"] == "CVE-2021-0123"
    assert outputs["AffectedSystem"] == "Example System"
    assert outputs["AffectedVersions"] == "1.0, 1.1"
    assert outputs["LastObserved"] == "2021-07-13 09:31:09"
    assert len(outputs["Observations"]) == 1
    assert outputs["Observations"][0]["actor"] == "Unattributed Threat Actor"
    assert outputs["Observations"][0]["actor_type"] == "other"
    assert outputs["Observations"][0]["exploit_type"] == "cve"
    assert outputs["Observations"][0]["exploit_notes"] is None
    assert outputs["Observations"][0]["date_observed"] == "2021-07-13 09:31:09"


def test_cve_command_empty(mocker):
    """Tests cve reputation command function with empty response.

    Checks the output of the command function with the expected output.
    """
    from QintelPMI import Client, cve_command

    client = Client(base_url=MOCK_URL, verify=False, client_id=MOCK_CLIENT_ID, client_secret=MOCK_CLIENT_SECRET)

    mock_response = util_load_json("test_data/cve_command_empty.json")
    mocker.patch.object(Client, "_http_request", return_value=mock_response)

    args = {"cve": "CVE-2021-0123"}

    response = cve_command(client, **args)

    assert len(response) == 1

    outputs = response[0].outputs
    hr = response[0].readable_output
    prefix = response[0].outputs_prefix

    assert prefix is None

    assert "Qintel vulnerability results for: CVE-2021-0123" in hr
    assert "Vulnerability in" not in hr
    assert "Last observed:" not in hr
    assert "|actor|actor_type|exploit_type|exploit_notes|date_observed|" not in hr

    assert outputs is None