Exemple #1
0
def create_user(username, email, password, admin):
    """Create a user or admin."""
    if User.query.filter_by(username=username).first():
        raise click.BadParameter(f"{username} already exists.",
                                 param_hint="username")
    if User.query.filter_by(email=email).first():
        raise click.BadParameter(f"{email} already exists.",
                                 param_hint="email")

    user = User(
        username=username,
        email=email,
        active=True,
        admin=admin,
        email_confirmed_at=datetime.datetime.utcnow(),
        password=app.user_manager.hash_password(password),
    )
    db.session.add(user)

    try:
        db.session.commit()
    except IntegrityError as e:
        error(e)
    else:
        info("User {} created.".format(username))
Exemple #2
0
def import_data(confirm):
    """
    Perform initial imports (cve, cwe, cpe).
    """
    if Cve.query.first():
        info("Import already done.")
        return

    if not confirm:
        msg = ("This command will import initial data in your database. "
               "Do you want to continue ?".format(CVE_FIRST_YEAR,
                                                  CURRENT_YEAR))
        if not click.confirm(msg):
            info("Bye.")
            return

    # Import the CWE list
    cwe.run()

    # Import the CVE, then use the returned list of vendors
    # to merge them with the official CPE dictionnary list.
    vendors = cve.run()
    cpe.run(vendors)

    # Populate the metas table
    with timed_operation("Populating metas table..."):
        meta = Meta(name="nvd_last_sha256", value="default")
        db.session.add(meta)
        db.session.commit()
Exemple #3
0
def init():
    """Initialize the configuration file."""
    path, created = create_config()
    if created:
        info(f"Configuration created in {path}")
    else:
        error(f"Configuration already exists ({path})")
Exemple #4
0
    def create_change(cls, cve_obj, cve_json, task, events):
        change = Change(
            created_at=arrow.get(cve_json["lastModifiedDate"]).datetime,
            updated_at=arrow.get(cve_json["lastModifiedDate"]).datetime,
            cve=cve_obj,
            task=task,
            events=events,
            json=cve_json,
        )
        db.session.add(change)
        db.session.commit()

        info("Change created (ID: {})".format(change.id))
        return change
Exemple #5
0
    def create_event(cls, cve_obj, cve_json, type, payload={}):
        event = Event(
            created_at=arrow.get(cve_json["lastModifiedDate"]).datetime,
            updated_at=arrow.get(cve_json["lastModifiedDate"]).datetime,
            cve=cve_obj,
            type=type,
            details=payload,
            review=False,
        )
        db.session.add(event)
        db.session.commit()

        info("Event {} created (ID: {})".format(type, event.id))
        return event
Exemple #6
0
def run(mappings):
    """
    Import the Vendors and Products list.
    """
    header("Importing CPE list...")

    # Download the XML file
    with timed_operation("Downloading {}...".format(NVD_CPE_URL)):
        resp = requests.get(NVD_CPE_URL).content

    # Parse the XML elements
    with timed_operation("Parsing XML elements..."):
        raw = gzip.GzipFile(fileobj=BytesIO(resp)).read()
        obj = untangle.parse(raw.decode("utf-8"))
        items = obj.cpe_list.cpe_item
        del obj

    # Create the objects
    with timed_operation("Creating list of mappings..."):
        for item in items:
            obj = CPE(item.cpe_23_cpe23_item["name"])
            vendor = obj.get_vendor()[0]
            product = obj.get_product()[0]

            if vendor not in mappings["vendors"].keys():
                mappings["vendors"][vendor] = dict(id=get_uuid(), name=vendor)

            if get_slug(vendor, product) not in mappings["products"].keys():
                mappings["products"][get_slug(vendor, product)] = dict(
                    id=get_uuid(),
                    name=product,
                    vendor_id=mappings["vendors"][vendor]["id"],
                )
        del items

    # Insert the objects in database
    with timed_operation("Inserting Vendors and Products..."):
        db.session.bulk_insert_mappings(Vendor, mappings["vendors"].values())
        db.session.bulk_insert_mappings(Product, mappings["products"].values())
        db.session.commit()

    info(
        "{} vendors and {} products imported.".format(
            len(mappings["vendors"]), len(mappings["products"])
        )
    )
    del mappings
