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 (usually, the interactive graphs). Please view the post on dogesec.com for the full interactive viewing experience.
tl;dr
We do a lot of our research into vulnerabilities. To aid this, we enrich CVEs using many remote sources of intelligence. Here is a walk-through showing how we connect CVEs to EPSS scores, CISA KEVs, MITRE ATT&CK, CWEs, and CAPECs.
Overview
Here is the current STIX 2.1 Vulnerability created by cve2stix for CVE-2019-18988;
{
"type": "vulnerability",
"spec_version": "2.1",
"id": "vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380",
"created_by_ref": "identity--562918ee-d5da-5579-b6a1-fae50cc6bad3",
"created": "2020-02-07T16:15:10.033Z",
"modified": "2024-11-21T04:33:56.580Z",
"name": "CVE-2019-18988",
"description": "TeamViewer Desktop through 14.7.1965 allows a bypass of remote-login access control because the same key is used for different customers' installations. It used a shared AES key for all installations since at least as far back as v7.0.43148, and used it for at least OptionsPasswordAES in the current version of the product. If an attacker were to know this key, they could decrypt protect information stored in the registry or configuration files of TeamViewer. With versions before v9.x , this allowed for attackers to decrypt the Unattended Access password to the system (which allows for remote login to the system as well as headless file browsing). The latest version still uses the same key for OptionPasswordAES but appears to have changed how the Unattended Access password is stored. While in most cases an attacker requires an existing session on a system, if the registry/configuration keys were stored off of the machine (such as in a file share or online), an attacker could then decrypt the required password to login to the system.",
"external_references": [
{
"source_name": "cve",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-18988",
"external_id": "CVE-2019-18988"
},
{
"source_name": "cwe",
"url": "https://cwe.mitre.org/data/definitions/CWE-521.html",
"external_id": "CWE-521"
},
{
"source_name": "[email protected]",
"description": "Vendor Advisory",
"url": "https://community.teamviewer.com/t5/Announcements/Specification-on-CVE-2019-18988/td-p/82264"
},
{
"source_name": "[email protected]",
"description": "Vendor Advisory",
"url": "https://community.teamviewer.com/t5/Knowledge-Base/tkb-p/Knowledgebase?threadtype=label&labels=Security"
},
{
"source_name": "[email protected]",
"description": "Third Party Advisory",
"url": "https://twitter.com/Blurbdust/status/1224212682594770946?s=20"
},
{
"source_name": "[email protected]",
"description": "Exploit,Third Party Advisory",
"url": "https://whynotsecurity.com/blog/teamviewer/"
},
{
"source_name": "af854a3a-2127-422b-91ae-364da2661108",
"description": "Vendor Advisory",
"url": "https://community.teamviewer.com/t5/Announcements/Specification-on-CVE-2019-18988/td-p/82264"
},
{
"source_name": "af854a3a-2127-422b-91ae-364da2661108",
"description": "Vendor Advisory",
"url": "https://community.teamviewer.com/t5/Knowledge-Base/tkb-p/Knowledgebase?threadtype=label&labels=Security"
},
{
"source_name": "af854a3a-2127-422b-91ae-364da2661108",
"description": "Third Party Advisory",
"url": "https://twitter.com/Blurbdust/status/1224212682594770946?s=20"
},
{
"source_name": "af854a3a-2127-422b-91ae-364da2661108",
"description": "Exploit,Third Party Advisory",
"url": "https://whynotsecurity.com/blog/teamviewer/"
},
{
"source_name": "vulnStatus",
"description": "Modified"
},
{
"source_name": "sourceIdentifier",
"description": "[email protected]"
}
],
"object_marking_refs": [
"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
"marking-definition--562918ee-d5da-5579-b6a1-fae50cc6bad3"
],
"extensions": {
"extension-definition--2c5c13af-ee92-5246-9ba7-0b958f8cd34a": {
"extension_type": "toplevel-property-extension"
}
},
"x_cvss": {
"v2_0": {
"base_score": 4.4,
"base_severity": "MEDIUM",
"exploitability_score": 3.4,
"impact_score": 6.4,
"source": "[email protected]",
"type": "Primary",
"vector_string": "AV:L/AC:M/Au:N/C:P/I:P/A:P"
},
"v3_1": {
"base_score": 7.0,
"base_severity": "HIGH",
"exploitability_score": 1.0,
"impact_score": 5.9,
"source": "[email protected]",
"type": "Primary",
"vector_string": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H"
}
}
},
You will see the Vulnerability object also includes references to further information, CWEs, CVSS scores, etc.
Similarly, the products (CPEs) that are vulnerable are tracked in Indicator objects (linked to the CVE) generated by cve2stix.
{
"type": "indicator",
"spec_version": "2.1",
"id": "indicator--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380",
"created_by_ref": "identity--562918ee-d5da-5579-b6a1-fae50cc6bad3",
"created": "2020-02-07T16:15:10.033Z",
"modified": "2024-11-21T04:33:56.580Z",
"name": "CVE-2019-18988",
"description": "TeamViewer Desktop through 14.7.1965 allows a bypass of remote-login access control because the same key is used for different customers' installations. It used a shared AES key for all installations since at least as far back as v7.0.43148, and used it for at least OptionsPasswordAES in the current version of the product. If an attacker were to know this key, they could decrypt protect information stored in the registry or configuration files of TeamViewer. With versions before v9.x , this allowed for attackers to decrypt the Unattended Access password to the system (which allows for remote login to the system as well as headless file browsing). The latest version still uses the same key for OptionPasswordAES but appears to have changed how the Unattended Access password is stored. While in most cases an attacker requires an existing session on a system, if the registry/configuration keys were stored off of the machine (such as in a file share or online), an attacker could then decrypt the required password to login to the system.",
"indicator_types": [
"compromised"
],
"pattern": "([software:cpe='cpe:2.3:a:teamviewer:teamviewer:*:*:*:*:*:*:*:*'])",
"pattern_type": "stix",
"pattern_version": "2.1",
"valid_from": "2020-02-07T16:15:10.033Z",
"external_references": [
{
"source_name": "cve",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-18988",
"external_id": "CVE-2019-18988"
}
],
"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:teamviewer:teamviewer:*:*:*:*:*:*:*:*",
"matchCriteriaId": "1169616E-3D16-4688-8402-8E922F26B339"
}
]
}
},
If you are interested in how the logic for the pattern
property is generated, read my post; Writing Detection Rules to Identify if Products in my Stack are Vulnerable
In short, cve2stix alone creates a rich bundle of intelligence for all reported CVEs.
To demonstrate, here are all the objects cve2stix creates for CVE-2019-18988;
However, external intelligence sources provide a lot more information that is useful when analysing vulnerabilities.
You can quickly see how the cve2stix graph of intelligence could be expanded for each CVE to include other data enrichments.
For example, taking a CVE and finding all the MITRE ATT&CK Techniques it is linked to.
Or doing it the other way around, taking an ATT&CK Techniques and finding all vulnerabilities exploited using that technique.
The problem; this data is very rarely linked together in a network graph making queries like this very difficult to perform. So, we set out to build such a graph ourselves.
Follow along
In this post I am going to provide ArangoDB queries you can use to analyse and filter the data (represented as STIX objects).
If you would like to follow along, and keep a searchable copy of the STIX objects locally, you can import the data using stix2arango.
Once you’ve installed stix2arango, you can run the following command to import all CVEs published in 2020 (I’ll use CVE-2019-18988 for this post, published in 2020) that were created by cve2stix;
python3 utilities/arango_cve_processor/insert_archive_cve.py \
--database blog_cve_demo \
--years 2020 \
--ignore_embedded_relationships
If you want to import all CVEs (250k+), you can run the script as follows (beware: this will take considerably longer to complete!);
python3 utilities/arango_cve_processor/insert_archive_cve.py \
--database blog_cve_demo \
--ignore_embedded_relationships
To double check everything has imported as expected you can search for CVE-2019-18988 as follows;
FOR doc IN nvd_cve_vertex_collection
FILTER doc.type == "vulnerability"
AND doc.name == "CVE-2019-18988"
RETURN [doc]
Finally, you will need to install arango_cve_processor using the setup instructions described here. I’d recommend using the hosted CTI Butler web app required with arango_cve_processor when configuring it.
CVE -> KEV
CISA tracks known exploited vulnerabilities (KEVs).
CVE-2019-18988 is one CVE known to be actively exploited, and can be found in the KEV catalogue.
arango_cve_processor has a cve-kev
relationship mode that will create report objects for all KEV records that exist for CVEs in your ArangoDB database.
To do this you can run arango_cve_processor as follows;
python3 arango_cve_processor.py \
--database blog_cve_demo_database \
--relationship cve-cwe \
--ignore_embedded_relationships true
Pro-tip, if you only want to run the script to run on a single CVE in the database (much faster), you can do so as follows…
python3 arango_cve_processor.py \
--database blog_cve_demo_database \
--relationship cve-kev \
--ignore_embedded_relationships true \
--cve_id CVE-2019-18988
Once the script completes, you can find if a KEV exists for the CVE using the following search (replacing the CVE ID as required)…
FOR doc IN nvd_cve_vertex_collection
FILTER doc.type == "report"
FILTER LENGTH(
doc.external_references[* FILTER CURRENT.source_name == "cve" AND CURRENT.external_id == "CVE-2019-18988"]
) > 0
AND "kev" IN doc.labels
LET keys = ATTRIBUTES(doc)
LET filteredKeys = keys[* FILTER !STARTS_WITH(CURRENT, "_")]
RETURN [KEEP(doc, filteredKeys)]
For CVE-2019-18988 we already know a KEV exists, and thus one result is returned…
{
"created": "2020-02-07T16:15:10.033Z",
"created_by_ref": "identity--152ecfe1-5015-522b-97e4-86b60c57036d",
"description": "TeamViewer Desktop Bypass Remote Login Vulnerability\n\nTeamViewer Desktop allows for bypass of remote-login access control because the same AES key is used for different customers' installations. If an attacker were to know this key, they could decrypt protected information stored in registry or configuration files or decryption of the Unattended Access password to the system (which allows for remote login to the system).\n\nRequired action: Apply updates per vendor instructions.\n\nAction due by: 2022-05-03",
"external_references": [
{
"source_name": "cve",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-18988",
"external_id": "CVE-2019-18988"
}
],
"id": "report--7f2c8587-d845-5964-83c8-d29187329863",
"labels": [
"kev"
],
"modified": "2024-11-21T04:33:56.580Z",
"name": "CISA KEV: CVE-2019-18988",
"object_marking_refs": [
"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
"marking-definition--152ecfe1-5015-522b-97e4-86b60c57036d"
],
"object_refs": [
"vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380"
],
"published": "2020-02-07T16:15:10.033Z",
"spec_version": "2.1",
"type": "report"
}
CVE -> EPSS
The Exploit Prediction Scoring System (EPSS), is a statistical model designed to estimate the likelihood of a given CVE being exploited in the wild. It provides a probabilistic score that helps organisations prioritise their vulnerability management efforts by focusing on the vulnerabilities that are most likely to be actively exploited.
EPSS scores can be retrieved via the EPSS API, e.g.
curl -X GET "https://api.first.org/data/v1/epss?cve=CVE-2019-18988"
{
"status": "OK",
"status-code": 200,
"version": "1.0",
"access-control-allow-headers": "x-requested-with",
"access": "public",
"total": 1,
"offset": 0,
"limit": 100,
"data": [
{
"cve": "CVE-2019-18988",
"epss": "0.005470000",
"percentile": "0.772820000",
"date": "2024-12-22"
}
]
}
arango_cve_processor will do this automatically for you using cve-epss
mode, creating a report object with the current EPSS score assigned to the CVE…
python3 arango_cve_processor.py \
--database blog_cve_demo_database \
--relationship cve-epss \
--ignore_embedded_relationships true \
--cve_id CVE-2019-18988
Running a similar search to before,
FOR doc IN nvd_cve_vertex_collection
FILTER doc.type == "report"
FILTER LENGTH(
doc.external_references[* FILTER CURRENT.source_name == "cve" AND CURRENT.external_id == "CVE-2019-18988"]
) > 0
AND "epss" IN doc.labels
LET keys = ATTRIBUTES(doc)
LET filteredKeys = keys[* FILTER !STARTS_WITH(CURRENT, "_")]
RETURN [KEEP(doc, filteredKeys)]
You’ll see the EPSS Report for CVE-2019-18988 returned…
{
"created": "2024-12-23T00:00:00.000Z",
"created_by_ref": "identity--152ecfe1-5015-522b-97e4-86b60c57036d",
"extensions": {
"extension-definition--efd26d23-d37d-5cf2-ac95-a101e46ce11d": {
"extension_type": "toplevel-property-extension"
}
},
"external_references": [
{
"source_name": "cve",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-18988",
"external_id": "CVE-2019-18988"
}
],
"id": "report--2c7be71c-c0a8-57a2-9643-5fb28dedefcd",
"labels": [
"epss"
],
"modified": "2024-12-23T00:00:00.000Z",
"name": "EPSS Scores: CVE-2019-18988",
"object_marking_refs": [
"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
"marking-definition--152ecfe1-5015-522b-97e4-86b60c57036d"
],
"object_refs": [
"vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380"
],
"published": "2024-12-23T00:00:00Z",
"spec_version": "2.1",
"type": "report",
"x_epss": [
{
"cve": "CVE-2019-18988",
"epss": "0.00547",
"percentile": "0.77280",
"date": "2024-12-23"
}
]
}
The EPSS score is updated every 24 hours. Each time you re-run the arango_cve_processor in cve-epss
mode and a new score is returned, arango_cve_processor will add the new score to the x_epss
object. This means you can filter CVEs by EPSS score but also track changes over time of their EPSS scores.
CVE -> CWEs
If you look inside the Vulnerability STIX object for CVE-2019-18988 you’ll see a reference to CWE-521;
{
"source_name": "cwe",
"url": "https://cwe.mitre.org/data/definitions/521.html",
"external_id": "CWE-521"
},
Using CTI Butler, you can get the STIX Object for CWE-521 as follows;
curl -X 'GET' \
'https://api.ctibutler.com/v1/cwe/objects/CWE-521/' \
-H 'accept: application/json' \
-H 'API-KEY: REDACTED'
{
"page_size": 50,
"page_number": 1,
"page_results_count": 1,
"total_results_count": 1,
"objects": [
{
"type": "weakness",
"spec_version": "2.1",
"id": "weakness--de02e88c-42c5-5ddf-b5d1-1c8aeac79926",
"created_by_ref": "identity--d91de5c9-2d85-5cc9-97c0-c5ec8deb1a4b",
"created": "2006-07-19T00:00:00.000Z",
"modified": "2023-06-29T00:00:00.000Z",
"name": "Weak Password Requirements",
"description": "The product does not require that users should have strong passwords, which makes it easier for attackers to compromise user accounts.\nAuthentication mechanisms often rely on a memorized secret (also known as a password) to provide an assertion of identity for a user of a system. It is therefore important that this password be of sufficient complexity and impractical for an adversary to guess. The specific requirements around how complex a password needs to be depends on the type of system being protected. Selecting the correct password requirements and enforcing them through implementation are critical to the overall success of the authentication mechanism.",
"modes_of_introduction": [
"Architecture and Design",
"Implementation"
],
"common_consequences": [
"Access Control"
],
"detection_methods": [
"Automated Static Analysis"
],
"external_references": [
{
"source_name": "cwe",
"url": "http://cwe.mitre.org/data/definitions/521.html",
"external_id": "CWE-521"
},
{
"source_name": "Michael Howard, David LeBlanc, John Viega",
"description": "24 Deadly Sins of Software Security",
"external_id": "REF-44"
},
{
"source_name": "NIST",
"description": "Digital Identity Guidelines (SP 800-63B)",
"url": "https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-63b.pdf",
"external_id": "REF-1053"
},
{
"source_name": "OWASP Top Ten 2004",
"description": "Broken Authentication and Session Management",
"external_id": "A3"
},
{
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/112.html",
"external_id": "CAPEC-112"
},
{
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/16.html",
"external_id": "CAPEC-16"
},
{
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/49.html",
"external_id": "CAPEC-49"
},
{
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/509.html",
"external_id": "CAPEC-509"
},
{
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/55.html",
"external_id": "CAPEC-55"
},
{
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/555.html",
"external_id": "CAPEC-555"
},
{
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/561.html",
"external_id": "CAPEC-561"
},
{
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/565.html",
"external_id": "CAPEC-565"
},
{
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/70.html",
"external_id": "CAPEC-70"
}
],
"object_marking_refs": [
"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
"marking-definition--d91de5c9-2d85-5cc9-97c0-c5ec8deb1a4b"
],
"extensions": {
"extension-definition--31725edc-7d81-5db7-908a-9134f322284a": {
"extension_type": "new-sdo"
}
}
}
]
}
By creating a STIX relationship object from the Vulnerability generated by cve2stix to the CWE object in CTI Butler, you can enhance the graph of enrichments.
This is exactly what arango_cve_processor does in cve-cwe
relationship mode when run as follows;
python3 arango_cve_processor.py \
--database blog_cve_demo_database \
--relationship cve-cwe \
--ignore_embedded_relationships true
Once the script completes, if you run the following search, all CWE objects connected to CVE-2019-18988 will be returned;
FOR doc IN nvd_cve_edge_collection
FILTER doc.source_ref == "vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380"
AND LENGTH(
doc.external_references[* FILTER CURRENT.source_name == "cwe"]
) > 0
LET keys = ATTRIBUTES(doc)
LET filteredKeys = keys[* FILTER !STARTS_WITH(CURRENT, "_")]
RETURN [KEEP(doc, filteredKeys)]
Which returns one result, the new vulnerability to weakness relationship object created by arango_cve_processor for CWE-521…
[
[
{
"created": "2020-02-07T16:15:10.033Z",
"created_by_ref": "identity--152ecfe1-5015-522b-97e4-86b60c57036d",
"description": "CVE-2019-18988 is exploited using CWE-521",
"external_references": [
{
"source_name": "cve",
"external_id": "CVE-2019-18988",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-18988"
},
{
"source_name": "cwe",
"external_id": "CWE-521",
"url": "http://cwe.mitre.org/data/definitions/521.html"
}
],
"id": "relationship--2d841d4e-6c3d-5b31-8ce5-dc84b2c9cd70",
"modified": "2024-11-21T04:33:56.580Z",
"object_marking_refs": [
"marking-definition--94868c89-83c2-464b-929b-a1a8aa3c8487",
"marking-definition--152ecfe1-5015-522b-97e4-86b60c57036d"
],
"relationship_type": "exploited-using",
"source_ref": "vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380",
"target_ref": "weakness--de02e88c-42c5-5ddf-b5d1-1c8aeac79926",
"type": "relationship"
}
]
]
CVE -> CAPEC
Looking inside the CWE-521 STIX object returned by CTI Butler you will see CAPEC references (there are 9 in total). Here is one reference for example;
{
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/112.html",
"external_id": "CAPEC-112"
},
Using CTI Butler, you can get each CAPEC object as follows (here I use CAPEC-112);
curl -X 'GET' \
'https://api.ctibutler.com/v1/capec/objects/CAPEC-112/' \
-H 'accept: application/json' \
-H 'API-KEY: REDACTED'
{
"page_size": 50,
"page_number": 1,
"page_results_count": 1,
"total_results_count": 1,
"objects": [
{
"created": "2014-06-23T00:00:00.000Z",
"created_by_ref": "identity--e50ab59c-5c4f-4d40-bf6a-d58418d89bcd",
"description": "In this attack, some asset (information, functionality, identity, etc.) is protected by a finite secret value. The attacker attempts to gain access to this asset by using trial-and-error to exhaustively explore all the possible secret values in the hope of finding the secret (or a value that is functionally equivalent) that will unlock the asset.",
"external_references": [
{
"external_id": "CAPEC-112",
"source_name": "capec",
"url": "https://capec.mitre.org/data/definitions/112.html"
},
{
"external_id": "CWE-330",
"source_name": "cwe",
"url": "http://cwe.mitre.org/data/definitions/330.html"
},
{
"external_id": "CWE-326",
"source_name": "cwe",
"url": "http://cwe.mitre.org/data/definitions/326.html"
},
{
"external_id": "CWE-521",
"source_name": "cwe",
"url": "http://cwe.mitre.org/data/definitions/521.html"
},
{
"description": "Brute Force",
"external_id": "T1110",
"source_name": "ATTACK",
"url": "https://attack.mitre.org/wiki/Technique/T1110"
},
{
"description": "Brute Force",
"external_id": "11",
"source_name": "WASC",
"url": "http://projects.webappsec.org/Brute-Force"
},
{
"description": "Brute force attack",
"source_name": "OWASP Attacks",
"url": "https://owasp.org/www-community/attacks/Brute_force_attack"
}
],
"id": "attack-pattern--7b423196-9de6-400f-91de-a1f26b3f19f1",
"modified": "2022-09-29T00:00:00.000Z",
"name": "Brute Force",
"object_marking_refs": [
"marking-definition--17d82bb2-eeeb-4898-bda5-3ddbcd2b799d"
],
"spec_version": "2.1",
"type": "attack-pattern",
"x_capec_abstraction": "Meta",
"x_capec_consequences": {
"Access_Control": [
"Gain Privileges"
],
"Authorization": [
"Gain Privileges"
],
"Confidentiality": [
"Read Data",
"Gain Privileges"
]
},
"x_capec_domains": [
"Software"
],
"x_capec_execution_flow": "<h2> Execution Flow </h2><div><h3>Explore</h3><ol><li> <p> <b>Determine secret testing procedure: </b>Determine how a potential guess of the secret may be tested. This may be accomplished by comparing some manipulation of the secret to a known value, use of the secret to manipulate some known set of data and determining if the result displays specific characteristics (for example, turning cryptotext into plaintext), or by submitting the secret to some external authority and having the external authority respond as to whether the value was the correct secret. Ideally, the attacker will want to determine the correctness of their guess independently since involvement of an external authority is usually slower and can provide an indication to the defender that a brute-force attack is being attempted.</p></li><table><tbody><tr><th>Techniques</th></tr><tr><td>Determine if there is a way to parallelize the attack. Most brute force attacks can take advantage of parallel techniques by dividing the search space among available resources, thus dividing the average time to success by the number of resources available. If there is a single choke point, such as a need to check answers with an external authority, the attackers' position is significantly degraded.</td></tr></tbody></table><li> <p> <b>Reduce search space: </b>Find ways to reduce the secret space. The smaller the attacker can make the space they need to search for the secret value, the greater their chances for success. There are a great many ways in which the search space may be reduced.</p></li><table><tbody><tr><th>Techniques</th></tr><tr><td>If possible, determine how the secret was selected. If the secret was determined algorithmically (such as by a random number generator) the algorithm may have patterns or dependencies that reduce the size of the secret space. If the secret was created by a human, behavioral factors may, if not completely reduce the space, make some types of secrets more likely than others. (For example, humans may use the same secrets in multiple places or use secrets that look or sound familiar for ease of recall.)</td></tr><tr><td>If the secret was chosen algorithmically, cryptanalysis can be applied to the algorithm to discover patterns in this algorithm. (This is true even if the secret is not used in cryptography.) Periodicity, the need for seed values, or weaknesses in the generator all can result in a significantly smaller secret space.</td></tr><tr><td>If the secret was chosen by a person, social engineering and simple espionage can indicate patterns in their secret selection. If old secrets can be learned (and a target may feel they have little need to protect a secret that has been replaced) hints as to their selection preferences can be gleaned. These can include character substitutions a target employs, patterns in sources (dates, famous phrases, music lyrics, family members, etc.). Once these patterns have been determined, the initial efforts of a brute-force attack can focus on these areas.</td></tr><tr><td>Some algorithmic techniques for secret selection may leave indicators that can be tested for relatively easily and which could then be used to eliminate large areas of the search space for consideration. For example, it may be possible to determine that a secret does or does not start with a given character after a relatively small number of tests. Alternatively, it might be possible to discover the length of the secret relatively easily. These discoveries would significantly reduce the search space, thus increasing speed with which the attacker discovers the secret.</td></tr></tbody></table><li> <p> <b>Expand victory conditions: </b>It is sometimes possible to expand victory conditions. For example, the attacker might not need to know the exact secret but simply needs a value that produces the same result using a one-way function. While doing this does not reduce the size of the search space, the presence of multiple victory conditions does reduce the likely amount of time that the attacker will need to explore the space before finding a workable value.</p></li></ol></div><div><h3>Exploit</h3><ol><li> <p> <b>Gather information so attack can be performed independently.: </b>If possible, gather the necessary information so a successful search can be determined without consultation of an external authority. This can be accomplished by capturing cryptotext (if the goal is decoding the text) or the encrypted password dictionary (if the goal is learning passwords).</p></li></ol></div>",
"x_capec_extended_description": "\n <xhtml:p>Examples of secrets can include, but are not limited to, passwords, encryption keys, database lookup keys, and initial values to one-way functions. The key factor in this attack is the attackers' ability to explore the possible secret space rapidly. This, in turn, is a function of the size of the secret space and the computational power the attacker is able to bring to bear on the problem. If the attacker has modest resources and the secret space is large, the challenge facing the attacker is intractable. Assuming a finite secret space, a brute force attack will eventually succeed. The defender must rely on making sure that the time and resources necessary to do so will exceed the value of the information.</xhtml:p>\n ",
"x_capec_parent_of_refs": [
"attack-pattern--86a5e931-7f53-46fe-b6f0-c88498f6557f",
"attack-pattern--8d88a81c-bde9-4fb3-acbe-901c783d6427"
],
"x_capec_prerequisites": [
"The attacker must be able to determine when they have successfully guessed the secret. As such, one-time pads are immune to this type of attack since there is no way to determine when a guess is correct."
],
"x_capec_resources_required": [
"None: No specialized resources are required to execute this type of attack. Ultimately, the speed with which an attacker discovers a secret is directly proportional to the computational resources the attacker has at their disposal. This attack method is resource expensive: having large amounts of computational power do not guarantee timely success, but having only minimal resources makes the problem intractable against all but the weakest secret selection procedures."
],
"x_capec_skills_required": {
"Low": "The attack simply requires basic scripting ability to automate the exploration of the search space. More sophisticated attackers may be able to use more advanced methods to reduce the search space and increase the speed with which the secret is located."
},
"x_capec_status": "Draft",
"x_capec_typical_severity": "High",
"x_capec_version": "3.9"
}
]
}
Using CAPEC references found in CWEs linked to CVEs, you can create a relationship between the CVE and CAPECs.
To do this in arango_cve_processor you can use the cve-capec
relationship mode as follows…
python3 arango_cve_processor.py \
--database blog_cve_demo_database \
--relationship cve-capec \
--ignore_embedded_relationships true
Running the query;
FOR doc IN nvd_cve_edge_collection
FILTER doc.source_ref == "vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380"
AND LENGTH(
doc.external_references[* FILTER CURRENT.source_name == "capec"]
) > 0
LET keys = ATTRIBUTES(doc)
LET filteredKeys = keys[* FILTER !STARTS_WITH(CURRENT, "_")]
RETURN [KEEP(doc, filteredKeys)]
Will return 9 results – the 9 CAPEC references found in CWE-521 (linked to CVE-2019-18988).
CVE -> ATT&CK
CAPEC objects have references to ATT&CK Techniques, for example in CAPEC-112 above you can see a reference to T1110;
{
"description": "Brute Force",
"external_id": "T1110",
"source_name": "ATTACK",
"url": "https://attack.mitre.org/wiki/Technique/T1110"
},
Using CTI Butler, you can get ATT&CK objects as follows (here I use T1110);
curl -X 'GET' \
'https://api.ctibutler.com/v1/attack-enterprise/objects/T1110/' \
-H 'accept: application/json' \
-H 'API-KEY: REDACTED'
{
"page_size": 50,
"page_number": 1,
"page_results_count": 1,
"total_results_count": 1,
"objects": [
{
"created": "2017-05-31T21:31:22.767Z",
"created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5",
"description": "Adversaries may use brute force techniques to gain access to accounts when passwords are unknown or when password hashes are obtained.(Citation: TrendMicro Pawn Storm Dec 2020) Without knowledge of the password for an account or set of accounts, an adversary may systematically guess the password using a repetitive or iterative mechanism.(Citation: Dragos Crashoverride 2018) Brute forcing passwords can take place via interaction with a service that will check the validity of those credentials or offline against previously acquired credential data, such as password hashes.\n\nBrute forcing credentials may take place at various points during a breach. For example, adversaries may attempt to brute force access to [Valid Accounts](https://attack.mitre.org/techniques/T1078) within a victim environment leveraging knowledge gathered from other post-compromise behaviors such as [OS Credential Dumping](https://attack.mitre.org/techniques/T1003), [Account Discovery](https://attack.mitre.org/techniques/T1087), or [Password Policy Discovery](https://attack.mitre.org/techniques/T1201). Adversaries may also combine brute forcing activity with behaviors such as [External Remote Services](https://attack.mitre.org/techniques/T1133) as part of Initial Access.",
"external_references": [
{
"source_name": "mitre-attack",
"url": "https://attack.mitre.org/techniques/T1110",
"external_id": "T1110"
},
{
"source_name": "TrendMicro Pawn Storm Dec 2020",
"description": "Hacquebord, F., Remorin, L. (2020, December 17). Pawn Storm’s Lack of Sophistication as a Strategy. Retrieved January 13, 2021.",
"url": "https://www.trendmicro.com/en_us/research/20/l/pawn-storm-lack-of-sophistication-as-a-strategy.html"
},
{
"source_name": "Dragos Crashoverride 2018",
"description": "Joe Slowik. (2018, October 12). Anatomy of an Attack: Detecting and Defeating CRASHOVERRIDE. Retrieved December 18, 2020.",
"url": "https://www.dragos.com/wp-content/uploads/CRASHOVERRIDE2018.pdf"
}
],
"id": "attack-pattern--a93494bb-4b80-4ea1-8695-3236a49916fd",
"kill_chain_phases": [
{
"kill_chain_name": "mitre-attack",
"phase_name": "credential-access"
}
],
"modified": "2024-10-14T22:11:30.271Z",
"name": "Brute Force",
"object_marking_refs": [
"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"
],
"revoked": false,
"spec_version": "2.1",
"type": "attack-pattern",
"x_mitre_attack_spec_version": "3.2.0",
"x_mitre_contributors": [
"David Fiser, @anu4is, Trend Micro",
"Alfredo Oliveira, Trend Micro",
"Magno Logan, @magnologan, Trend Micro",
"Yossi Weizman, Azure Defender Research Team",
"Ed Williams, Trustwave, SpiderLabs",
"Mohamed Kmal"
],
"x_mitre_data_sources": [
"User Account: User Account Authentication",
"Command: Command Execution",
"Application Log: Application Log Content"
],
"x_mitre_deprecated": false,
"x_mitre_detection": "Monitor authentication logs for system and application login failures of [Valid Accounts](https://attack.mitre.org/techniques/T1078). If authentication failures are high, then there may be a brute force attempt to gain access to a system using legitimate credentials. Also monitor for many failed authentication attempts across various accounts that may result from password spraying attempts. It is difficult to detect when hashes are cracked, since this is generally done outside the scope of the target network.",
"x_mitre_domains": [
"enterprise-attack"
],
"x_mitre_is_subtechnique": false,
"x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5",
"x_mitre_platforms": [
"Windows",
"SaaS",
"IaaS",
"Linux",
"macOS",
"Containers",
"Network",
"Office Suite",
"Identity Provider"
],
"x_mitre_version": "2.6"
}
]
}
Using ATT&CK references found in CAPECs linked to CWEs linked to CVEs, you can create a relationship between the CVE and ATT&CK Technique.
You can do this using arango_cve_processor in cve-attack
mode;
python3 arango_cve_processor.py \
--database blog_cve_demo_database \
--relationship cve-attack \
--ignore_embedded_relationships true
Running the query;
FOR doc IN nvd_cve_edge_collection
FILTER doc.source_ref == "vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380"
AND LENGTH(
doc.external_references[* FILTER CURRENT.source_name == "mitre-attack"]
) > 0
LET keys = ATTRIBUTES(doc)
LET filteredKeys = keys[* FILTER !STARTS_WITH(CURRENT, "_")]
RETURN [KEEP(doc, filteredKeys)]
Returns 10 results – the 10 ATT&CK references in the 9 CAPEC objects linked to the CVE.
Putting it all together
In summary we now have the following content in the database for CVE-2019-18988;
- Indicator -> Vulnerability (cve2stix)
- Indicator -> Software (cve2stix)
- Report (EPSS) (arango_cve_processor)
- Report (KEV) (arango_cve_processor)
- Indicator -> CWE (arango_cve_processor)
- Indicator -> CAPEC (arango_cve_processor)
- Indicator -> ATT&CK (arango_cve_processor)
The following search returns all the relationships (the edges of the graph) that exist for CVE-2019-18988;
FOR doc IN nvd_cve_edge_collection
FILTER (doc.source_ref=="vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380" OR doc.target_ref=="vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380")
OR LENGTH(
doc.external_references[* FILTER CURRENT.source_name == "cve" AND CURRENT.external_id == "CVE-2019-18988"]
) > 0
RETURN doc
Here is what is looks like on the default ArangoDB graph;
To get all the objects (edges and nodes) and export as a bundle (for your other security tooling), you can use the following search;
// Step 1: Fetch relevant edges
LET edges = (
FOR edge IN nvd_cve_edge_collection
FILTER (edge.source_ref == "vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380" OR edge.target_ref == "vulnerability--cc5ed17b-33d7-58bf-8c1c-7ad9fd323380")
OR LENGTH(
edge.external_references[* FILTER CURRENT.source_name == "cve" AND CURRENT.external_id == "CVE-2019-18988"]
) > 0
LET keys = ATTRIBUTES(edge)
LET filteredKeys = keys[* FILTER !STARTS_WITH(CURRENT, "_")]
RETURN KEEP(edge, filteredKeys)
)
// Step 2: Extract unique node references from the edges
LET edgeNodeRefs = UNIQUE(
FLATTEN(
edges[* RETURN [CURRENT.source_ref, CURRENT.target_ref]]
)
)
// Step 3: Fetch `kev`-labeled reports
LET kevReports = (
FOR doc IN nvd_cve_vertex_collection
FILTER doc.type == "report"
FILTER LENGTH(
doc.external_references[* FILTER CURRENT.source_name == "cve" AND CURRENT.external_id == "CVE-2019-18988"]
) > 0
AND "kev" IN doc.labels
LET keys = ATTRIBUTES(doc)
LET filteredKeys = keys[* FILTER !STARTS_WITH(CURRENT, "_")]
RETURN KEEP(doc, filteredKeys)
)
// Step 4: Fetch `epss`-labeled reports
LET epssReports = (
FOR doc IN nvd_cve_vertex_collection
FILTER doc.type == "report"
FILTER LENGTH(
doc.external_references[* FILTER CURRENT.source_name == "cve" AND CURRENT.external_id == "CVE-2019-18988"]
) > 0
AND "epss" IN doc.labels
LET keys = ATTRIBUTES(doc)
LET filteredKeys = keys[* FILTER !STARTS_WITH(CURRENT, "_")]
RETURN KEEP(doc, filteredKeys)
)
// Step 5: Fetch all nodes (from edgeNodeRefs and matching `kev`/`epss` reports)
LET allNodeRefs = UNIQUE(FLATTEN([edgeNodeRefs, kevReports[*].id, epssReports[*].id]))
LET nodes = (
FOR node IN nvd_cve_vertex_collection
FILTER node.id IN allNodeRefs
LET keys = ATTRIBUTES(node)
LET filteredKeys = keys[* FILTER !STARTS_WITH(CURRENT, "_")]
RETURN KEEP(node, filteredKeys)
)
// Step 6: Combine all objects and wrap in a bundle
RETURN {
"type": "bundle",
"id": CONCAT("bundle--", UUID()),
"objects": APPEND(edges, nodes)
}
When loading the bundle returned into a STIX viewer…
Going further
I’ve shown you enrichments from the starting point of a CVE.
However, if you imagine the wider intelligence graph in your mind, Software objects, CWEs, CAPECs and ATT&CK objects will be linked to other vulnerabilities.
What this means is that you can pivot from these objects on the graph, asking the question; what else is this linked too?
For example, the following query will return all vulnerabilities are linked to CWE-521
FOR edge IN nvd_cve_edge_collection
FILTER edge.target_ref == "weakness--de02e88c-42c5-5ddf-b5d1-1c8aeac79926"
RETURN edge
That’s a really simple example. I’ll cover this type of exploration in detail in a future post.
Cheat code
Querying the CVE bundle endpoint on Vulmatch as follows;
curl -X 'GET' \
'http://api.vulmatch/v1/cve/objects/CVE-2019-18988/bundle/' \
-H 'accept: application/json' \
-H 'API-KEY: REDACTED'
Will return the same bundle, without all the manual work!
Vulmatch
Straightforward vulnerability management. Know when software you use is vulnerable, how it is being exploited, and how to detect an attack.
CTI Butler
One API. Much CTI. CTI Butler is the API used by the world's leading cyber-security companies.
Discuss this post
Head on over to the dogesec community to discuss this post.
Never miss an update
Sign up to receive new articles in your inbox as they published.