Esempio n. 1
0
    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
Esempio n. 2
0
class CveFactory:
    FIELDS = [i for i in CveDocument.get_fields_name()]

    @staticmethod
    def process(handle):
        data = json.load(handle)
        docs = []
        for obj in data['CVE_Items']:
            cve = CveFactory.create(obj)

            if cve:
                docs.append(cve.to_dict(include_meta=True))

            if len(docs) > 500:
                async_bulk(docs, CveDocument.Index.name)
                docs = []

        async_bulk(docs, CveDocument.Index.name)

    @staticmethod
    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

    @staticmethod
    def get_id(item: dict) -> str:
        return item['cve']['CVE_data_meta']['ID']

    @staticmethod
    def base_score_v2(item: dict) -> [float, None]:
        return CveFactory.base_score('cvssV2', item)

    @staticmethod
    def base_score_v3(item: dict) -> [float, None]:
        return CveFactory.base_score('cvssV3', item)

    @staticmethod
    def base_score(version: str, item: dict) -> [float, None]:
        score = CveFactory.value_from_base_metrics(version, 'baseScore', item)
        return float(score) if score else None

    @staticmethod
    def summary(item: dict) -> str:
        for desc in item['cve']['description']['description_data']:
            if desc['lang'] == 'en':
                return desc['value']
        return str()

    @staticmethod
    def references(item: RestrictedElement) -> str:
        objs = []
        for ref in item['cve']['references']['reference_data']:
            objs.append({'source': ref['refsource'], 'url': ref['url']})
        return json.dumps(objs)

    @staticmethod
    def cwe(item: dict) -> CweDocument:
        for problemtype_data in item['cve']['problemtype']['problemtype_data']:
            for desc in problemtype_data['description']:
                if desc['lang'] == 'en':
                    return CWEFactory.get(desc['value'])

    @staticmethod
    def get_cpe(item: dict) -> list:
        cpes = []
        try:
            for conf in item['configurations']['nodes']:
                for cpe_match in conf['cpe_match']:
                    cpes.append(CpeFactory.get(cpe_match['cpe23Uri']))
        except (KeyError, IndexError):
            pass
        return cpes

    @staticmethod
    def published_date(item: dict) -> datetime:
        return parse_datetime(item['publishedDate'])

    @staticmethod
    def last_modified_date(item: dict) -> datetime:
        return parse_datetime(item['lastModifiedDate'])

    @staticmethod
    def access_vector_v2(item: dict) -> metrics.AccessVectorV2:
        av = CveFactory.value_from_base_metrics('cvssV2', 'accessVector', item)
        return metrics.AccessVectorV2(av).value

    @staticmethod
    def access_complexity_v2(item: dict) -> metrics.AccessComplexityV2:
        ac = CveFactory.value_from_base_metrics('cvssV2', 'accessComplexity',
                                                item)
        return metrics.AccessComplexityV2(ac).value

    @staticmethod
    def authentication_v2(item: dict) -> metrics.AuthenticationV2:
        auth = CveFactory.value_from_base_metrics('cvssV2', 'authentication',
                                                  item)
        return metrics.AuthenticationV2(auth).value

    @staticmethod
    def confidentiality_impact_v2(item: dict) -> metrics.ImpactV2:
        imp = CveFactory.value_from_base_metrics('cvssV2',
                                                 'confidentialityImpact', item)
        return metrics.ImpactV2(imp).value

    @staticmethod
    def integrity_impact_v2(item: dict) -> metrics.ImpactV2:
        imp = CveFactory.value_from_base_metrics('cvssV2', 'integrityImpact',
                                                 item)
        return metrics.ImpactV2(imp).value

    @staticmethod
    def availability_impact_v2(item: dict) -> metrics.ImpactV2:
        imp = CveFactory.value_from_base_metrics('cvssV2',
                                                 'availabilityImpact', item)
        return metrics.ImpactV2(imp).value

    @staticmethod
    def attack_vector_v3(item: dict) -> metrics.AttackVectorV3:
        av = CveFactory.value_from_base_metrics('cvssV3', 'attackVector', item)
        return metrics.AttackVectorV3(av).value

    @staticmethod
    def attack_complexity_v3(item: dict) -> metrics.AttackComplexityV3:
        ac = CveFactory.value_from_base_metrics('cvssV3', 'attackComplexity',
                                                item)
        return metrics.AttackComplexityV3(ac).value

    @staticmethod
    def privileges_required_v3(item: dict) -> metrics.PrivilegesRequiredV3:
        pr = CveFactory.value_from_base_metrics('cvssV3', 'privilegesRequired',
                                                item)
        return metrics.PrivilegesRequiredV3(pr).value

    @staticmethod
    def user_interaction_v3(item: dict) -> metrics.UserInteractionV3:
        us = CveFactory.value_from_base_metrics('cvssV3', 'userInteraction',
                                                item)
        return metrics.UserInteractionV3(us).value

    @staticmethod
    def scope_v3(item: dict) -> metrics.ScopeV3:
        sc = CveFactory.value_from_base_metrics('cvssV3', 'scope', item)
        return metrics.ScopeV3(sc).value

    @staticmethod
    def confidentiality_impact_v3(item: dict) -> metrics.ImpactV3:
        ci = CveFactory.value_from_base_metrics('cvssV3',
                                                'confidentialityImpact', item)
        return metrics.ImpactV3(ci).value

    @staticmethod
    def integrity_impact_v3(item: dict) -> metrics.ImpactV3:
        ii = CveFactory.value_from_base_metrics('cvssV3', 'integrityImpact',
                                                item)
        return metrics.ImpactV3(ii).value

    @staticmethod
    def availability_impact_v3(item: dict) -> metrics.ImpactV3:
        ai = CveFactory.value_from_base_metrics('cvssV3', 'availabilityImpact',
                                                item)
        return metrics.ImpactV3(ai).value

    @staticmethod
    def value_from_base_metrics(version: str, value: str,
                                item: dict) -> [str, None]:
        return item['impact']['baseMetricV2' if version ==
                              'cvssV2' else 'baseMetricV3'][version][value]