Exemple #7
0
def create_user(username, email, password, admin):
    """Create a user or admin."""
    user = User(
        username=username,
        email=email,
        active=True,
        admin=admin,
        email_confirmed_at=datetime.datetime.utcnow(),
        password=app.user_manager.hash_password(password),
    )
    db.session.add(user)

    try:
        db.session.commit()
    except IntegrityError as e:
        error(e)
    else:
        info("User {} created.".format(username))
Exemple #8
0
    def execute(self):
        old = self.cve_obj.cwes
        new = [
            c["value"] for c in self.cve_json["cve"]["problemtype"]
            ["problemtype_data"][0]["description"]
        ]

        payload = {
            "added": list(set(new) - set(old)),
            "removed": list(set(old) - set(new)),
        }

        # It's possible that a CVE links a CWE not yet defined in database.
        # In this case we'll save it in the `cwes` table and a periodic task
        # will populate later its name and description using the MITRE file.
        for cwe_id in payload["added"]:
            cwe = Cwe.query.filter_by(cwe_id=cwe_id).first()

            if not cwe:
                info(
                    f"{cwe_id} detected in {self.cve_obj.cve_id} but not existing in database, adding it..."
                )
                cwe = Cwe(cwe_id=cwe_id)
                db.session.add(cwe)
                db.session.commit()

        # If the list of CWE changed
        if payload["added"] or payload["removed"]:

            # Save the new list
            self.cve_obj.cwes = new
            db.session.commit()

            # Create the event
            event = CveUtil.create_event(self.cve_obj, self.cve_json, "cwes",
                                         payload)
            return event

        return None
Exemple #9
0
def run():
    """
    Import the CWE list.
    """
    header("Importing CWE list...")

    # Download the file
    with timed_operation("Downloading {}...".format(MITRE_CWE_URL)):
        resp = requests.get(MITRE_CWE_URL).content

    # Parse weaknesses
    with timed_operation("Parsing cwes..."):
        z = ZipFile(BytesIO(resp))
        raw = z.open(z.namelist()[0]).read()
        obj = untangle.parse(raw.decode("utf-8"))
        weaknesses = obj.Weakness_Catalog.Weaknesses.Weakness
        categories = obj.Weakness_Catalog.Categories.Category

    # Create the objects
    cwes = {}
    with timed_operation("Creating mappings..."):
        for c in weaknesses + categories:
            cwes[c["ID"]] = dict(
                id=get_uuid(),
                cwe_id=f"CWE-{c['ID']}",
                name=c["Name"],
                description=c.Description.cdata
                if hasattr(c, "Description") else c.Summary.cdata,
            )

    # Insert the objects in database
    with timed_operation("Inserting CWE..."):
        db.session.bulk_insert_mappings(Cwe, cwes.values())
        db.session.commit()

    info("{} CWE imported.".format(len(cwes)))
    del cwes
