Posted by:

David Greenwood

David Greenwood, Chief of Signal

If you are reading this blog post via a 3rd party source it is very likely that many parts of it will not render correctly. Please view the post on signalscorps.com for the full interactive viewing experience.

In this post I will show you how to use STIX 2.1 SDOs, SCOs, and SROs to standardised the way vulnerabilities are represented.

Note: Vulmatch is an ever evolving product therefore the concepts described in this post might not always be relevant for the latest version.

Recapping what I have covered in the previous two posts, Vulmatch contains;

  • NVD CPE records
  • NVD CVE records (including CPE configurations)
  • Vulmatch user specific CPE configurations

One of the main design elements of the Vulmatch design was the ability to integrate data with other products. STIX 2.1 was what I settled on, becoming an increasingly popular standard in the world of cyber threat intelligence.

I will not cover STIX 2.1 concepts in the post. If you are new to STIX, check out my tutorial on the subject from last year.

CVEs as STIX 2.1 Objects

STIX 2.1 contains a Vulnerability SDO, here is the specification for it. In short, it is designed for modelling vulnerabilities, so I will use it for just that.

Below you can see the fields from the CVE that are mapped to the Vulnerability Object Properties;

    {
      "type": "vulnerability",
      "spec_version": "2.1",
      "id": "vulnerability--<GENERATED BY STIX2 LIBRARY>",
      "created_by_ref": "identity--<SIGNALS CORPS IDENTITY ID>",
      "created": "<CVE_Items.publishedDate>",
      "modified": "<CVE_Items.lastModifiedDate>",
      "name": "<CVE_Items.cve.CVE_data_meta.ID>",
      "description": "<CVE_Items.cve.description.description_data.value>",
      "external_references": [
        {
          "source_name": "cve",
          "external_id": "<CVE_Items.cve.CVE_data_meta.ID>"
        },
        {
          "source_name": "cwe",
          "external_id": "<CVE_Items.cve.problemtype.problemtype_data.description.value[n]>"
        },
        { 
          "source_name": "<CVE_Items.cve.references.reference_data.name.[n]>",
          "source": "<CVE_Items.references.reference_data.refsource.[n]>",
          "url": "<CVE_Items.references.reference_data.url.[n]>",
          "tags": [
              "<CVE_Items.references.reference_data.tags.[n]>"
          ]
        },
        {
          "source_name": "vulmatch",
          "url": "https://app.vulmatch.com/cve/<CVE_Items.cve.CVE_data_meta.ID>"
        },
      ],
      "x_nvd_impact": [
          {
            "x_baseMetricV3": {
                "x_cvssV3": {
                    "x_version": "<CVE_Items.impact.baseMetricV3.cvssV3.version>",
                    "x_vectorString": "<CVE_Items.impact.baseMetricV3.cvssV3.vectorString>",
                    "x_attackVector": "<CVE_Items.impact.baseMetricV3.cvssV3.attackVector>",
                    "x_attackComplexity": "<CVE_Items.impact.baseMetricV3.cvssV3.attackComplexity>",
                    "x_privilegesRequired": "<CVE_Items.impact.baseMetricV3.cvssV3.privilegesRequired>",
                    "x_userInteraction": "<CVE_Items.impact.baseMetricV3.cvssV3.userInteraction>",
                    "x_scope": "<CVE_Items.impact.baseMetricV3.cvssV3.scope>",
                    "x_confidentialityImpact": "<CVE_Items.impact.baseMetricV3.cvssV3.confidentialityImpact>",
                    "x_integrityImpact": "<CVE_Items.impact.baseMetricV3.cvssV3.integrityImpact>",
                    "x_availabilityImpact": "<CVE_Items.impact.baseMetricV3.cvssV3.availabilityImpact>",
                    "x_baseScore": "<CVE_Items.impact.baseMetricV3.cvssV3.baseScore>",
                    "x_baseSeverity": "<CVE_Items.impact.baseMetricV3.cvssV3.baseSeverity>"
                },
                "x_exploitabilityScore": "<CVE_Items.impact.baseMetricV3.exploitabilityScore>",
                "x_impactScore": "<CVE_Items.impact.baseMetricV3.impactScore>"
            },
            "x_baseMetricV2": {
                "x_cvssV2": {
                    "x_version": "<CVE_Items.impact.baseMetricV2.cvssV2.version>",
                    "x_vectorString": "<CVE_Items.impact.baseMetricV2.cvssV2.vectorString>",
                    "x_accessVector": "<CVE_Items.impact.baseMetricV2.cvssV2.accessVector>",
                    "x_accessComplexity": "<CVE_Items.impact.baseMetricV2.cvssV2.accessComplexity>",
                    "x_authentication": "<CVE_Items.impact.baseMetricV2.cvssV2.authentication>",
                    "x_confidentialityImpact": "<CVE_Items.impact.baseMetricV2.cvssV2.confidentialityImpact>",
                    "x_integrityImpact": "<CVE_Items.impact.baseMetricV2.cvssV2.integrityImpact>",
                    "x_availabilityImpact": "<CVE_Items.impact.baseMetricV2.cvssV2.availabilityImpact>",
                    "x_baseScore": "<CVE_Items.impact.baseMetricV2.cvssV2.baseScore>"
              },
                "x_severity": "<CVE_Items.impact.baseMetricV2.severity>",
                "x_exploitabilityScore": "<CVE_Items.impact.baseMetricV2.exploitabilityScore>",
                "x_impactScore": "<CVE_Items.impact.baseMetricV2.impactScore>",
                "x_acInsufInfo": "<CVE_Items.impact.baseMetricV2.acInsufInfo>",
                "x_obtainAllPrivilege": "<CVE_Items.impact.baseMetricV2.obtainAllPrivilege>",
                "x_obtainUserPrivilege": "<CVE_Items.impact.baseMetricV2.obtainUserPrivilege>",
                "x_obtainOtherPrivilege": "<CVE_Items.impact.baseMetricV2.obtainOtherPrivilege>",
                "x_userInteractionRequired": "<CVE_Items.impact.baseMetricV2.userInteractionRequired>"
            }
          }
        ],
       "x_nvd_configurations": 
         {
          "x_nodes": [
            {
              "x_operator": "<CVE_Items.configurations.node.operator>",
              "x_children": "<CVE_Items.configurations.node.children[]}",
              "x_cpe_match": "<CVE_Items.configurations.node.children[]}"
            }
          ]
        }    
      }

