Patterns inside cve2stix Indicator objects

I see Indicator objects from cve2stix look like this

        {
            "type": "indicator",
            "spec_version": "2.1",
            "id": "indicator--f217749b-dded-56f3-b2be-9ad6ea3f9e47",
            "created_by_ref": "identity--562918ee-d5da-5579-b6a1-fae50cc6bad3",
            "created": "2017-12-11T17:29:00.270Z",
            "modified": "2022-01-24T16:46:02.897Z",
            "name": "CVE-2015-8470",
            "description": "The console in Puppet Enterprise 3.7.x, 3.8.x, and 2015.2.x does not set the secure flag for the JSESSIONID cookie in an HTTPS session, which makes it easier for remote attackers to capture this cookie by intercepting its transmission within an HTTP session.",
            "indicator_types": [
                "compromised"
            ],
            "pattern": "([software:cpe='cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:*' OR software:cpe='cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:*' OR software:cpe='cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:*'])",
            "pattern_type": "stix",
            "pattern_version": "2.1",
            "valid_from": "2017-12-11T17:29:00.27Z",
            "external_references": [
                {
                    "source_name": "cve",
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2015-8470",
                    "external_id": "CVE-2015-8470"
                }
            ],
            "object_marking_refs": [
                "marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
                "marking-definition--562918ee-d5da-5579-b6a1-fae50cc6bad3"
            ],
            "extensions": {
                "extension-definition--ad995824-2901-5f6e-890b-561130a239d4": {
                    "extension_type": "toplevel-property-extension"
                }
            },
            "x_cpes": {
                "not_vulnerable": [],
                "vulnerable": [
                    {
                        "criteria": "cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:*",
                        "matchCriteriaId": "E3C0546D-3FF4-461A-B6C4-3C1586DFA79E"
                    },
                    {
                        "criteria": "cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:*",
                        "matchCriteriaId": "6F08C767-D814-4026-9895-36EF1E4B2F78"
                    },
                    {
                        "criteria": "cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:*",
                        "matchCriteriaId": "4E6676D2-5545-456E-A10D-7AE7B75B6A63"
                    }
                ]
            }
        },

So I interpret the above pattern as:

cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:* OR cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:* OR cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:*

All of which are vulnerable.

But all the CPEs listed here are the same. so what is going on here?

The matchCriteriaId is the vital part you’re missing

                    {
                        "criteria": "cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:*",
                        "matchCriteriaId": "E3C0546D-3FF4-461A-B6C4-3C1586DFA79E"
                    },

Using the CPE Match endpoint, you can get the full list of CPEs this match string covers…

e.g.

curl --location 'https://services.nvd.nist.gov/rest/json/cpematch/2.0?matchCriteriaId=E3C0546D-3FF4-461A-B6C4-3C1586DFA79E \
{
    "resultsPerPage": 1,
    "startIndex": 0,
    "totalResults": 1,
    "format": "NVD_CPEMatchString",
    "version": "2.0",
    "timestamp": "2024-03-12T11:31:58.800",
    "matchStrings": [
        {
            "matchString": {
                "matchCriteriaId": "E3C0546D-3FF4-461A-B6C4-3C1586DFA79E",
                "criteria": "cpe:2.3:a:puppet:puppet_enterprise:*:*:*:*:*:*:*:*",
                "versionStartIncluding": "3.7.0",
                "versionEndIncluding": "3.7.2",
                "lastModified": "2022-01-24T16:44:41.490",
                "cpeLastModified": "2022-01-24T16:46:02.407",
                "created": "2022-01-24T16:44:41.490",
                "status": "Active",
                "matches": [
                    {
                        "cpeName": "cpe:2.3:a:puppet:puppet_enterprise:3.7.0:*:*:*:*:*:*:*",
                        "cpeNameId": "4E472B67-1448-441D-A087-98B2D483FA6E"
                    },
                    {
                        "cpeName": "cpe:2.3:a:puppet:puppet_enterprise:3.7.1:*:*:*:*:*:*:*",
                        "cpeNameId": "8269ACF0-16F6-4DD3-89CC-EAD75F0BE9DB"
                    },
                    {
                        "cpeName": "cpe:2.3:a:puppet:puppet_enterprise:3.7.2:*:*:*:*:*:*:*",
                        "cpeNameId": "AB3321EF-2518-4148-A88F-8A8EAFC490CF"
                    }
                ]
            }
        }
    ]
}

The matches property lists all the CPEs match the version range.

In this case those are:

  • cpe:2.3:a:puppet:puppet_enterprise:3.7.0:*:*:*:*:*:*:*
  • cpe:2.3:a:puppet:puppet_enterprise:3.7.1:*:*:*:*:*:*:*
  • cpe:2.3:a:puppet:puppet_enterprise:3.7.2:*:*:*:*:*:*:*

We made a conscious choice not to include all the CPEs in the Indicator object b/c in some cases 100’s are returned, making the STIX object huge.

Arango CTI Processor will actually do this lookup process for you, and link the Indicator to the corresponding CPE objects that are shown by the Match Criteria API.

Run it in cve-cpe mode. e.g.

python3 arango_cti_processor.py \
    --database DATABASE \
    --relationship cve-cpe \
    --ignore_embedded_relationships BOOLEAN \
    --stix2arango_note STRING