def test_call_update_exploits(self, get_file): self.assertEqual(Search().index(CveDocument.Index.name).count(), 2) get_file.return_value = self.data update_exploits() get_file.assert_called_once_with( 'https://www.cve-search.org/feeds/via4.json') thread_pool_executor.wait_for_all() self.assertEqual(Search().index(CveDocument.Index.name).count(), 2) cve = CveDocument.search().filter( 'term', id='CVE-2017-0008').sort('-modified_date').execute().hits[0] prev_modified_date = cve.modified_date self.assertEqual(len(cve.exploits), 1) self.assertEqual(cve.exploits, [{ 'id': '44904', 'url': 'https://www.exploit-db.com/exploits/44904' }]) update_exploits() thread_pool_executor.wait_for_all() self.assertEqual(Search().index(CveDocument.Index.name).count(), 2) cve = CveDocument.search().filter( 'term', id='CVE-2017-0008').sort('-modified_date').execute().hits[0] self.assertEqual(cve.modified_date, prev_modified_date) self.assertEqual(len(cve.exploits), 1) self.assertEqual(cve.exploits, [{ 'id': '44904', 'url': 'https://www.exploit-db.com/exploits/44904' }])
def test_cwe_update(self): cwe = CweDocument.search().filter('term', id='CWE-200').execute().hits[0] cwe.name = 'Changed' cwe.save() thread_pool_executor.wait_for_all() self.assertEqual( CveDocument.search().filter('term', id='CVE-2017-0008').count(), 1) cve = CveDocument.search().filter('term', id='CVE-2017-0008').execute().hits self.assertEqual(len(cve), 1) self.assertEqual(cve[0].cwe.name, 'Changed')
def create(item: dict): if '** REJECT **' not in CveFactory.summary(item): old = CveDocument.search().filter( 'term', id=CveFactory.get_id(item)).sort( '-last_modified_date')[0].execute() if old.hits: last_modified_date = old.hits[0].last_modified_date else: last_modified_date = None if not last_modified_date or last_modified_date < CveFactory.last_modified_date( item): cve = CveDocument(id=CveFactory.get_id(item)) for field in CveDocument.get_fields_name(): parser = getattr(CveFactory, field, None) if parser: try: setattr(cve, field, parser(item)) except Exception as err: logging.debug( F'cve id {cve.id}, field {field}, err {err}') for cpe in CveFactory.get_cpe(item): cve.cpe.append(cpe) if old.hits and cve.has_changed(old.hits[0]): return old.hits[0].update(cve, weak=True) else: return cve.save(weak=True) return None logging.info(F'cve id {CveFactory.get_id(item)} is rejected') return None
def test_update(self): cve = CveDocument.search().filter('term', id='CVE-2017-0002').execute().hits[0] cve.last_modified_date = None cve.save(refresh=True) with open(get_fixture_location(__file__, 'nvdcve-1.0-2017.json')) as handle: CveFactory.process(handle) thread_pool_executor.wait_for_all() self.assertEqual( CveDocument.search().filter('term', id='CVE-2017-0002').count(), 1) new_cve = CveDocument.search().filter( 'term', id='CVE-2017-0002').execute().hits[0] self.assertTrue(cve.last_modified_date != new_cve.last_modified_date)
def get_cve_sets(asset_count): cve_sets = {name: set() for name in CPE_LIST.keys()} cve_cvss_3 = CveDocument.search().filter('exists', field='base_score_v3') cve_cvss_2 = CveDocument.search() cve_count = 0 while cve_count < asset_count * 4: cve_count = 0 for os in CPE_LIST: max_cve = cve_cvss_3.filter( 'wildcard', cpe__name=F'*{CPE_LIST[os]}*').query(RAND_QUERY).count() count = random.randint(1, max_cve) if max_cve > 0: cves = cve_cvss_3.filter( 'wildcard', cpe__name=F'*{CPE_LIST[os]}*').query(RAND_QUERY)[0:count] else: cves = cve_cvss_2.filter( 'wildcard', cpe__name=F'*{CPE_LIST[os]}*').query(RAND_QUERY)[0:count] cve_sets[os].update(cve for cve in cves) for cve in cve_sets: cve_count += len(cve_sets[cve]) print(F'The amount of cve drawn: {cve_count}, ' F'assets count: {asset_count}, ' F'ratio: {round(cve_count / asset_count, 2)}') for os_name in cve_sets: print( F'System name: {os_name}, cve pool count: {len(cve_sets[os_name])}' ) return {k: list(v) for k, v in cve_sets.items()}
def test_call_create(self): cve = CveDocument.search().filter('term', id='CVE-2017-0008').execute().hits[0] self.assertEqual(cve.base_score_v2, 4.3) self.assertEqual(cve.base_score_v3, 4.3) self.assertEqual( cve.summary, 'Microsoft Internet Explorer 9 through 11 allow remote attackers to obtain sensitive ' 'information from process memory via a crafted web site, aka "Internet Explorer Information ' 'Disclosure Vulnerability." This vulnerability is different from those described in ' 'CVE-2017-0009 and CVE-2017-0059.') self.assertEquals(str(cve.published_date), '2017-03-17 00:59:00+00:00') self.assertEquals(str(cve.last_modified_date), '2017-07-12 01:29:00+00:00') self.assertEqual(cve.cwe.id, 'CWE-200') self.assertEqual(len(cve.cpe), 3) self.assertEqual(cve.cpe, [{ 'name': 'cpe:2.3:a:microsoft:internet_explorer:9:*:*:*:*:*:*:*', 'vendor': 'microsoft' }, { 'name': 'cpe:2.3:a:microsoft:internet_explorer:10:*:*:*:*:*:*:*', 'vendor': 'microsoft' }, { 'name': 'cpe:2.3:a:microsoft:internet_explorer:11:*:*:*:*:*:*:*', 'vendor': 'microsoft' }]) self.assertEqual(cve.access_vector_v2, metrics.AccessVectorV2.NETWORK) self.assertEqual(cve.access_complexity_v2, metrics.AccessComplexityV2.MEDIUM) self.assertEqual(cve.authentication_v2, metrics.AuthenticationV2.NONE) self.assertEqual(cve.confidentiality_impact_v2, metrics.ImpactV2.PARTIAL) self.assertEqual(cve.integrity_impact_v2, metrics.ImpactV2.NONE) self.assertEqual(cve.availability_impact_v2, metrics.ImpactV2.NONE) self.assertEqual(cve.attack_vector_v3, metrics.AttackVectorV3.NETWORK) self.assertEqual(cve.attack_complexity_v3, metrics.AttackComplexityV3.LOW) self.assertEqual(cve.privileges_required_v3, metrics.PrivilegesRequiredV3.NONE) self.assertEqual(cve.user_interaction_v3, metrics.UserInteractionV3.REQUIRED) self.assertEqual(cve.scope_v3, metrics.ScopeV3.UNCHANGED) self.assertEqual(cve.confidentiality_impact_v3, metrics.ImpactV3.LOW) self.assertEqual(cve.integrity_impact_v3, metrics.ImpactV3.NONE) self.assertEqual(cve.availability_impact_v3, metrics.ImpactV3.NONE) self.assertEqual(cve.get_privileges_required_v3_value(), 0.85)
def create(key: str, value: dict) -> [CveDocument, None]: try: exploits = [] for exp_id in value['refmap']['exploit-db']: exploits.append(ExploitInnerDoc.create(exp_id=exp_id)) except KeyError: pass else: result = CveDocument.search().filter('term', id=key)[0].execute() if result.hits and result.hits[0].exploits != exploits: result.hits[0].exploits = exploits return result.hits[0] return None
def test_call_call_not_update(self): with open(get_fixture_location(__file__, 'nvdcve-1.0-2017-2.json')) as handle: CveFactory.process(handle) thread_pool_executor.wait_for_all() result = CveDocument.search().filter('term', id='CVE-2017-0002').execute() self.assertEqual(len(result.hits), 1) cve = result.hits[0] self.assertEqual(cve.id, 'CVE-2017-0002') self.assertEqual(cve.access_vector_v2, metrics.AccessVectorV2.NETWORK) self.assertEqual(cve.access_complexity_v2, metrics.AccessComplexityV2.MEDIUM) self.assertEqual(cve.authentication_v2, metrics.AuthenticationV2.NONE) self.assertEqual(cve.confidentiality_impact_v2, metrics.ImpactV2.PARTIAL) self.assertEqual(cve.integrity_impact_v2, metrics.ImpactV2.PARTIAL) self.assertEqual(cve.availability_impact_v2, metrics.ImpactV2.PARTIAL)
def test_calculate_base_score(self): for cve in CveDocument.search(): self.assertEqual(cve.base_score_v2, calculate_base_score_v2(cve), cve.id) self.assertEqual(cve.base_score_v3, calculate_base_score_v3(cve), cve.id)
def test_call_call_not_create_rejected(self): self.assertFalse(CveDocument.search().filter( 'term', id='CVE-2017-0605').execute())
def get_value(value): return value if value else '' def summary(d_cwe, d_cve): text = ' '.join([ get_value(d_cwe.name), get_value(d_cwe.description), get_value(d_cwe.extended_description), get_value(d_cve) ]) return text.translate(str.maketrans('', '', '\n\t\r')).replace('|', ' ') if __name__ == 'main': all_count = CveDocument.search().count() print('All CVE count', all_count) search = CveDocument.search().filter('exists', field='base_score_v3') count = search.count() print('CVE with 3.1 score:', count) print('CVE CVSSv3/CVSSv2', count / all_count * 100) print('Downloading data') cves = [c for c in search.scan()] print('Downloaded data') with open(OUTPUT_FILE, 'w', encoding='utf-8') as out: for cve in cves: k = '|'.join([ str(cve.base_score_v2),