The CVE metadata and references in the response are mapped directly to the default properties of the STIX 2.1 Vulnerability Object.

You can see the use of many custom Properties used for the impact and configurations fields in the CVE (denoted by x_nvd_ at the top level, and x_ prefix for nested custom properties below) as they do not naturally map to any other STIX Object or Properties.

The configurations section is the critical part of the CVE for matching to a users software.

These configurations are indicators of potential malicious activities. Whilst we include the raw CPE configurations data in the CVE Object (which defines what CPE is actually vulnerable), to better represent this data Vulmatch also uses the STIX 2.1 Indicator SDO.

STIX 2.1 Indicator Objects contain STIX Patterns that can be used to describe the CPE configuration logic defined in the CVE.

The STIX 2.1 Specification contains a Software SCO that can be used to construct these patterns, here is the specification for it.

The problem here is CPEs cover applications (software), operating systems (also software), and hardware (not software).

As a trade-off to ensure consistency we decided to model all CPEs as Software SCOs regardless of whether they are software or not.

The pattern object is always constructed from STIX Software SCOs CPE property (software.cpe).

For example, if the CVE contained a simple node configuration with the following CPE URI cpe:2.3:o:tesla:model_3_firmware:-:*:*:*:*:*:*:* the pattern would read;

    "pattern": "[software.cpe = 'cpe:2.3:o:tesla:model_3_firmware:-:*:*:*:*:*:*:*']",

One Indicator Object is used for each CVE, therefore more complex patterns will exist, where operators and parenthesis will be required to construct the pattern.

I will talk more about pattern construction later in this post.

Here is the structure of the Indicator SDO and how Vulmatch populates it;

  {
    "type": "indicator",
    "spec_version": "2.1",
    "id": "indicator--<GENERATED BY STIX2 LIBRARY>",
    "created_by_ref": "identity--<SIGNALS CORPS IDENTITY ID>",
    "created": "<CVE_Items.publishedDate>",
    "modified": "<CVE_Items.lastModifiedDate>",
    "indicator_types": ["compromised"],
    "name": "<CVE_Items.cve.CVE_data_meta.ID>",
    "description": "<CVE_Items.cve.description.description_data.value>",
    "pattern": "<CPE PATTERN>",
    "valid_from": "<CVE_Items.publishedDate>"
  }

