Skip to content

Commit

Permalink
Add new equivalent CPE and improve wildcard handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ra1nb0rn committed Nov 9, 2023
1 parent 9f25e2d commit 89da02f
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 9 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# Changelog
This file keeps track of all notable changes between the different versions of search_vulns.

## v0.4.5 - 2023-11-09
### Added
- New CPE equivalence for Handlebars.js.
- New test cases for Handlebars.js.

### Fixed
- Expand CPE wildcard replacement when searching for vulnerabilities with an exactly matching CPE.


## v0.4.4 - 2023-11-08
### Fixed
- Update test cases with new CVE.
Expand Down
3 changes: 2 additions & 1 deletion man_equiv_cpes.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@
"cpe:2.3:a:citrix:netscaler_application_delivery_controller:": ["cpe:2.3:a:citrix:application_delivery_controller:"],
"cpe:2.3:h:citrix:netscaler_application_delivery_controller:": ["cpe:2.3:h:citrix:application_delivery_controller:"],
"cpe:2.3:o:citrix:netscaler_application_delivery_controller_firmware:": ["cpe:2.3:o:citrix:application_delivery_controller_firmware:"],
"cpe:2.3:a:citrix:provisioning_services:": ["cpe:2.3:a:citrix:provisioning:"]
"cpe:2.3:a:citrix:provisioning_services:": ["cpe:2.3:a:citrix:provisioning:"],
"cpe:2.3:a:handlebarsjs:handlebars:": ["cpe:2.3:a:handlebars.js_project:handlebars.js:"]
}
37 changes: 30 additions & 7 deletions search_vulns.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,36 @@ def printit(text: str = "", end: str = "\n", color=SANE):

def get_exact_vuln_matches(cpe, db_cursor):
"""Get vulns whose cpe entry matches the given one exactly"""
query_cpe = ':'.join(cpe.split(':')[:7]) + ':%%'
query = "SELECT DISTINCT cpe, cve_id, with_cpes FROM cve_cpe WHERE cpe LIKE ?"
pot_vulns = db_cursor.execute(query, (query_cpe, )).fetchall()

cpe_split = cpe.split(':')
query_cpe1 = ':'.join(cpe_split[:7]) + ':%%'

# create main CPE to query for and alt cpes with wildcards '*' and '-' replaced by each other
query_cpes = [query_cpe1]
repl_version, repl_update = '', ''
if cpe_split[5] == '*':
repl_version = '-'
elif cpe_split[5] == '-':
repl_version = '*'

if repl_version:
query_cpes.append(':'.join(cpe_split[:5]) + ':' + repl_version + ':' + cpe_split[6] + ':%%')

if cpe_split[6] == '*':
repl_update = '-'
elif cpe_split[6] == '-':
repl_update = '*'

if repl_update:
query_cpes.append(':'.join(cpe_split[:6]) + ':' + repl_update + ':%%')

if repl_version and repl_update:
query_cpes.append(':'.join(cpe_split[:5]) + ':' + repl_version + ':' + repl_update + ':%%')

# query for vulns with all retrieved variants of the supplied CPE
or_str = 'OR cpe LIKE ?' * (len(query_cpes) - 1)
query = "SELECT DISTINCT cpe, cve_id, with_cpes FROM cve_cpe WHERE cpe LIKE ? " + or_str
pot_vulns = db_cursor.execute(query, query_cpes).fetchall()
vulns = []
for vuln_cpe, cve_id, with_cpes in pot_vulns:
if is_cpe_included_after_version(cpe, vuln_cpe):
Expand Down Expand Up @@ -184,10 +211,6 @@ def get_vulns(cpe, db_cursor, ignore_general_cpe_vulns=False, add_other_exploit_
vulns += get_exact_vuln_matches(cpe, db_cursor)
vulns += get_vulns_version_start_end_matches(cpe, cpe_parts, db_cursor, ignore_general_cpe_vulns)

if ':-:' in cpe:
# use '-' as wildcard and query for additional exact matches
vulns += get_exact_vuln_matches(cpe.replace(':-:', ':*:'), db_cursor)

# retrieve more information about the found vulns, e.g. CVSS scores and possible exploits
detailed_vulns = {}
for vuln_info in vulns:
Expand Down
12 changes: 12 additions & 0 deletions tests/test_cve_attr_completeness.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ def test_search_hitachi_replication_manager_86500(self):
self.assertEqual(cve_attrs['cvss'], expected_attrs[cve]['cvss'])
self.assertEqual(cve_attrs['cvss_vec'], expected_attrs[cve]['cvss_vec'])

def test_search_handlebars_js_300(self):
self.maxDiff = None
result = search_vulns.search_vulns(query='cpe:2.3:a:handlebarsjs:handlebars:3.0.0:*:*:*:*:node.js:*:*', add_other_exploit_refs=True, is_good_cpe=False)
expected_attrs = {'CVE-2021-23369': {'published': '2021-04-12 14:15:14', 'cvss_ver': '3.1', 'cvss': '9.8', 'cvss_vec': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H'}, 'CVE-2019-20920': {'published': '2020-09-30 18:15:17', 'cvss_ver': '3.1', 'cvss': '8.1', 'cvss_vec': 'CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:L/A:L'}, 'CVE-2021-23383': {'published': '2021-05-04 09:15:07', 'cvss_ver': '3.1', 'cvss': '9.8', 'cvss_vec': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H'}, 'CVE-2019-19919': {'published': '2019-12-20 23:15:11', 'cvss_ver': '3.1', 'cvss': '9.8', 'cvss_vec': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H'}, 'CVE-2015-8861': {'published': '2017-01-23 21:59:00', 'cvss_ver': '3.1', 'cvss': '6.1', 'cvss_vec': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N'}}

for cve, cve_attrs in result.items():
self.assertIn(cve, expected_attrs)
self.assertEqual(cve_attrs['published'], expected_attrs[cve]['published'])
self.assertEqual(cve_attrs['cvss_ver'], expected_attrs[cve]['cvss_ver'])
self.assertEqual(cve_attrs['cvss'], expected_attrs[cve]['cvss'])
self.assertEqual(cve_attrs['cvss_vec'], expected_attrs[cve]['cvss_vec'])


if __name__ == '__main__':
unittest.main()
6 changes: 6 additions & 0 deletions tests/test_cve_completeness.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ def test_search_hitachi_replication_manager_86500(self):
expected_cves = ['CVE-2022-4146', 'CVE-2020-36695', 'CVE-2019-17360']
self.assertEqual(set(expected_cves), set(list(result.keys())))

def test_search_handlebars_js_300(self):
self.maxDiff = None
result = search_vulns.search_vulns(query='cpe:2.3:a:handlebarsjs:handlebars:3.0.0:*:*:*:*:node.js:*:*', add_other_exploit_refs=True, is_good_cpe=False)
expected_cves = ['CVE-2019-19919', 'CVE-2021-23369', 'CVE-2021-23383', 'CVE-2019-20920', 'CVE-2015-8861']
self.assertEqual(set(expected_cves), set(list(result.keys())))


if __name__ == '__main__':
unittest.main()
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.4.4
0.4.5

0 comments on commit 89da02f

Please sign in to comment.