add: [vulnerability_lookup] Enhanced CSAF format parsing

- Supporting NCSC-NL CSAF format & the CISA CSAF
    format prefixed with `va`
- Extracting cpe information from `product_tree`
    for all the CSAF formats
pull/709/head
Christian Studer 2024-12-16 16:41:01 +01:00
parent 8b3da50c57
commit 4ff402e117
No known key found for this signature in database
GPG Key ID: 6BBED1B63A6D639F
1 changed files with 15 additions and 2 deletions

View File

@ -74,8 +74,8 @@ class VulnerabilityLookupMapping(VulnerabilityMapping):
__source_mapping.update(
dict.fromkeys(
(
'cisco', 'icsa', 'icsma', 'nn', 'oxas',
'rhba', 'rhea', 'rhsa', 'sca', 'ssa', 'wid'
'cisco', 'icsa', 'icsma', 'ncsc', 'nn', 'oxas',
'rhba', 'rhea', 'rhsa', 'sca', 'ssa', 'va', 'wid'
),
'_parse_csaf_description'
)
@ -161,6 +161,15 @@ class VulnerabilityLookupParser(VulnerabilityParser):
feature = self.mapping.source_mapping(alias.split('-')[0].lower())
yield getattr(self, feature)(vulnerability)
def _parse_csaf_branch(self, branch: list) -> Iterator[str]:
for sub_branch in branch:
if sub_branch.get('branches'):
yield from self._parse_csaf_branch(sub_branch['branches'])
else:
cpe = sub_branch.get('product', {}).get('product_identification_helper', {}).get('cpe')
if cpe is not None:
yield cpe
def _parse_csaf_description(self, lookup_result: dict) -> str:
description = lookup_result['document']
@ -172,6 +181,10 @@ class VulnerabilityLookupParser(VulnerabilityParser):
for reference in description.get('references', []):
misp_object.add_attribute('references', reference['url'])
misp_object.add_attribute('credit', description['publisher']['name'])
branches = lookup_result.get('product_tree', {}).get('branches', [])
if branches:
for cpe in set(self._parse_csaf_branch(branches)):
misp_object.add_attribute('vulnerable-configuration', cpe)
misp_object.add_reference(self.misp_attribute.uuid, 'describes')
vulnerability_object = self.misp_event.add_object(misp_object)