Now that the CVE is modelled as a STIX Vulnerability and STIX Indicator Objects the relationship between them needs to be defined.

Vulmatch uses STIX Relationship SROs to do this. They are structured like so;

{
  "type": "relationship",
  "spec_version": "2.1",
  "id": "relationship--<GENERATED BY STIX2 LIBRARY>",
  "created": "<CVE_Items.PublishedDate>",
  "modified": "<CVE_Items.lastModifiedDate>",
  "relationship_type": "indicates",
  "source_ref": "indicator--<INDICATOR STIX OBJECT>",
  "target_ref": "vulnerability--<VULNERABILITY STIX OBJECT>"
}

Let me demonstrate using three CVEs with configurations of various complexity.

Simple Relationships

CVE-2022-29098 offers a good example of simple relationships: https://nvd.nist.gov/vuln/detail/CVE-2022-29098

In this CVE there are 5 possible CPE match variations. The logic of the CVE CPE nodes reads as follows;

  1. Dell PowerScale OneFS (version 9.0.0) (application) [application vulnerable to CVE] OR,
    • [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.0.0:*:*:*:*:*:*:*' ]
  2. Dell PowerScale OneFS (version 9.1.0) (application) [application vulnerable to CVE] OR,
    • [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.1.0:*:*:*:*:*:*:*' ]
  3. Dell PowerScale OneFS (version 9.1.1) (application) [application vulnerable to CVE] OR,
    • [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.1.1:*:*:*:*:*:*:*' ]
  4. Dell PowerScale OneFS (version 9.2.0) (application) [application vulnerable to CVE] OR,
    • [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.2.0:*:*:*:*:*:*:*' ]
  5. Dell PowerScale OneFS (version 9.2.1) (application) [application vulnerable to CVE] OR,
    • [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.2.1:*:*:*:*:*:*:*' ]
  6. Dell PowerScale OneFS (version 9.3.0) (application) [application vulnerable to CVE]
    • [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.3.0:*:*:*:*:*:*:*' ]

In each match I have shown the STIX Pattern. Concatenated together into a single pattern gives;

[ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.0.0:*:*:*:*:*:*:*' ] OR [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.1.0:*:*:*:*:*:*:*' ] OR [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.1.1:*:*:*:*:*:*:*' ] OR [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.2.0:*:*:*:*:*:*:*' ] OR [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.2.1:*:*:*:*:*:*:*' ] OR [ software.cpe='cpe:2.3:a:dell:powerscale_onefs:9.3.0:*:*:*:*:*:*:*' ]

The CVE represented in STIX looks like;

Running On/With Relationships

Let me demonstrate how more complex Relationships are modelled using the example CVE-2022-27948: https://nvd.nist.gov/vuln/detail/CVE-2022-27948

In this CVE there are 12 possible CPE match variations (each with 2 CPEs). The logic of the CVE CPE matches reads;

  1. Tesla Model 3 (hardware) (version unspecified -) AND Tesla Model S (firmware) (any specified or unspecified version *) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*' ])
  2. Tesla Model 3 (hardware) (version unspecified -) AND Tesla Model X (firmware) (version unspecified -) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:-:*:*:*:*:*:*:*' ])
  3. Tesla Model 3 (hardware) (version unspecified -) AND Tesla Model X (firmware) (version 2020-11-23) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:2020-11-23:*:*:*:*:*:*:*' ])
  4. Tesla Model 3 (hardware) (version unspecified -) AND Tesla Model 3 (firmware) (version unspecified -) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_3_firmware:*:*:*:*:*:*:*:*' ])
  5. Tesla Model X (hardware) (version unspecified -) AND Tesla Model S (firmware) (any specified or unspecified version *) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_x:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*' ])
  6. Tesla Model X (hardware) (version unspecified -) AND Tesla Model X (firmware) (version unspecified -) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_x:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:-:*:*:*:*:*:*:*' ])
  7. Tesla Model X (hardware) (version unspecified -) AND running Tesla Model X (firmware) (version 2020-11-23) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_x:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:2020-11-23:*:*:*:*:*:*:*' ])
  8. Tesla Model X (hardware) (version unspecified -) AND running Tesla Model 3 (firmware) (version unspecified -) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_x:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_3_firmware:-:*:*:*:*:*:*:*' ])
  9. Tesla Model S (hardware) (version unspecified -) AND running Tesla Model S (firmware) (any specified or unspecified version *) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_s:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*' ])
  10. Tesla Model S (hardware) (version unspecified -) AND running Tesla Model X (firmware) (version unspecified -) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_s:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:-:*:*:*:*:*:*:*' ])
  11. Tesla Model S (hardware) (version unspecified -) AND running Tesla Model X (firmware) (version 2020-11-23) [firmware vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:tesla:model_s:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:2020-11-23:*:*:*:*:*:*:*' ])
  12. Tesla Model S (hardware) (version unspecified -) AND running Tesla Model 3 (firmware) (version unspecified -) [firmware vulnerable to CVE]
    • ([ software.cpe='cpe:2.3:h:tesla:model_s:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_3_firmware:-:*:*:*:*:*:*:*' ])

In each match I have shown the STIX Pattern. Concatenated together into a single pattern gives;

([ software.cpe='cpe:2.3:h:tesla:model_3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:-:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:2020-11-23:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_3_firmware:*:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_x:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_x:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:-:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_x:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:2020-11-23:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_x:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_3_firmware:-:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_s:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_s:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:-:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_s:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_x_firmware:2020-11-23:*:*:*:*:*:*:*' ]) OR ([ software.cpe='cpe:2.3:h:tesla:model_s:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:tesla:model_3_firmware:-:*:*:*:*:*:*:*' ])

Which modelled in STIX gives;

Advanced Relationships

I will use CVE-2019-18939 to demonstrate another more complex configuration: https://nvd.nist.gov/vuln/detail/CVE-2019-18939

In this CVE there are 4 possible variations, but this time each variation contains 3 CPEs.

All 4 possible distinct match configurations for this CVE can be written like so;

  1. eQ-3 Homematic CCU2 (hardware) (version unspecified -) AND EQ-3 HomeMatic CCU2 version 2.47.20 (firmware) AND HM Print Project HM Print version 1.2a (application) [firmware and application vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:eq-3:homematic_ccu2:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:eq-3:homematic_ccu2_firmware:2.47.20:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:a:hm-print_project:hm-print:1.2a:*:*:*:*:*:*:*' ] )
  2. eQ-3 Homematic CCU3 (hardware) (version unspecified -) AND EQ-3 HomeMatic CCU3 version 3.47.18 (firmware) AND HM Print Project HM Print version 1.2 (application) [firmware and application vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:eq-3:homematic_ccu3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:eq-3:homematic_ccu3_firmware:3.47.18:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:a:hm-print_project:hm-print:1.2:*:*:*:*:*:*:*' ] )
  3. eQ-3 Homematic CCU3 (hardware) (version unspecified -) AND EQ-3 HomeMatic CCU3 version 3.47.18 (firmware) AND HM Print Project HM Print version 1.2a (application) [firmware and application vulnerable to CVE], OR,
    • ([ software.cpe='cpe:2.3:h:eq-3:homematic_ccu3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:eq-3:homematic_ccu3_firmware:3.47.18:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:a:hm-print_project:hm-print:1.2a:*:*:*:*:*:*:*' ] )
  4. eQ-3 Homematic CCU2 (hardware) (version unspecified -) AND EQ-3 HomeMatic CCU2 version 2.47.20 (firmware) AND HM Print Project HM Print version 1.2 (application) [firmware and application vulnerable to CVE]
    • ([ software.cpe='cpe:2.3:h:eq-3:homematic_ccu2:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:eq-3:homematic_ccu2_firmware:2.47.20:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:a:hm-print_project:hm-print:1.2:*:*:*:*:*:*:*' ] )

In each match I have shown the STIX Pattern. Concatenated together into a single pattern gives;

([ software.cpe='cpe:2.3:h:eq-3:homematic_ccu2:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:eq-3:homematic_ccu2_firmware:2.47.20:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:a:hm-print_project:hm-print:1.2a:*:*:*:*:*:*:*' ] ) OR ([ software.cpe='cpe:2.3:h:eq-3:homematic_ccu3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:eq-3:homematic_ccu3_firmware:3.47.18:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:a:hm-print_project:hm-print:1.2:*:*:*:*:*:*:*' ] ) OR ([ software.cpe='cpe:2.3:h:eq-3:homematic_ccu3:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:eq-3:homematic_ccu3_firmware:3.47.18:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:a:hm-print_project:hm-print:1.2a:*:*:*:*:*:*:*' ] ) OR ([ software.cpe='cpe:2.3:h:eq-3:homematic_ccu2:-:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:o:eq-3:homematic_ccu2_firmware:2.47.20:*:*:*:*:*:*:*' ] AND [ software.cpe='cpe:2.3:a:hm-print_project:hm-print:1.2:*:*:*:*:*:*:*' ] )

Which modelled in STIX gives;

User Software (CPEs) as STIX Objects

I have already talked about using Software SCOs for patterns in STIX Objects to represent patterns of products that are vulnerable to CVEs.

Software SCOs can also be used to model products. In the case of Vulmatch they are used to model the products a user can select.

Software SCOs have a default cpe, languages, vendor, and version Properties that are all found in the cpe23Uri values.

Vulmatch constructs Software SCOs for a users product selection as follows;

    {
      "type": "software",
      "spec_version": "2.1",
      "id": "software--<GENERATED BY STIX2 LIBRARY>",
      "name": "<cpes.titles.title>",
      "cpe": "<cpes.titles.cpe23Uri>",  
      "version": "<cpes.titles.cpe23Uri[version_section]>",
      "vendor": "<cpes.titles.cpe23Uri[vendor_section]>",
      "languages": "<cpes.titles.lang>",
      "revoked": "<cpes.deprecated>",
      "x_nvd_lastModifiedDate": "<cpes.lastModifiedDate>",
      "x_nvd_part": "<cpes.titles.cpe23Uri[part_section]>",
      "x_nvd_vendor": "<cpes.titles.cpe23Uri[vendor_section]>",
      "x_nvd_product": "<cpes.titles.cpe23Uri[product_section]>",
      "x_nvd_version": "<cpes.titles.cpe23Uri[version_section]>",
      "x_nvd_update": "<cpes.titles.cpe23Uri[update_section]>",
      "x_nvd_language": "<cpes.titles.cpe23Uri[language_section]>",
      "x_nvd_sw_edition": "<cpes.titles.cpe23Uri[sw_edition_section]>",
      "x_nvd_target_sw": "<cpes.titles.cpe23Uri[target_sw_section]>",
      "x_nvd_target_hw": "<cpes.titles.cpe23Uri[target_hw_section]>",
      "x_nvd_other": "<cpes.titles.cpe23Uri[other_section]>",
      "x_nvd_refs": [
        {
          "x_ref": "<cpes.refs.ref[n]>",
          "x_type": "<cpes.refs.type[n]>"
        }
      ],
      "x_nvd_state": {
        "x_deprecated": "<cpes.deprecated>",
        "x_deprecatedBy": ["cpes.deprecatedBy[N]"]
      }
    }

Many of the default CPE fields are mapped directly to the Software Object properties.

You can see that I have broken each section of the CPE URI as a custom property (e.g. x_nvd_version) to allow for performance improvements when matching is carried out (and for easier search and filtering later down the line).

Take a real example of the CPE for the Tesla Model 3 Web Interface 2020.4.10;

GET https://services.nvd.nist.gov/rest/json/cpes/1.0/?apiKey=&cpeMatchString=cpe:2.3:a:tesla:model_3_web_interface:2020.4.10:*:*:*:*:*:*:*&includeDeprecated=true

Response here for reference.

Dealing with Deprecated CPEs

When backfilling, adding new, or updating CPEs, Vulmatch uses the CPE database records (pulled via the CPE API).

In the first post I mentioned how some CPE records can become deprected when an update happens. I used the example cpe:2.3:a:microsoft:visio_2003-:sp3:*:*:*:*:*:*:* which was deprecated in favour of cpe:2.3:a:microsoft:visio:2003:sp3:*:*:*:*:*:* as you can see in the following response.

GET https://services.nvd.nist.gov/rest/json/cpes/1.0/?apiKey=<<APIKEY>>&cpeMatchString=cpe:2.3:a:microsoft:visio_2003-:sp3:*:*:*:*:*:*:*&includeDeprecated=true

To account for these deprecations, Vulmatch first adds the revoked property to the old STIX CPE Object (and adds any updated fields), creates a new CPE Object for the new CPE Object, and uses a STIX SRO to connect the two with the relationship_type derived-from (as described in my STIX versioning tutorial).

Here is how the example cpe:2.3:a:microsoft:visio_2003-:sp3:*:*:*:*:*:*:* would be modelled;

Dealing with CVEs that contain missing CPEs

In other cases, CVEs contain CPEs not covered in the CPE database. The earlier CVE example in this post (CVE-2022-27948) has such a case (cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*)

Querying the CPE API;

GET https://services.nvd.nist.gov/rest/json/cpes/1.0/?apiKey=&includeDeprecated=true&cpeMatchString=cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*&addOns=cves&startIndex=0&resultsPerPage=500

Returns no results for this CPE URI;

{
    "resultsPerPage": 500,
    "startIndex": 0,
    "totalResults": 0,
    "result": {
        "dataType": "CPE",
        "feedVersion": "1.0",
        "cpeCount": 0,
        "feedTimestamp": "2022-07-25T18:58Z",
        "cpes": []
    }
}

You can identify cases of CVEs containing CPEs not found in the CPE database where the cpe_name field is empty, as follows;

{
  "vulnerable": true,
  "cpe23Uri": "cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*",
  "versionEndIncluding": "2022-03-26",
  "cpe_name": []
},

Whereas a CPE that does exist in the CPE database will have values in the cpe_name name field in the CVE like so with the nested version value containing defined (-) or specific version used (e.g. 1.0) in the CPE URI;

{
  "vulnerable": true,
  "cpe23Uri": "cpe:2.3:o:tesla:model_3_firmware:*:*:*:*:*:*:*:*",
  "versionEndIncluding": "2022-03-26",
  "cpe_name": [
    {
      "cpe23Uri": "cpe:2.3:o:tesla:model_3_firmware:-:*:*:*:*:*:*:*",
      "lastModifiedDate": "2020-08-26T22:42Z"
    }
  ]
}

In order to allow users to select products missing from the CPE database (e.g. cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*), when a CPE in a CVE is missing in the CPE database (and thus missing in Vulmatch), Vulmatch creates missing CPE records using the CPE information inside the CVE.

These are modelled differently as Software SCOs containing much less data. This is to make this clear that the record is not an official CVE. Here is how these records are modelled;

    {
      "type": "software",
      "spec_version": "2.1",
      "id": "software--<GENERATED BY STIX2 LIBRARY>",
      "name": "<cpes.titles.cpe23Uri>",
      "cpe": "<cpes.titles.cpe23Uri>",  
      "version": "<cpes.titles.cpe23Uri[version_section]>",
      "vendor": "<cpes.titles.cpe23Uri[vendor_section]>",
    }

Here is an example using the missing cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*;

If any records for this CPE are identified by Vulmatch at a later date in the CPE database then a new Object will be created for it, as described above. The old, partial Object created from the CVE record will then be updated with the property revoked = true and a new SRO created to link the two Objects.

For example, if a record for cpe:2.3:o:tesla:model_s_firmware:2030-01-02:*:*:*:*:*:*:* appeared in the CPE database (it does not currently exist) replacing cpe:2.3:o:tesla:model_s_firmware:*:*:*:*:*:*:*:*. In this case a new Software SCO would be created in Vulmatch for the new CPE, and the SCO for old CPE Object would be revoked and a relationship to the new Software SCO added, like so;

Next time: Sightings

The only thing missing is how to model a match between a users CPE configuration (STIX software SCO) and the CVE CPE configurations (also STIX software SCOs).

STIX Sighting SROs provide a way to do this, as I will show in the next post.




Our brand new Discord!

Like this blog?

Sign up to receive new posts in your inbox.


Stixify

Stixify. Extract machine readable intelligence from unstructured data.

Extract machine readable intelligence from unstructured data.

Obstracts

Obstracts

Turn any blog into structured threat intelligence.


Vulmatch

Vulmatch

Know when software you use is vulnerable, how it is being exploited, and how to detect an attack.

SIEM Rules

SIEM Rules. Your detection engineering database.

View, modify, and deploy SIEM rules for threat hunting.