Exemple #10
0
def run():
    """
    Import the CVE list.
    """
    mappings = {"vendors": {}, "products": {}}

    from opencve.commands.imports import CURRENT_YEAR, CVE_FIRST_YEAR

    # Create the initial task
    task = Task()
    db.session.add(task)
    db.session.commit()
    task_id = task.id

    for year in range(CVE_FIRST_YEAR, CURRENT_YEAR + 1):
        header("Importing CVE for {}".format(year))
        mappings.update({"cves": [], "changes": []})

        # Download the file
        url = NVD_CVE_URL.format(year=year)
        with timed_operation("Downloading {}...".format(url)):
            resp = requests.get(url).content

        # Parse the XML elements
        with timed_operation("Parsing JSON elements..."):
            raw = gzip.GzipFile(fileobj=BytesIO(resp)).read()
            del resp
            items = json.loads(raw.decode("utf-8"))["CVE_Items"]
            del raw

        with timed_operation("Creating model objects..."):

            for item in items:
                cve_db_id = get_uuid()
                summary = item["cve"]["description"]["description_data"][0]["value"]
                cvss2 = (
                    item["impact"]["baseMetricV2"]["cvssV2"]["baseScore"]
                    if "baseMetricV2" in item["impact"]
                    else None
                )
                cvss3 = (
                    item["impact"]["baseMetricV3"]["cvssV3"]["baseScore"]
                    if "baseMetricV3" in item["impact"]
                    else None
                )

                # Construct CWE and CPE lists
                cwes = get_cwes(
                    item["cve"]["problemtype"]["problemtype_data"][0]["description"]
                )
                cpes = convert_cpes(item["configurations"])
                vendors = flatten_vendors(cpes)

                # Create the CVEs mappings
                mappings["cves"].append(
                    dict(
                        id=cve_db_id,
                        cve_id=item["cve"]["CVE_data_meta"]["ID"],
                        summary=summary,
                        json=item,
                        vendors=vendors,
                        cwes=cwes,
                        cvss2=cvss2,
                        cvss3=cvss3,
                        created_at=arrow.get(item["publishedDate"]).datetime,
                        updated_at=arrow.get(item["lastModifiedDate"]).datetime,
                    )
                )

                # Create the vendors and their products
                for vendor, products in cpes.items():

                    # Create the vendor
                    if vendor not in mappings["vendors"].keys():
                        mappings["vendors"][vendor] = dict(id=get_uuid(), name=vendor)

                    for product in products:
                        if get_slug(vendor, product) not in mappings["products"].keys():
                            mappings["products"][get_slug(vendor, product)] = dict(
                                id=get_uuid(),
                                name=product,
                                vendor_id=mappings["vendors"][vendor]["id"],
                            )

        # Insert the objects in database
        with timed_operation("Inserting CVE..."):
            db.session.bulk_insert_mappings(Cve, mappings["cves"])
            db.session.commit()

            # Create the changes based on CVEs data
            for cve in mappings["cves"]:
                mappings["changes"].append(
                    dict(
                        id=get_uuid(),
                        created_at=cve["created_at"],
                        updated_at=cve["updated_at"],
                        json=cve["json"],
                        cve_id=cve["id"],
                        task_id=task_id,
                    )
                )
            db.session.bulk_insert_mappings(Change, mappings["changes"])
            db.session.commit()

        info("{} CVE imported.".format(len(mappings["cves"])))

        # Free the memory after each processed year
        del mappings["cves"]
        del mappings["changes"]

    return mappings
Exemple #11
0
    def create_cve(cls, cve_json):
        cvss2 = (cve_json["impact"]["baseMetricV2"]["cvssV2"]["baseScore"]
                 if "baseMetricV2" in cve_json["impact"] else None)
        cvss3 = (cve_json["impact"]["baseMetricV3"]["cvssV3"]["baseScore"]
                 if "baseMetricV3" in cve_json["impact"] else None)

        # Construct CWE and CPE lists
        cwes = get_cwes(cve_json["cve"]["problemtype"]["problemtype_data"][0]
                        ["description"])
        cpes = convert_cpes(cve_json["configurations"])
        vendors = flatten_vendors(cpes)

        # Create the CVE
        cve = Cve(
            cve_id=cve_json["cve"]["CVE_data_meta"]["ID"],
            summary=cve_json["cve"]["description"]["description_data"][0]
            ["value"],
            json=cve_json,
            vendors=vendors,
            cwes=cwes,
            cvss2=cvss2,
            cvss3=cvss3,
            created_at=arrow.get(cve_json["publishedDate"]).datetime,
            updated_at=arrow.get(cve_json["lastModifiedDate"]).datetime,
        )
        db.session.add(cve)
        db.session.commit()

        # Add the CWE that not exists yet in database
        for cwe in cwes:
            cwe_obj = Cwe.query.filter_by(cwe_id=cwe).first()
            if not cwe_obj:
                info(
                    f"{cwe} detected in {cve.cve_id} but not existing in database, adding it..."
                )
                cwe_obj = Cwe(cwe_id=cwe)
                db.session.add(cwe_obj)
                db.session.commit()

        # Add the CPEs
        vendors_products = convert_cpes(
            nested_lookup("cpe23Uri", cve_json["configurations"]))
        for vendor, products in vendors_products.items():
            v_obj = Vendor.query.filter_by(name=vendor).first()

            # Create the vendor
            if not v_obj:
                v_obj = Vendor(name=vendor)
                db.session.add(v_obj)
                db.session.commit()

            # Create the products
            for product in products:
                p_obj = Product.query.filter_by(name=product,
                                                vendor=v_obj).first()
                if not p_obj:
                    p_obj = Product(name=product, vendor=v_obj)
                    db.session.add(p_obj)
                    db.session.commit()

        return cve